In order for this to work, one has to give the device a unique name under the expert tab in the PTVO configurator and save a custom converter. This is added to Zigbee2Mqtt without modifications. Place it in config/zigbee2mqtt and add it via the z2m GUI (Settings → External converters).
Since its using counter modules which accumulate, I used the statistics module to create the required sensors. Heres the Yaml config for that:
(in my case the friendly name is “Wetterstation”, may differ for you)
#########################################################
# #
# BME280 DATA #
# #
#########################################################
- platform: template
sensors:
wetterstation_abs_luftfeuchtigkeit:
value_template: >-
{% set h, t = states('sensor.wetterstation_humidity_l1') | float, states('sensor.wetterstation_temperature_l1') %}
{% if not h or t == 'unknown' -%}
'unknown'
{%- else %}
{% set t = t | float %}
{{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(1) }}
{% endif %}
unit_of_measurement: g/m³
friendly_name: Wetterstation Absolute Luftfeuchtigkeit
- platform: template
sensors:
wetterstation_taupunkt:
friendly_name: "Wetterstation Taupunkt"
value_template: >-
{{ (log( states('sensor.wetterstation_humidity_l1')|int / 100 ) + 18.678 * states('sensor.wetterstation_temperature_l1')|float / (257.14 + states('sensor.wetterstation_temperature_l1')|float ) )| round (1) }}
unit_of_measurement: °C
#########################################################
# #
# RAIN METER #
# #
#########################################################
- platform: statistics
name: "Rain Clicks 24 hours"
entity_id: sensor.wetterstation_l3
state_characteristic: sum_differences_nonnegative
max_age:
hours: 24
- platform: statistics
name: "last rain clicks"
entity_id: sensor.wetterstation_l3
state_characteristic: sum_differences_nonnegative
sampling_size: 2
- platform: statistics
name: "last rain click age"
entity_id: sensor.wetterstation_l3
state_characteristic: datetime_newest
sampling_size: 2
- platform: template
sensors:
rainfall_now:
value_template: >-
{%if states('sensor.last_rain_clicks') == 'unknown' %}
0.0
{% else %}
{% if as_timestamp(now()) - as_timestamp(states('sensor.last_rain_click_age')) > 65 %}
0.0
{% else %}
{{ states('sensor.last_rain_clicks') }}
{% endif %}
{% endif %}
- platform: template
sensors:
rainfall_24h:
friendly_name: Regen 24 Stunden
unit_of_measurement: mm
value_template: >-
{%if states('sensor.rain_clicks_24_hours') == 'unknown' %}
0.0
{% else %}
{% set count = states('sensor.rain_clicks_24_hours') | int %}
{% set mm_per_pulse = 0.30303 %}
{% set mm = count * mm_per_pulse %}
{{ mm|round(1, 'floor') }}
{% endif %}
#########################################################
# #
# ANEMOMETER #
# #
#########################################################
- platform: statistics
name: "last wind clicks"
entity_id: sensor.wetterstation_l4
state_characteristic: sum_differences_nonnegative
sampling_size: 2
- platform: statistics
name: "last wind click age"
entity_id: sensor.wetterstation_l4
state_characteristic: datetime_newest
sampling_size: 2
- platform: template
sensors:
wind_now:
value_template: >-
{%if states('sensor.last_wind_clicks') == 'unknown' %}
0.0
{% else %}
{% if as_timestamp(now()) - as_timestamp(states('sensor.last_wind_click_age')) > 65 %}
0.0
{% else %}
{{ states('sensor.last_wind_clicks') }}
{% endif %}
{% endif %}
- platform: template
sensors:
windspeed:
friendly_name: Windgeschwindigkeit
unit_of_measurement: m/s
# m_per_pulse = (r * 2 * Pi)/2 = (0.09 * 2 * 3.14)/2 = 0.2862 m
value_template: >-
{% set count = states('sensor.wind_now') | int %}
{% set m_per_pulse = 0.2826 %}
{% set mps = count * m_per_pulse / 60 %}
{{ mps|round(1) }}
- platform: template
sensors:
windforce:
friendly_name: Windstärke
icon_template: " mdi:weather-windy"
value_template: "{% set wind = (states('sensor.windspeed')|float)*3.6 %}
{% set wind_round = wind|round(0) %}
{% if wind <= 1 %}Bft: 0, Windstill, {{wind_round}} km/h
{% elif wind <= 5 %}Bft: 1, leiser Zug, {{wind_round}} km/h
{% elif wind <= 11 %}Bft: 2, leichte Briese, {{wind_round}} km/h
{% elif wind <= 20 %}Bft: 3, schwache Briese, {{wind_round}} km/h
{% elif wind <= 28 %}Bft: 4, mäßige Briese, {{wind_round}} km/h
{% elif wind <= 39 %}Bft: 5, frische Briese, {{wind_round}} km/h
{% elif wind <= 50 %}Bft: 6, starker Wind, {{wind_round}} km/h
{% elif wind <= 62 %}Bft: 7, steifer Wind, {{wind_round}} km/h
{% elif wind <= 75 %}Bft: 8, stürmischer Wind, {{wind_round}} km/h
{% elif wind <= 89 %}Bft: 9, Sturm, {{wind_round}} km/h
{% elif wind <= 103 %}Bft: 10, schwerer Sturm, {{wind_round}} km/h
{% elif wind <= 117 %}Bft: 11, orkanartiger Sturm, {{wind_round}} km/h
{% else %} > 117 %}Bft: 12, Orkan, {{wind_round}} km/h
{%- endif %}"
- platform: template
sensors:
beaufort:
friendly_name: Beaufort
value_template: "{% set wind = states('sensor.windgeschwindigkeit')|float %}
{% if wind <= 0.3 %}0
{% elif wind <= 1.5 %}1
{% elif wind <= 3.3 %}2
{% elif wind <= 5.4 %}3
{% elif wind <= 7.9 %}4
{% elif wind <= 10.7 %}5
{% elif wind <= 13.8 %}6
{% elif wind <= 17.1 %}7
{% elif wind <= 20.7 %}8
{% elif wind <= 24.4 %}9
{% elif wind <= 28.4 %}10
{% elif wind <= 32.6 %}11
{% else %} > 32.6 %}12
{%- endif %}"
entity_picture_template: "
{% set state = states('sensor.beaufort') %}
{% set path = '/local/beaufort/' %}
{% set ext = '.jpg'%}
{{[path,state,ext]|join('')|lower}}"
#########################################################
# #
# END OF CONFIGURATION FILE #
# #
#########################################################
Also under the PTVO expert tab, I set the reporting interval to 60s which is rather short, but I want to react to rain or strong winds by closing an awning. If you change the reporting interval, the following line needs to be adjusted:
{% set mps = count * m_per_pulse / 60 %}
In my Case I had to enable some of the used sensors in mqtt first.
And here’s the final result in HA:
Credit to @Doublet who created the original version.