diff --git a/README.md b/README.md index 96ddbfe..ce9c7d8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # ESP32 + ESPHome Open Source Energy Monitor ## Introduction -For months I've been looking for a non-intrusive energy monitoring solution for my home. The residence receives more than one phase from the utility company and because of that, the available solutions in the market based on open protocols are extremely expensive. Cheap alternatives always rely on cloud services and I don't believe any of them will remain online for too long. +For months I've been looking for a non-intrusive energy monitoring solution for my home. The residence receives more than one phase from the utility company and the available solutions in the market based on open protocols are extremely expensive for this setup. Cheap alternatives always rely on cloud services and I don't believe any of them will remain online for too long. The solution I present here is a DIY project built on the top of [Open Energy Monitor](https://openenergymonitor.org/) and [ESPHome framework](https://esphome.io/). I selected the ESP32 controller because it has several analog ports to measure voltage and current. @@ -26,7 +26,7 @@ The solution I present here is a DIY project built on the top of [Open Energy Mo - Daily energy consumption (kWh) - Weekly energy consumption (kWh) - Monthly energy consumption (kWh) - - Wifi connection stats + - Wifi connection stats (SSID, Signal and IP) ## Hardware @@ -176,7 +176,8 @@ This piece of code can also be used to create your own Energy Monitoring solutio ### Flashing ESPHome firmware to the ESP32 board -```esphome run esp32emon.yaml``` +- Compile and upload: ```esphome run esp32emon.yaml``` +- Compile and upload to a remote device using the IP address (if automatic host detection fails): ```esphome run esp32emon.yaml --device= 192.168.0.15``` Please refer to [ESPHome website](https://esphome.io/guides/getting_started_command_line.html) for detailed instructions. @@ -205,12 +206,14 @@ MQTT integration is disabled by default. To enable, uncomment the lines in the y - **ESPHome webserver is crashing:** The web server was disabled because it was crashing the ESP32. due the blocking nature of Emon library. You may be able to run it if you decrease the CROSSINGS setting in *esp32emon.h*. -- **Negative power readings:** Double check the CT clamp connections. Try inverting the clamp direction in the wire. +- **Voltage and current are displayed but the power is zero:** Double check the CT clamp connections. Try inverting the clamp direction in the wire. ## Download - [GitHub Release](https://github.com/danpeig/ESP32EnergyMonitor/releases/) ## Version history +- 1.3 (10/01/2023) + - Added filters to all sensors to prevent integrators corruption. - 1.2 (31/12/2022) - Changed Power Factor state class to "measurement" to prevent log pollution - 1.1 (27/12/2022) diff --git a/esphome-esp32emon/esp32emon.yaml b/esphome-esp32emon/esp32emon.yaml index f94b2fd..8f9c8c1 100644 --- a/esphome-esp32emon/esp32emon.yaml +++ b/esphome-esp32emon/esp32emon.yaml @@ -8,7 +8,7 @@ esphome: - esp32emon.h project: name: danpeig.esp32emon - version: "1.2.0" + version: "1.3.0" # Board configuration esp32: @@ -108,27 +108,82 @@ sensor: state_class: "measurement" accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Apparent Power P1" device_class: "apparent_power" unit_of_measurement: VA state_class: "measurement" accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Power Factor P1" device_class: "power_factor" state_class: "measurement" accuracy_decimals: 2 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Voltage P1" device_class: "voltage" unit_of_measurement: V accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Current P1" device_class: "current" unit_of_measurement: A accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } #Phase 2 sensors - name: "Real Power P2" @@ -137,54 +192,166 @@ sensor: state_class: "measurement" accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Apparent Power P2" device_class: "apparent_power" unit_of_measurement: VA state_class: "measurement" accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Power Factor P2" device_class: "power_factor" state_class: "measurement" accuracy_decimals: 2 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Voltage P2" device_class: "voltage" unit_of_measurement: V accuracy_decimals: 1 + internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - name: "Current P2" device_class: "current" unit_of_measurement: A accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } # #Phase 3 sensors - #- name: "Real Power P3" - # device_class: "power" - # unit_of_measurement: W - # state_class: "measurement" - # accuracy_decimals: 1 - # internal: false - #- name: "Apparent Power P3" - # device_class: "apparent_power" - # unit_of_measurement: VA - # state_class: "measurement" - # accuracy_decimals: 1 - # internal: false - #- name: "Power Factor P3" - # device_class: "power_factor" - # state_class: "measurement" - # accuracy_decimals: 2 - # internal: false - #- name: "Voltage P3" - # device_class: "voltage" - # unit_of_measurement: V - # accuracy_decimals: 1 - #- name: "Current P3" - # device_class: "current" - # unit_of_measurement: A - # accuracy_decimals: 1 - # internal: false + # - name: "Real Power P3" + # device_class: "power" + # unit_of_measurement: W + # state_class: "measurement" + # accuracy_decimals: 1 + # internal: false + # filters: + # - lambda: |- + # //Avoid corrupting integration sensors + # if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + # { + # return x; + # } + # else + # { + # return 0; + # } + # - name: "Apparent Power P3" + # device_class: "apparent_power" + # unit_of_measurement: VA + # state_class: "measurement" + # accuracy_decimals: 1 + # internal: false + # filters: + # - lambda: |- + # //Avoid corrupting integration sensors + # if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + # { + # return x; + # } + # else + # { + # return 0; + # } + # - name: "Power Factor P3" + # device_class: "power_factor" + # state_class: "measurement" + # accuracy_decimals: 2 + # internal: false + # filters: + # - lambda: |- + # //Avoid corrupting integration sensors + # if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + # { + # return x; + # } + # else + # { + # return 0; + # } + # - name: "Voltage P3" + # device_class: "voltage" + # unit_of_measurement: V + # accuracy_decimals: 1 + # internal: false + # filters: + # - lambda: |- + # //Avoid corrupting integration sensors + # if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + # { + # return x; + # } + # else + # { + # return 0; + # } + # - name: "Current P3" + # device_class: "current" + # unit_of_measurement: A + # accuracy_decimals: 1 + # internal: false + # filters: + # - lambda: |- + # //Avoid corrupting integration sensors + # if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + # { + # return x; + # } + # else + # { + # return 0; + # } #Total sensors - name: "Total Real Power" @@ -197,7 +364,7 @@ sensor: filters: - lambda: |- //Avoid corrupting integration sensors - if(!isinf(x) && !isnan(x) && x >= 0) + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) { return x; } @@ -214,7 +381,7 @@ sensor: filters: - lambda: |- //Avoid corrupting integration sensors - if(!isinf(x) && !isnan(x) && x >= 0) + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) { return x; } @@ -228,6 +395,17 @@ sensor: unit_of_measurement: A accuracy_decimals: 1 internal: false + filters: + - lambda: |- + //Avoid corrupting integration sensors + if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6) + { + return x; + } + else + { + return 0; + } - platform: integration name: "Daily Consumption" @@ -277,7 +455,7 @@ sensor: - platform: copy # Reports the WiFi signal strength in % source_id: wifi_signal_db - name: "WiFi signal percent" + name: "WiFi signal" filters: - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0); unit_of_measurement: "%"