Updated documentation related to power meter integration (#3184)

* Updated documentation related to power meter integration

I've updated the cookbook to use the more accurate ``pulse_meter_sensor`` and added how to convert power to energy using ``total_daily_energy``.

* Update power_meter.rst

* Update pulse_meter.rst

* Update total_daily_energy.rst

* Update pulse_meter.rst

* Update total_daily_energy.rst

* Update power_meter.rst

* Add files via upload

* Added more information about pulse meter
and pulse counter differences including graph.

* Reduced image size.

* Path issue

* Once more into the fray.

* And again.

* Some more documentation related to meters

* Worked more on the power meter cookbook.

* Minor modification to match previously used
impulse constant.

* Made pulse_meter more implementation agnostic
and moved power meter relevant information
to the cookbook.

* Apply suggestions from code review

Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>

* Code Review Changes

* Linting.

* Linting again.

* Some reformatting of pulse_meter.rst

* Some more formatting changes.

* Corrected internal filter mode description.

---------

Co-authored-by: H. Árkosi Róbert <robreg@zsurob.hu>
Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com>
This commit is contained in:
Dennis 2023-10-25 17:10:57 +02:00 committed by GitHub
parent 5518d96f58
commit 7ef6443568
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 169 additions and 80 deletions

View File

@ -10,7 +10,7 @@ on any pin.
On the ESP32, this sensor is even highly accurate because it's using the hardware `pulse counter
peripheral <https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/pcnt.html>`__
on the ESP32. However, due to the use of the pulse counter peripheral, a maximum of 8 channels can be used!
on the ESP32. However, due to the use of the pulse counter peripheral, a maximum of 8 channels can be used!
.. figure:: images/pulse-counter.png
:align: center
@ -24,7 +24,7 @@ on the ESP32. However, due to the use of the pulse counter peripheral, a maximum
pin: 12
name: "Pulse Counter"
Configuration variables:
Configuration variables
------------------------
- **pin** (**Required**, :ref:`config-pin`): The pin to count pulses on.
@ -38,7 +38,6 @@ Configuration variables:
- **falling_edge** (*Optional*): What to do when a falling edge is
detected. One of ``DISABLE``, ``INCREMENT`` and ``DECREMENT``.
Defaults to ``DISABLE``.
- **use_pcnt** (*Optional*, boolean): Use hardware ``PCNT`` pulse counter. Only supported on ESP32. Defaults to ``true``.
@ -79,13 +78,12 @@ count the light pulses on a power meter, you can do the following:
filters:
- multiply: 0.06 # (60s/1000 pulses per kWh)
Counting total pulses
---------------------
When the total sensor is configured, the pulse_counter also reports the total
number of pulses measured. When used on a power meter, this can be used to
measure the total consumed energy in kWh.
When the total sensor is configured, the pulse_counter also reports the total
number of pulses measured. When used on a power meter, this can be used to
measure the total consumed energy in kWh.
.. code-block:: yaml

View File

@ -6,8 +6,14 @@ Pulse Meter Sensor
:image: pulse.svg
The pulse meter sensor allows you to count the number and frequency of pulses on any pin. It is intended to be a drop-in replacement
for :doc:`integration sensor </components/sensor/pulse_counter>`, but offering better resolution.
It measures the time between rising edges on a pin, for each pulse it outputs the frequency in pulses/min.
for the :doc:`pulse counter integration </components/sensor/pulse_counter>`.
Rather than counting pulses over a fixed time interval, the pulse meter sensor measures the time between pulses. The precise manner in which this is done depends on the ``internal_filter_mode`` option. This leads to a higher resolution, especially for low pulse rates, as the pulse counter sensor is limited by the number of pulses within a time interval.
Here's a comparison of the two sensors; both are set to an update interval of 10 seconds (using the ``update_interval`` and the ``throttle_average`` option respectively):
.. figure:: /images/pulse-counter_vs_pulse-meter.png
:align: center
:width: 50.0%
.. code-block:: yaml
@ -17,66 +23,61 @@ It measures the time between rising edges on a pin, for each pulse it outputs th
pin: 12
name: "Pulse Meter"
Configuration variables:
Configuration variables
------------------------
- **pin** (**Required**, :ref:`config-pin`): The pin to count pulses on.
- **name** (**Required**, string): The name of the sensor.
- **internal_filter** (*Optional*, :ref:`config-time`): If a pulse shorter than this
time is detected, its discarded and no pulse is counted. Defaults to ``13us``. For S0 pulse meters that are used to meter power consumption 50-100 ms is a reasonable value.
- **internal_filter** (*Optional*, :ref:`config-time`): If a pulse shorter than this time is detected, it is discarded. Defaults to ``13us``.
This acts as a debounce filter to eliminate input noise, so choose a value a little less than your expected minimum pulse width.
- **internal_filter_mode** (*Optional*, string): Determines how the internal filter is applied.
One of ``EDGE`` and ``PULSE``. Defaults to ``EDGE``. In ``EDGE`` mode subsequent rising edges are compared and if they fall into an interval lesser than the internal filter value, the last one is discarded. In ``PULSE`` mode the rising edge is discarded if any further interrupts are detected before the internal_filter time has passed. In other words, a high pulse must be at least internal_filter long to be counted. This is useful if you are detecting long pulses that may bounces before and/or after the main pulse.
One of ``EDGE`` or ``PULSE``. Defaults to ``EDGE``.
- In ``EDGE`` mode, subsequent rising edges are compared and if they fall into an interval lesser than the ``internal filter`` value, the last one is discarded. This is useful if your input signal bounces, but is otherwise clean.
- In ``PULSE`` mode, the rising edge is discarded if any further interrupts are detected before the ``internal_filter`` time has passed. In other words, a high pulse must be at least ``internal_filter`` long to be counted. This is useful if you have a noisy input signal that may have bounces before and/or after the main pulse.
- **timeout** (*Optional*, :ref:`config-time`): If we don't see a pulse for this length of time, we assume 0 pulses/sec. Defaults to ``5 min``.
- **timeout** (*Optional*, :ref:`config-time`): If we don't see a pulse for this length of time, we assume *0 pulses/s*. Defaults to ``5 min``.
- **total** (*Optional*, :ref:`config-id`): An additional sensor that outputs the total number of pulses counted.
- All other options from :ref:`Sensor <config-sensor>`.
Converting units
----------------
The sensor defaults to units of “pulses/min”. You can change this by using :ref:`sensor-filters`.
For example, if youre using the pulse meter with a photodiode to
count the light pulses on a power meter that outputs 1000 pulses per kWh,
you can use the following to output instantaneous usage in kW:
The sensor defaults to units of *pulses/min*, You can change this by using :ref:`sensor-filters`.
For example, if youre using the pulse meter with a photodiode to count the light pulses on a power meter that has an impulse constant of *10000 pulses / kWh*, you can use the following to output instantaneous usage in *W*:
.. code-block:: yaml
# Example configuration entry
sensor:
- platform: pulse_meter
pin: 12
unit_of_measurement: 'kW'
name: 'Electricity Usage'
id: sensor_pulse_meter # Optional ID, necessary if you want to calculate the total number of pulses.
unit_of_measurement: 'W'
device_class: power
state_class: measurement
internal_filter: 20ms # Assuming maximum load of 16 kW and 10000 impulses per kWh, any pulses faster than 22.5 ms would exceed load. -10% ~= 20 ms.
accuracy_decimals: 0
pin: 12
filters:
- multiply: 0.06
- multiply: 6 # (60s / impulse constant) * (1000W / 1kW)
Counting total pulses
---------------------
When the total sensor is configured, pulse_meter also reports the total
number of pulses measured. When used on a power meter, this can be used to
measure the total consumed energy in kWh.
When the total sensor is configured, ``pulse_meter`` also reports the total
number of pulses measured.
.. code-block:: yaml
# Example configuration entry
sensor:
- platform: pulse_meter
pin: 12
unit_of_measurement: 'kW'
name: 'Electricity Usage'
internal_filter: 100ms
accuracy_decimals: 3
filters:
- multiply: 0.06
# ...
total:
name: "Electricity Total"
unit_of_measurement: "kWh"
accuracy_decimals: 3
filters:
- multiply: 0.001
name: "Total Pulses"
(Re)Setting the total pulse count
---------------------------------
@ -87,22 +88,27 @@ trying to match.
.. code-block:: yaml
on_...:
then:
- pulse_meter.set_total_pulses:
id: pulse_meter_id
value: 12345
api:
services:
- service: set_total
variables:
new_total: int
then:
- pulse_counter.set_total_pulses:
id: sensor_pulse_meter
value: !lambda 'return new_total;'
.. note::
This value is the raw count of pulses, and not the value you see after the filters
are applied.
See Also
--------
- :ref:`sensor-filters`
- :doc:`/components/sensor/pulse_counter`
- :doc:`/components/sensor/total_daily_energy`
- :doc:`/cookbook/power_meter`
- `Home Assistant Glow 🌟 <https://github.com/klaasnicolaas/home-assistant-glow/>`__.
- :apiref:`pulse_meter/pulse_meter_sensor.h`
- :ghedit:`Edit`

View File

@ -17,8 +17,15 @@ daily energy usage in ``Wh`` or ``kWh``.
# Example configuration entry
sensor:
- platform: total_daily_energy
name: "Total Daily Energy"
name: 'Total Daily Energy'
power_id: my_power
unit_of_measurement: 'kWh'
state_class: total_increasing
device_class: energy
accuracy_decimals: 3
filters:
# Multiplication factor from W to kW is 0.001
- multiply: 0.001
# The power sensor to convert, can be any power sensor
- platform: hlw8012
@ -28,8 +35,8 @@ daily energy usage in ``Wh`` or ``kWh``.
# Enable time component to reset energy at midnight
time:
- platform: sntp
id: my_time
- platform: homeassistant
id: homeassistant_time
Configuration variables:
------------------------
@ -70,6 +77,9 @@ See Also
- :ref:`sensor-filters`
- :doc:`hlw8012`
- :doc:`cse7766`
- :doc:`/components/sensor/pulse_counter`
- :doc:`/components/sensor/pulse_meter`
- :doc:`/components/time/homeassistant`
- :doc:`/cookbook/power_meter`
- :apiref:`total_daily_energy/total_daily_energy.h`
- :ghedit:`Edit`

View File

@ -5,20 +5,11 @@ Non-Invasive Power Meter
:description: Instructions for hacking your power meter at home to measure your power usage.
:image: power_meter.jpg
So an essential part of making your home smart is knowing how much power it uses over
the day. Tracking this can be difficult, often you need to install a completely new
power meter which can often cost a bunch of money. However, quite a few power meters
have a red LED on the front that blinks every time that one Wh has been used.
So an essential part of making your home smart is knowing how much power it uses over the day. Tracking this can be difficult, often you need to install a completely new power meter which can often cost a bunch of money. However, quite a few power meters have a red LED on the front that blinks every time that one Wh has been used.
The simple idea therefore is: Why don't we just abuse that functionality to make the power-meter
IoT enabled? We just have to hook up a simple photoresistor in front of that aforementioned
LED and track the amount of pulses we receive. Then using ESPHome we can instantly have
the power meter show up in Home Assistant 🎉
The simple idea therefore is: Why don't we just abuse that functionality to make the power-meter IoT enabled? We just have to hook up a simple photoresistor in front of that aforementioned LED and track the number of pulses we receive. Then using ESPHome we can instantly have the power meter show up in Home Assistant 🎉
Hooking it all up is quite easy: Just buy a suitable photoresistor (make sure the wave length
approximately matches the one from your power meter). Then connect it using a simple variable
resistor divider (see `this article <https://blog.udemy.com/arduino-ldr/>`__ for inspiration).
And... that should already be it :)
Hooking it all up is quite easy: Just buy a suitable photoresistor (make sure the wave length approximately matches the one from your power meter). Then connect it using a simple variable resistor divider (see `this article <https://blog.udemy.com/arduino-ldr/>`__ for inspiration). And... that should already be it :)
.. figure:: images/power_meter-header.jpg
:align: center
@ -26,8 +17,7 @@ And... that should already be it :)
.. note::
Some energy meters have an exposed S0 port (which essentially just is a switch that closes), if
that is the case the photodiode can be replaced with the following connection.
Some energy meters have an exposed `S0 port <https://en.wikipedia.org/wiki/S_interface/>`__ (which essentially just is a switch that closes), if that is the case the photodiode can be replaced with the following connection.
.. code-block::
@ -36,45 +26,130 @@ And... that should already be it :)
. |
. +--------- GPIO12
For ESPHome, you can then use the
:doc:`pulse counter sensor </components/sensor/pulse_counter>` using below configuration:
For ESPHome, you can then use the :doc:`pulse meter sensor </components/sensor/pulse_meter>` using below configuration:
.. code-block:: yaml
sensor:
- platform: pulse_counter
- platform: pulse_meter
name: 'Power'
id: sensor_pulse_meter # Optional ID, necessary if you want to calculate the total daily energy
unit_of_measurement: 'W'
device_class: power
state_class: measurement
accuracy_decimals: 0
pin: GPIO12
unit_of_measurement: 'kW'
name: 'Power Meter'
filters:
- multiply: 0.06 # (60s/1000 pulses per kWh)
- multiply: 6 # (60s / impulse constant) * (1000W / 1kW)
Adjust ``GPIO12`` to match your set up of course. The output from the pulse counter sensor is in
``pulses/min`` and we also know that 1000 pulses from the LED should equal 1kWh of power usage.
Thus, rearranging the expression yields a proportional factor of ``0.06`` from ``pulses/min`` to
``kW``.
And if a technician shows up and he looks confused about what the heck you have done to your
power meter, tell them about ESPHome 😉
Adjust ``GPIO12`` to match your set up of course. The output from the pulse counter sensor is in pulses/min and we also know that 10000 pulses from the LED should equal 1kWh of power usage. Thus, rearranging the expression yields a proportional factor of 6 from pulses/min to *W*.
.. note::
Photoresistors often have a bit of noise during their switching phases. So in certain situations,
a single power meter tick can result in many pulses being counted. This effect is especially big on
ESP8266s. If you're experiencing this, try enabling the ``internal_filter:`` filter option:
The ``pulse_meter`` sensor sends an update every time a pulse is detected. This can quickly lead to sub-second updates which can be a bit much for Home Assistant to handle. To avoid this, you can use the ``average_throttle`` filter to only send updates up to a desired interval:
.. code-block:: yaml
sensor:
- platform: pulse_counter
- platform: pulse_meter
# ...
internal_filter: 10us
filters:
- average_throttle: 10s
- filter_out: NaN
See :doc:`/components/sensor/total_daily_energy` for counting up the total daily energy usage
with these ``pulse_counter`` power meters.
.. note::
The ``pulse_meter`` sensor has an internal filter that is used to debounce the input signal. This filter is set to ``13us`` by default. To increase the safety margin, you can increase this value. For this you need to know the *minimum pulse width* that you can expect to see from your power meter within the expected load range.
The minimum pulse width threshold is determined by considering the upper limit of the *load* the meter is designed to handle, as well as the meter's *impulse constant* (x pulses / kWh). Here's the calculation involved:
- **Load Limit in Watts**: Establish the *upper load limit* that the meter is designed to measure. For example, if the limit is 16 kW (16,000 Watts), this becomes a reference point.
- **Pulse Rate Calculation**: Determine the pulse rate corresponding to this load limit. For this we need to know the impulse constant. In our example, the power meter has an impulse constant of 10000 pulses/kWh, resulting in 160000 pulses per hour at the maximum 16 kW load, i.e. 44.4 pulses/second.
- **Minimum Pulse Width Calculation**: Use the pulse rate to calculate the minimum pulse width threshold. In our example, with a maximum pulse rate of 44.4/sec, the minimum pulse width we expect to see is approximately 22.5 milliseconds. Choose a slightly smaller value than this to avoid missing pulses.
.. code-block:: yaml
sensor:
- platform: pulse_meter
# ...
internal_filter: 20ms
If a technician shows up and he looks confused about what the heck you have done to your power meter, tell them about ESPHome 😉
Counting total generated energy
-------------------------------
When the total sensor is configured, ``pulse_meter`` also reports the total number of pulses measured. When used on a power meter, this can be used to measure the total transmitted energy in kWh.
.. code-block:: yaml
# Example configuration entry
sensor:
- platform: pulse_meter
# ...
total:
name: "Electricity Total"
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 3
filters:
- multiply: 0.0001 # (1/10000 pulses per kWh)
# - average_throttle: 10s
# - filter_out: NaN
(Re)Setting the total energy value
----------------------------------
Using this action, you are able to reset/set the total pulse count. This can be useful if you would like the ``total`` sensor to match what you see on your meter you are trying to match.
.. code-block:: yaml
api:
services:
- service: set_total
variables:
new_total: int
then:
- pulse_counter.set_total_pulses:
id: sensor_pulse_meter
value: !lambda 'return new_total * 1000;'
Tracking Total Daily Energy
---------------------------
Additionally you can also calculate the total daily energy generated, for which you can use the :doc:`Total Daily Energy </components/sensor/total_daily_energy>` using below configuration:
.. code-block:: yaml
sensor:
#(...)
- platform: total_daily_energy
name: 'Total Daily Energy'
id: sensor_total_daily_energy
power_id: sensor_energy_pulse_meter
unit_of_measurement: 'kWh'
state_class: total_increasing
device_class: energy
accuracy_decimals: 3
filters:
# Multiplication factor from W to kW is 0.001
- multiply: 0.001
time:
- platform: homeassistant
id: homeassistant_time
While you can in theory also do this with the home assistant `integration <https://www.home-assistant.io/integrations/integration/>`__ integration, the benefit of this is that it continues to integrate the power during times home assistant is unable to work with values, i.e. during updates, restarts and so on.
See Also
--------
- :doc:`/components/sensor/pulse_counter`
- :doc:`/components/sensor/pulse_meter`
- :doc:`/components/sensor/total_daily_energy`
- :doc:`/components/time/homeassistant`
- `Home Assistant Glow 🌟 <https://github.com/klaasnicolaas/home-assistant-glow/>`__.
- :ghedit:`Edit`

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB