{{ :supportukraine.gif|}} ====== Home Assistant: Water consumption monitoring with gPlugD-E and Ensor eRS801 via P1-DSMR interface in ESPHome ====== {{en:tux.png |Hey, my name is "Tux"!}} Hey, my name is "Tux" and this tutorial will show you how to set up water consumption monitoring in [[https://www.home-assistant.io/|Home Assistant]] with [[https://esphome.io/|ESPHome]], a [[https://gplug.ch/produkte/gplugd-e/|gPlugD-E]] adapter, connected to the //P1-DSMR// interface of an [[https://www.ensor.com/produkte|Ensor]] eRS801 smart meter. ---- \\ ===== Preparation ===== First of all, if you want to catch any data of an //Ensor eRS801// its //P1-DSMR// customer interface, you have to make sure the customer interface is being unlocked. In my case, the electrician hired by the municipality from the village I live, which installed the //Ensor eRS801//, took care on this for me. I also asked him to set down the //Ensor eRS801// its internal request interval to the physical water meter (which is an [[https://ch.integra-metering.com/product/aquastream-m-bus-pulses/|Integra aquastream Type AQS-MB]] in my case) to an interval of 60 seconds instead of default 3600 seconds. This way I could monitor at least consumed liters per minute, which is sufficient for my needs. He also had to tell me on which //M-Bus// channel the water metering communication is being transferred, which is channel #4 in my case. If the channel number differs in your case, please just adjust the number accordingly on the YAML code provided later in this tutorial. In addition, in case you need it, because I was not able to find anything documented officially and therefore had to trial and error, here's on how to bring the //gPlugD-E// adapter into flashing mode: Press and hold the ''R''-button (1), then press and hold the ''A''-button (2), then release the ''R''-button (1) and finally release the ''A''-button (2). Now you can flash your custom ''.bin'' firmware file via [[https://web.esphome.io/|web.esphome.io]] web interface. Be aware, that after successful flashing, you need to press the ''R''-button at least once again to reset the //gPlugD-E// adapter to make the uploaded program start running. It was somehow not sufficient in my case to press the virtual device reset button on the //web.esphome.io// web interface. [{{:homeassistantgplugde01.png?400|gPlugD-E physical buttons}}] \\ ===== First thoughts & tutorial ===== While searching for a way to track my water usage in //Home Assistant// after the municipality had ruined my original, well-functioning solution with their new installation, I came across [[https://github.com/haribert/gplug-esphome|this]] alternative. Should be an easy task, right? Using the main YAML code from the linked tutorial, replacing the power monitoring code part with my own water monitoring part, flashing it via //ESPHome// to the //gPlugD-E// adapter and I will be ready to go... \\ But wait: The problem I stumbled across was that the //gPlugE// adapter from the linked tutorial is not available anymore and has being replaced with its successor, the //gPlugD-E// adapter. The underlying hardware is not the same anymore and internal microcontroller pin connections to the physical ethernet interface have changed. So I had to determine the new board its layout by myself. I contacted the //gPlugD-E// support but they were not willing to help me out with this so I flashed back the [[http://ota.gplug.ch/Tasmota/gPlugDE/firmware.factory.bin|gPlugD-E its original Tasmota firmware]], opened its web console and tried to determine the according pin layout by executing the following command: Template Which gave me the following output: ''{"NAME":"IoT-Adapter","GPIO":[736,672,5536,704,0,0,0,0,5600,0,5568,0,0,0,0,0,0,0,0,0,0,0]}'' Seems like an array of GPIO mapping values, which I could use to compare against the [[https://tasmota.github.io/docs/GPIO-Conversion/|official Tasmota GPIO conversion table]], right? Unfortunately not. I was not able to find those array values within the conversion table, so the logic behind it must be different. My bad, I guess. So I asked [[https://claude.ai|claude.ai]] to help me and it told me to execute the following command on the //Tasmota// console: gpio all ...and voilà: ''17:47:27.464 RSL: RESULT = {"GPIO0":{"SPI CLK1":736},"GPIO1":{"SPI MISO1":672},"GPIO2":{"ETH POWER":5536},"GPIO3":{"SPI MOSI1":704},"GPIO4":{"None":0},"GPIO5":{"None":0},"GPIO6":{"None":0},"GPIO7":{"None":0},"GPIO8":{"ETH MDIO":5600},"GPIO9":{"None":0},"GPIO10":{"ETH MDC":5568},"GPIO11":{"None":0},"GPIO12":{"None":0},"GPIO13":{"None":0},"GPIO18":{"None":0},"GPIO19":{"None":0},"GPIO20":{"None":0},"GPIO21":{"None":0}}'' All the required pin mappings are there. Now I got everything I needed to configure the ethernet port via YAML code accordingly, which worked perfectly. Yay! Now the //ESPHome// YAML code to read out data via DSMR protocol standard was indeed simple and minimal. But the next problem was right around the corner: Data was being transmitted successfully, but the default [[https://esphome.io/components/sensor/dsmr/|DSMR library]] from //ESPHome// was not able to parse the data output accordingly, it mostly had something to do with missing or false timestamp format, but I cannot tell for sure as I never analyzed the whole raw data stream. No worries. In the end I had to prompt //Claude// again to help me out with this and it gave me the following perfectly working code solution: # Ethernet: ethernet: type: W5500 clk_pin: GPIO0 mosi_pin: GPIO3 miso_pin: GPIO1 cs_pin: GPIO10 interrupt_pin: GPIO8 reset_pin: GPIO2 # Globals: globals: # Globals for water consumption calculation - id: water_m3 type: float restore_value: true initial_value: '0.0' - id: tbuf type: std::string initial_value: '""' - id: tactive type: bool initial_value: 'false' # Sensors: sensor: # Water consumption - platform: template id: water_sensor name: "Water consumption" unit_of_measurement: "m³" accuracy_decimals: 3 device_class: water state_class: total_increasing icon: "mdi:water" lambda: return id(water_m3); update_interval: 5s # UART: uart: id: uart_bus rx_pin: GPIO4 baud_rate: 115200 rx_buffer_size: 2048 # Interval-driven data parsing interval: # Check for incoming data over serial every 100ms - interval: 100ms then: - lambda: |- while (id(uart_bus).available() > 0) { uint8_t b; id(uart_bus).read_byte(&b); char c = (char) b; if (c == '/') { id(tbuf) = ""; id(tactive) = true; } if (!id(tactive)) continue; id(tbuf) += c; if (id(tbuf).size() > 2000) { id(tbuf) = ""; id(tactive) = false; continue; } if (c == '!') { const std::string pfx = "0-4:24.2.1("; size_t p = id(tbuf).find(pfx); size_t s = id(tbuf).find('*', p); if (p != std::string::npos && s != std::string::npos) { p += pfx.size(); float v = atof(id(tbuf).substr(p, s - p).c_str()); if (v > 0.0f) id(water_m3) = v; } id(tbuf) = ""; id(tactive) = false; } } Now I adapted the //gPlugD-E// adapter into //Home Assistant// and the ''Water consumption" sensor was available as expected: [{{:homeassistantgplugde02.png?600|ESPHome "Water consumption" sensor}}] I now was able to use this sensor for adding water consumption monitoring on the //Home Assistant Energy Dashboard//. \\ ===== End of tutorial ===== \\ \\ Appreciate my work? \\ [[https://www.buymeacoffee.com/fabioU|Buy me a coffee]] {{:buymeacoffee.png|}} or [[https://www.paypal.com/donate/?hosted_button_id=TH8Q3NTJCAJBA|PayPal]] {{:paypal.png|}} \\ \\ **Source(s):** \\ [[https://bitaranto.ch | Bitaranto.ch: IT-tutorials & technics]] \\ {{htmlmetatags>metatag-robots=()}}