How to: Daily rain sensor from cumulative sensor using MQTT and template_sensor

Tags: #<Tag:0x00007f3f16af54e0> #<Tag:0x00007f3f16af51e8> #<Tag:0x00007f3f16af4d88>

Hi phileep, yes slow is fine, I don’t rush either as it’s too stressful to try.

Yes I use MQTT for about a dozen other sensors like BruhAutomation MultiSensor and Tasmota’s FW on Sonoff products, so it’s there and running well right now with those.

What is not clear also is why I get some ‘package’ errors when I restart HASS server regardless for a while now,
Edit: OK bla blah bla yep sure I have a standing issue with ‘packages errors’ and failed verification from a HA GUI soft ‘server restart’ since a couple of updates back, which means I could not really test new configurations…
I hope HA will get sorted regarding this as I have NFI what that cryptic log entry means and how to ‘fix’ it as HA does in fact restart fine from a power off reset meaning the ‘packages error’ stuff is a red herring I guess…
Moving back to the topic of THIS thread below…

Hi again phileep. OK I can now report success with your method and your code. Yippeee!

My trouble was not the code I’d made last attempt but the issue/bug stopping me from reloading configuration.yaml via HA to actually use it !

This works for me now that I’ve learned to just hard reset the RPi, your code with a few name changes, but basically the same.

#New MQTT stuff to create daily rain measurements
  - platform: mqtt
    state_topic: 'ha/total_rain_prior'
    name: 'rain_total_prior'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain:
        value_template: '{%- if not (is_state("sensor.dkw2012_00f7_raintot","unknown") or is_state("sensor.rain_total_prior","unknown") )-%}  {{ ((states.sensor.dkw2012_00f7_raintot.state | float) - (states.sensor.rain_total_prior.state | float)) | max (0) | round(1) }} {%- endif -%}' ## ensure calc is no lower than zero!
        friendly_name: 'Rain from 9AM today'
        unit_of_measurement: 'mm'

Automation.

- alias: 'Record total rain at 9AM'
  trigger:
    platform: time
    at: '09:00:00'
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/total_rain_prior'
      retain: true
      payload: '{"day_1":"{{states.sensor.dkw2012_00f7_raintot.state}}"}' 
1 Like

i read this thread but dont understand.

i ve a rflink sensor, perhaps anyone can give me the right code

  - platform: rflink
    devices:
      cresta_8001_raintot:
        name: RegenTotal
        sensor_type: total_rain
```EDIT

i try this

'''
# Regen
  - alias: 'Regen seit Mitternacht'
    trigger:
      - platform: time
        after: '00:00:01'
    action:
      - service: mqtt.publish
      - data_template:
          topic: 'ha/cum_rain_prior'
          retain: true
          payload: '{"day_1":"{{states.regentotal.state}}"}'
'''

'''
  - platform: mqtt
    state_topic: 'ha/total_rain_prior'
    name: 'rain_total_prior'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain:
        value_template: '{%- if not (is_state("sensor.regentotal","unknown") or is_state("sensor.regentotal_prior","unknown") )-%}  {{ ((states.sensor.regentotal.state | float) - (states.sensor.raintotal_prior.state | float)) | max (0) | round(1) }} {%- endif -%}' ## ensure calc is no lower than zero!
        friendly_name: 'Rain from 9AM today'
        unit_of_measurement: 'mm'
'''

and get this error

Invalid config for [automation]: [after] is an invalid option for [automation]. Check: automation->trigger->0->after. (See /config/configuration.yaml, line 79). Please check the docs at https://home-assistant.io/components/automation/

See the time trigger automations here …

Basically after: needs to be changed to at: (this was a change to homeassistant after I wrote the original post)

I will edit it now - hope it works for you once you make the change.

1 Like

thx. no error anymore. but, it seems my code is wrong. i get no values.

sensor:

  - platform: rflink
    devices:
      cresta_8001_raintot:
        name: RegenTotal
        sensor_type: total_rain
    # Rain is cumulative forever - collect it and subtract yesterday for todays rain
  - platform: mqtt
    state_topic: 'RF/DKW2012-ID=004c'
    name: 'regentotal'
    icon: mdi:weather-rainy
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.RAIN }}'     
  - platform: mqtt
    state_topic: 'ha/regentotal_prior'
    name: 'regentotal_prior'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain:
        value_template: '{%- if not (is_state("sensor.regentotal","unknown") or is_state("sensor.regentotal_prior","unknown") )-%}  {{ ((states.sensor.regentotal.state | float) - (states.sensor.regentotal_prior.state | float)) | max (0) | round(1) }} {%- endif -%}' ## ensure calc is no lower than zero!
        friendly_name: 'Rain Today'
        unit_of_measurement: 'mm

automatic:

  - alias: 'record cumulative rain to midnight'
    trigger:
      - platform: time
        at: "00:00:01"
    action:
      service: mqtt.publish
      data_template:
        topic: 'ha/cum_rain_prior'
        retain: true
        payload: '{"day_1":"{{states.sensor.regentotal.state}}"}'

Can you trigger the automation ‘record cumulative rain to midnight’ manually in the HA gui and get any result ?
Should match the current station rain total.

@noxx, if @mr.sneezy’s suggestion does not work, try and ascertain if you have values in your 3 sensors.

easiest to check in the states tab

Is there a numeric value in sensor.regentotal ?
same for sensor.regentotal_prior ?

If either is unknown, then you will not get a value in the template sensor (although you SHOULD get 0 as the calculation from the sensor using the if tests nested in it)

@phileep
my values are all empty or unknown.

can you add your rflink device ( RF weather sensor) here? so i can see the difference between us.

@noxx,

My config is in post #1

my values per the states tab currently are:

no rain today here!

looks like you are using different MQTT topics for the prior cumulative total.

i think your automation should post to the state_topic: ‘ha/regentotal_prior’ the same as your sensor, not topic: ‘ha/cum_rain_prior’

I think I actually got this working with telldus live… but with a workaround :smiley:
My telldus is connected to hass -->
hass sends the values to influxdb -->
node-red takes the values from influxdb and turns them into a mqtt message --> success! :beers:

Any ideas for fetching yesterdays max value and presenting as a sensor?

Glad it is working

Are you talking about yesterday’s max temperature, or yesterday’s total rainfall (for the day)?

Either way, if the value is in MQTT, then add an MQTT sensor to read the MQTT value into HASS as a sensor … then you can show it in homeassistant.

If you need to do a calculation on the value (ie subtract one from another), then use a template sensor

This is all I used in the original method in post #1

I had a similar issue in which, apparently, no values were shown in the Influxdb graphs. This got solved when I ticked, in Grafana, the box to fill blanks with the previous value.

Dump question how do u reset to 0 am I missing something

I would like to get data for last day, last week, last month.

I tried this:

 - platform: mqtt
    state_topic: 'ha/cum_rain_prior'
    name: 'rain_cum_prior'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain_last_0:
        value_template: '{%- if not (is_state("sensor.alectov5_00ef_raintot","unknown") or is_state("sensor.rain_cum_prior","unknown") )-%}  {{ ((states.sensor.alectov5_00ef_raintot.state | float) - (states.sensor.rain_cum_prior.state | float)) | max (0) | round(1) }} {%- endif -%}' 
        ## ensure calc is no lower than zero!
        friendly_name: 'Rain Today'
        unit_of_measurement: 'mm'

  - platform: mqtt
    state_topic: 'ha/cum_rain_prior'
    name: 'rain_cum_prior_7'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_7 }}' 
  - platform: template
    sensors:
      rain_last_7:
        value_template: '{%- if not (is_state("sensor.alectov5_00ef_raintot","unknown") or is_state("sensor.rain_cum_prior_7","unknown") )-%}  {{ ((states.sensor.alectov5_00ef_raintot.state | float) - (states.sensor.rain_cum_prior_7.state | float)) | max (0) | round(1) }} {%- endif -%}' 
        ## ensure calc is no lower than zero!
        friendly_name: 'Rain Last Week'
        unit_of_measurement: 'mm'  

  - platform: mqtt
    state_topic: 'ha/cum_rain_prior'
    name: 'rain_cum_prior_30'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_30 }}' 
  - platform: template
    sensors:
      rain_last_30:
        value_template: '{%- if not (is_state("sensor.alectov5_00ef_raintot","unknown") or is_state("sensor.rain_cum_prior_30","unknown") )-%}  {{ ((states.sensor.alectov5_00ef_raintot.state | float) - (states.sensor.rain_cum_prior_30.state | float)) | max (0) | round(1) }} {%- endif -%}' 
        ## ensure calc is no lower than zero!
        friendly_name: 'Rain Last Month'
        unit_of_measurement: 'mm'            

automations:

- alias: 'record cumulative rain to midnight'
  trigger:
    - platform: time
      at: "00:00:01"
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/cum_rain_prior'
      retain: true
      payload: '{"day_1":"{{states.sensor.alectov5_00ef_raintot.state}}"}' 

- alias: 'record cumulative rain for last week'
  trigger:
    - platform: time
      at: "00:00:01"
  condition:
    - condition: time
      weekday:
        - mon 
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/cum_rain_prior'
      retain: true
      payload: '{"day_7":"{{states.sensor.alectov5_00ef_raintot.state}}"}' 

- alias: 'record cumulative rain for last month'
  trigger:
    - platform: time
      at: "00:00:01"
  condition:
    - condition: template
    # Change the number here to get whatever day of the month you want.
      value_template: "{{ now().day == 1 }}"
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/cum_rain_prior'
      retain: true
      payload: '{"day_30":"{{states.sensor.alectov5_00ef_raintot.state}}"}' 

…but it’s not really working. For example foro today I always get 0.

Use different MQTT topics for each stored value, because there can be only one retained message in a topic.

Hi @realthk. I changed as you suggested, but still not working:

- platform: mqtt
    state_topic: 'ha/cum_rain_prior'
    name: 'rain_cum_prior'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain_last_0:
        value_template: '{%- if not (is_state("sensor.alectov5_00ef_raintot","unknown") or is_state("sensor.rain_cum_prior","unknown") )-%}  {{ ((states.sensor.alectov5_00ef_raintot.state | float) - (states.sensor.rain_cum_prior.state | float)) | max (0) | round(1) }} {%- endif -%}' 
        ## ensure calc is no lower than zero!
        friendly_name: 'Rain Today'
        unit_of_measurement: 'mm'

  - platform: mqtt
    state_topic: 'ha/cum_rain_prior_7'
    name: 'rain_cum_prior_7'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain_last_7:
        value_template: '{%- if not (is_state("sensor.alectov5_00ef_raintot","unknown") or is_state("sensor.rain_cum_prior_7","unknown") )-%}  {{ ((states.sensor.alectov5_00ef_raintot.state | float) - (states.sensor.rain_cum_prior_7.state | float)) | max (0) | round(1) }} {%- endif -%}' 
        ## ensure calc is no lower than zero!
        friendly_name: 'Rain Last Week'
        unit_of_measurement: 'mm'  

  - platform: mqtt
    state_topic: 'ha/cum_rain_prior_30'
    name: 'rain_cum_prior_30'
    unit_of_measurement: 'mm'
    value_template: '{{ value_json.day_1 }}' 
  - platform: template
    sensors:
      rain_last_30:
        value_template: '{%- if not (is_state("sensor.alectov5_00ef_raintot","unknown") or is_state("sensor.rain_cum_prior_30","unknown") )-%}  {{ ((states.sensor.alectov5_00ef_raintot.state | float) - (states.sensor.rain_cum_prior_30.state | float)) | max (0) | round(1) }} {%- endif -%}' 
        ## ensure calc is no lower than zero!
        friendly_name: 'Rain Last Month'
        unit_of_measurement: 'mm'    

- alias: 'record cumulative rain to midnight'
  trigger:
    - platform: time
      at: "00:00:01"
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/cum_rain_prior'
      retain: true
      payload: '{"day_1":"{{states.sensor.alectov5_00ef_raintot.state}}"}' 

- alias: 'record cumulative rain for last week'
  trigger:
    - platform: time
      at: "00:00:01"
  condition:
    - condition: time
      weekday:
        - mon 
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/cum_rain_prior_7'
      retain: true
      payload: '{"day_1":"{{states.sensor.alectov5_00ef_raintot.state}}"}' 

- alias: 'record cumulative rain for last month'
  trigger:
    - platform: time
      at: "00:00:01"
  condition:
    - condition: template
    # Change the number here to get whatever day of the month you want.
      value_template: "{{ now().day == 1 }}"
  action:
    service: mqtt.publish
    data_template:
      topic: 'ha/cum_rain_prior_30'
      retain: true
      payload: '{"day_1":"{{states.sensor.alectov5_00ef_raintot.state}}"}'

Is that like this in the config file?
The “- platform: mqtt” and “- platform: template” records should be under “sensor:” and the triggered actions under “automation:”

I did the same and it works fine.

There is a problem with that approach above: that chinese sensor resets its value after a battery replacement (or just after a short power-out, that happened because for example a cat bumped into the sensor and it fell over to its side), which results in losing the history data!
(as the prior state saved in MQTT suddenly becomes much higher than the current sensor value)
That does not matter for hourly measurement, but I would not like to lose weekly or monthly values.

So I changed the workflow to catch any change in sensor current value, calculate the difference by substracting the old value from it (and zero out difference if old value was higher after a sensor reset, and also first insert 0 to make sure if the difference remains the same between 2 updates it still will trigger an update) store the current value, and update all counters by adding this difference to them. This way all I need to do is reset these counters daily/weekly/monthly.

automation:
  - alias: 'rain sensor value changed'
    trigger:
      - platform: state
        entity_id: sensor.rain_total
    action:
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_difference'
          retain: true
          payload: 0
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_difference'
          retain: true
          payload: >
            {% if (((states.sensor.rain_total.state | float) - (states.sensor.rain_total_last_value.state | float)) | max (0) ) > 0 %} 
              {{ ((states.sensor.rain_total.state | float) - (states.sensor.rain_total_last_value.state | float)) | max (0) | round(1)  }}
            {% else %}
              0
            {% endif %}
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_total_last_value'
          retain: true
          payload: "{{states.sensor.rain_total.state}}" 

  - alias: 'rain difference changed'
    trigger:
      - platform: state
        entity_id: sensor.rain_difference
    condition:   
        condition: numeric_state     
        entity_id: sensor.rain_difference
        above: 0   
    action:
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_hour'
          retain: true
          payload: '{{ ((states.sensor.rain_hour.state | float) + (states.sensor.rain_difference.state | float)) | round(1) }}'
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_today'
          retain: true
          payload: '{{ ((states.sensor.rain_today.state | float) + (states.sensor.rain_difference.state | float)) | round(1) }}'
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_week'
          retain: true
          payload: '{{ ((states.sensor.rain_week.state | float) + (states.sensor.rain_difference.state | float)) | round(1) }}'
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_month'
          retain: true
          payload: '{{ ((states.sensor.rain_month.state | float) + (states.sensor.rain_difference.state | float)) | round(1) }}'
      - service: homeassistant.update_entity
        entity_id: sensor.rain_hour          
      - service: homeassistant.update_entity
        entity_id: sensor.rain_today          
      - service: homeassistant.update_entity
        entity_id: sensor.rain_week          
      - service: homeassistant.update_entity
        entity_id: sensor.rain_month   

  - alias: 'reset rain for hour'
    trigger:
      - platform: time_pattern
        minutes: 0     
    action:
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_hour'
          retain: true
          payload: 0 
  - alias: 'reset rain today'
    trigger:
      - platform: time
        at: "00:00:01"
    action:
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_today'
          retain: true
          payload: 0 
  - alias: 'reset rain for week'
    trigger:
      - platform: time
        at: "00:00:01"
    condition:
      - condition: time
        weekday:
          - mon 
    action:
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_week'
          retain: true
          payload: 0
  - alias: 'reset rain for month'
    trigger:
      - platform: time
        at: "00:00:01"
    condition:
      - condition: template
        value_template: "{{ now().day == 1 }}"
    action:
      - service: mqtt.publish
        data_template:
          topic: 'ha/rain_month'
          retain: true
          payload: 0

sensor:
    - platform: mqtt
      state_topic: 'ha/rain_total_last_value'
      name: 'rain_total_last_value'
      unit_of_measurement: 'mm'
      value_template: '{{ value_json }}' 
    - platform: mqtt
      state_topic: 'ha/rain_difference'
      name: 'rain_difference'
      unit_of_measurement: 'mm'
      value_template: '{{ value_json }}' 

    - platform: mqtt
      state_topic: 'ha/rain_hour'
      name: 'rain_hour'
      unit_of_measurement: 'mm'
      value_template: '{{ value_json }}' 
    - platform: mqtt
      state_topic: 'ha/rain_today'
      name: 'rain_today'
      unit_of_measurement: 'mm'
      value_template: '{{ value_json }}' 
    - platform: mqtt
      state_topic: 'ha/rain_week'
      name: 'rain_week'
      unit_of_measurement: 'mm'
      value_template: '{{ value_json }}' 
    - platform: mqtt
      state_topic: 'ha/rain_month'
      name: 'rain_month'
      unit_of_measurement: 'mm'
      value_template: '{{ value_json }}'
2 Likes

Can I just say thanks - I’ve added this to my system, and it works beautifully.

1 Like