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

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 }}'
3 Likes

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

1 Like

Hi @Naesstrom, I see I have the same rain sensor as you. I eventually get to see a sensor in HA but it does not seem to work reliable. Is it working reliable in your case? My concerns are:

  1. I find it hard to link with my HA
  2. It does not seem to keep a steady heart beat with HA if no rain is falling
  3. It sometimes rains but the sensor does not notice

btw, I have 3 additional 433 devices and they work just fine with my setup that’s why I’m pointing towards this device.

thanks!!

Hi, the chinese sensor send data via

sensor.rain_total

?

Thanks

Here is how I did it:

Create a statistics sensor, which only looks back 24 hours (max_age) on the rain total sensor.
Then create a template sensor to extract the “change” attribute from the new statistics sensor. (Not technically needed, as you could extract the change attribute directly into any automation as needed, but I like to have it)

I’m getting my rain sensor from a 433mhz weather station, received via Home-Assistant-RFLink-Gateway-ESP8266 and imported to Home Assistant using the RF-Link Sensors

Here is my configuration: genestealer / Home-Assistant-Configuration


sensor:
- platform: statistics
    name: Local Rain 24 Hours Statistics
    entity_id: sensor.rain_total
    sampling_size: 4320 # Enough for 3 readings a minute
    max_age:
      hours: 24

  - platform: template
    sensors:
      template_rain_last_24_hours:
        friendly_name: "Local Rain 24 Hours"
        unit_of_measurement: 'mm'
        value_template: "{{ state_attr('sensor.local_rain_24_hours_statistics', 'change') }}"

image

image

1 Like

hello Realthk
is this automation still working in your home assistant. For some reason my values are not updated anymore after the latest home assistant update. Thanks.

I don’t use it any more, but would not do like this now, rather use simple utility meters (with cycles hourly, daily, weekly, monthly) which is a simple 2 lines config and takes care of any value reset.

(when this topic was started, there was no utility meter in HA, that only came somewhere in 2019)