I´m also trying your custom component. It validates just fine with Esphome v1.15.3, but when I compile it I get some errors:
In file included from src/main.cpp:44:0:
src/pulse_meter_sensor.h:11:7: error: redefinition of 'class esphome::pulse_meter::PulseMeterSensor'
class PulseMeterSensor : public sensor::Sensor, public Component {
^
In file included from src/esphome.h:23:0,
from src/main.cpp:3:
src/esphome/components/pulse_meter/pulse_meter_sensor.h:11:7: error: previous definition of 'class esphome::pulse_meter::PulseMeterSensor'
class PulseMeterSensor : public sensor::Sensor, public Component {
^
*** [/data/esp32_01/.pioenvs/esp32_01/src/main.cpp.o] Error 1
I have put pulse_meter_sensor.h, pulse_meter_sensor.cpp and sensor.py in
the directory: config/esphome/custom_components/pulse_meter/
Can you check you definitely haven’t got pulse_meter_sensor.h anywhere else in your config directory? It looks like two versions are being included from different directories.
Yes, the three files are only located in
config/esphome/custom_components/pulse_meter/
I made a clean build but it didn´t help. I run the esphome add-on from the HA community, but it is in sync with the Esphome repository and shouldn´t matter…?
Linking /data/esp32_01/.pioenvs/esp32_01/firmware.elf
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `esphome::pulse_meter::PulseMeterSensor::gpio_intr(esphome::pulse_meter::PulseMeterSensor*)':
/config/esphome/esp32_01/src/pulse_meter_sensor.cpp:58: multiple definition of `esphome::pulse_meter::PulseMeterSensor::gpio_intr(esphome::pulse_meter::PulseMeterSensor*)'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:/config/esphome/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp:58: first defined here
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `esphome::pulse_meter::PulseMeterSensor::setup()':
pulse_meter_sensor.cpp:(.text._ZN7esphome11pulse_meter16PulseMeterSensor5setupEv+0x0): multiple definition of `esphome::pulse_meter::PulseMeterSensor::setup()'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:pulse_meter_sensor.cpp:(.text._ZN7esphome11pulse_meter16PulseMeterSensor5setupEv+0x0): first defined here
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `non-virtual thunk to esphome::pulse_meter::PulseMeterSensor::setup()':
pulse_meter_sensor.cpp:(.text._ZThn160_N7esphome11pulse_meter16PulseMeterSensor5setupEv+0x0): multiple definition of `non-virtual thunk to esphome::pulse_meter::PulseMeterSensor::setup()'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:pulse_meter_sensor.cpp:(.text._ZThn160_N7esphome11pulse_meter16PulseMeterSensor5setupEv+0x0): first defined here
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `esphome::pulse_meter::PulseMeterSensor::dump_config()':
pulse_meter_sensor.cpp:(.text._ZN7esphome11pulse_meter16PulseMeterSensor11dump_configEv+0x0): multiple definition of `esphome::pulse_meter::PulseMeterSensor::dump_config()'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:pulse_meter_sensor.cpp:(.text._ZN7esphome11pulse_meter16PulseMeterSensor11dump_configEv+0x0): first defined here
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `non-virtual thunk to esphome::pulse_meter::PulseMeterSensor::dump_config()':
pulse_meter_sensor.cpp:(.text._ZThn160_N7esphome11pulse_meter16PulseMeterSensor11dump_configEv+0x0): multiple definition of `non-virtual thunk to esphome::pulse_meter::PulseMeterSensor::dump_config()'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:pulse_meter_sensor.cpp:(.text._ZThn160_N7esphome11pulse_meter16PulseMeterSensor11dump_configEv+0x0): first defined here
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `esphome::pulse_meter::PulseMeterSensor::loop()':
pulse_meter_sensor.cpp:(.text._ZN7esphome11pulse_meter16PulseMeterSensor4loopEv+0x0): multiple definition of `esphome::pulse_meter::PulseMeterSensor::loop()'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:pulse_meter_sensor.cpp:(.text._ZN7esphome11pulse_meter16PulseMeterSensor4loopEv+0x0): first defined here
/data/esp32_01/.pioenvs/esp32_01/src/pulse_meter_sensor.cpp.o: In function `non-virtual thunk to esphome::pulse_meter::PulseMeterSensor::loop()':
pulse_meter_sensor.cpp:(.text._ZThn160_N7esphome11pulse_meter16PulseMeterSensor4loopEv+0x0): multiple definition of `non-virtual thunk to esphome::pulse_meter::PulseMeterSensor::loop()'
/data/esp32_01/.pioenvs/esp32_01/src/esphome/components/pulse_meter/pulse_meter_sensor.cpp.o:pulse_meter_sensor.cpp:(.text._ZThn160_N7esphome11pulse_meter16PulseMeterSensor4loopEv+0x0): first defined here
collect2: error: ld returned 1 exit status
*** [/data/esp32_01/.pioenvs/esp32_01/firmware.elf] Error 1
@stevebaxter First of all thanks for the code and your explanations in this thread. It helped met to setup a puls meter for my Solar Panels.
I was wondering if you could help me with one issue I have. Sometimes I get big spikes.
I already set my internal_filter to 500ms which helps a little. When I set a median the spikes are gone but then the out ut never reaches 0, it hovers around 36W.
Could you help me remove the spikes but still get the output to 0. What am I missing?
Just chipping in here to thank @stevebaxter! I found your pulse meter quite accurate. I’ve built a power monitor using M5Stick and accompanied LDR that reads impulses from a led flashes our electricity meter generates.
It is surprising that pulse meter was so much more accurate than built in pulse counter. In fact, pulse counter reported values that were off over 30% from the actual numbers.
I’m comparing the numbers to my electricity distributor numbers that I can check from their app a few days after the fact.
So just saying that I appreciate your work, and as it seems to work so good, ask if it could be merged to the esphome main line?
I had a few issues here and there. I also got huge spikes which I had to filter by tweaking the median filter and changing input pin to inverted. Additionally, I’m seeing some jitter in the power numbers, but I suspect that it’s probably some underfloor heating system going on and off. This needs to be verified.
How big is your median filter? I saw spikes as well, I’m really not sure of the source, but most likely noise on the input (this wouldn’t be visible with the existing pulse_counter because that essentially averages everything over 1 min or whatever you set as your interval). I found that a very short median filter of window_size: 3 fixed this for me. My latest config for reference:
sensor:
- platform: pulse_meter
name: "Electricity"
pin: D5
unit_of_measurement: "kW"
internal_filter: 100ms
accuracy_decimals: 3
timeout: 2 min
filters:
# Filter outliers
- median:
window_size: 3
send_every: 1
send_first_at: 1
# Convert pulses/min (Wh/min) to kW
- multiply: 0.06
total:
name: "Electricity Meter"
unit_of_measurement: "kWh"
accuracy_decimals: 3
filters:
- multiply: 0.001
- platform: pulse_meter
name: "Gas"
pin: D6
unit_of_measurement: "kW"
internal_filter: 4s
accuracy_decimals: 3
timeout: 2 min
filters:
# Convert 0.01 m³ (one pulse) to kWH/min using:
#
# 1.022640 * 39.2 / 3.6 / 100 = 0.1113541333
#
# Then kWH/min to kW by multiplying by 60 = 6.6812
- multiply: 6.6812
total:
name: "Gas Meter"
unit_of_measurement: "m³"
accuracy_decimals: 2
filters:
# One revolution of the small dial is 10l
- multiply: 0.01
500ms as the internal filter might be a bit long - you may under-read if a real signal involves more than two pulses per second.
If the reading isn’t reaching 0, check your timeout value. This is used to decide when we’re at 0 (we can only update the output when we see a pulse, so if we never get a pulse we “stick” on the last reading, the timeout value gets around that). Also, are you maybe really seeing 36W? For a system that has one flash per Wh, 36W is a flash every 100 seconds, which is quite a long time. You can look at the absolute counter value to see if you are getting counts at a very low rate.
pulse_meter should be much more accurate than pulse_counter, particularly for the “absolute” count. I’d love for this to be merged, there’s a pull request here awaiting review from the ESPHome maintainers:
If you could add a voice asking for it to be merged it might help!
I think some jitter in the power numbers is inevitable (and might be real). Devices don’t consume a constant level of power, it will vary from second to second depending on load (even a fridge will vary its load when the compressor is running I think). Readings will also be sensitive to any jitter in the timing and interrupt handling on the board - I think this is likely to be small though, if I have my maths right, 1 ms jitter (quite a lot) would only make about 10 mW of difference for a typical meter that outputs 1 pulse per Wh.
Hi Steve,
Thanks for your reply.
I first had my settings like you. Just copied your settings how that would work. Worked good only I still got some spikes therefore tried below.
I did comment out the median because this also doesn’t show 0w.
It should definitely read 0 because it is measuring my solar panels and at night there is no sun .
Hope you can point me in the right direction.
Window size of 7 is probably a bit big - can you try 3?
I’d still really check you aren’t seeing any counts at night. I guess you may still get small amounts of power generated from moonlight, or possibly a reverse flow back into the panels (that may show up on the meter as pulses even if it is counting backwards).
Hi @stevebaxter ,
Very good job !!
The sensor works perfectly in my installation.
I have a question in order to simplify my board, is-it possible to activate the pull-up fonction on the GPIO ?
Thanks !
actually it isn’t possible (you have a yaml error) because pulse_meter herit from sensor (input_pullup is not implemented) and not gpio_binary_sensor (where pullup is implemented)