Oil Tank Level Monitor Watchman Sonic rtl_433 Integration for RF sensors or level sensors

Thanks dingledell for trailblazing this implementation. I wanted to leverage it to shoehorn my estimated oil usage into the new energy management system in Home Assistant (as mentioned here Energy Management - Allow 'Oil' in addition to 'Gas').

The problem I came across is that the variance on the sonar measurement is quite high, can vary by 2-3cm in depth throughout the day due to ambient temperature etc… To overcome this I tied together a bunch of things to ensure I only ever take the minimum measurement, with “fill up” detection, and compute the difference in volume from measurement to measurement manually.

I followed your suggestion on setting up MQTT to send the rtl-433 data across to home assistant:

- platform: mqtt
  state_topic: "home/rtl_433"
  name: "Raw oil measurement"
  value_template: >-
    {% set x = 0.52 %}
    {% set y = (104 - (value_json.depth_cm | int(0)) + 5) | float(0) * 0.01 %}
    {% set z = 1.63 %}
    {{ ((x*x*acos((x-y)/x) - (x-y)*sqrt(2*x*y-y*y))*z*1000) | round(0,default=0) }}
  unit_of_measurement: 'L'
  state_class: measurement
  availability_template: >- 
    {{ (value_json.depth_cm | int(0)) > 0 }}

I have a horizontal cylinder so I compute the volume accordingly. Then I have a couple of input numbers I use to store persistent variables and a template variable tracking the change in oil volume between measurements:

input_number:
  curr_oil:
    name: Current Oil
    unit_of_measurement: L
    min: 0
    max: 1380
    step: 1
  cumulative_oil:
    name: Cumulative Oil
    unit_of_measurement: L
    min: 0
    max: 16777215
    step: 1

- platform: template
  sensors:
    oil_measurement_diff:
       friendly_name: "Oil Measurement Diff"
       unit_of_measurement: "L"
       value_template: '{{ states("input_number.curr_oil") | int(0) - states("sensor.raw_oil_measurement") | int(0) }}'
       availability_template: >- 
        {{ not is_state("sensor.raw_oil_measurement", "unavailable") and not is_state("sensor.raw_oil_measurement", "unknown") }}

Then my automation, whenever a new MQTT measurement arrives, if the volume of the tank has increased by 100L, I assume it was filled up and just set the current level to that amount. Otherwise, if the volume of the tank is lower than the lowest value read since the last time it was filled up, I add the difference in volume to the cumulative volume change and update the current (lowest) level:

  alias: Oil Aggregation
  description: ''
  trigger:
  - platform: event
    event_type: state_changed
    event_data:
      entity_id: sensor.oil_measurement_diff
  condition: []
  action:
  - choose:
    - conditions:
      - condition: numeric_state
        entity_id: sensor.oil_measurement_diff
        below: '-100'
      sequence:
      - service: input_number.set_value
        data_template:
          value: '{{ states(''sensor.raw_oil_measurement'') | int(0) }}'
        target:
          entity_id: input_number.curr_oil
    - conditions:
      - condition: numeric_state
        entity_id: sensor.oil_measurement_diff
        above: '0'
      sequence:
      - service: input_number.set_value
        data_template:
          value: '{{ states(''input_number.cumulative_oil'') | int(0) + states(''sensor.oil_measurement_diff'')
            | int(0) }}'
        target:
          entity_id: input_number.cumulative_oil
      - service: input_number.set_value
        data_template:
          value: '{{ states(''sensor.raw_oil_measurement'') | int(0) }}'
        target:
          entity_id: input_number.curr_oil
    default: []
  mode: single

Finally I have another template to put the cumulative volume used into a format consumable by the gas consumption energy integration:

template:
  - sensor:
      - name: "Oil Energy"
        state: >-
             {{ states('input_number.cumulative_oil') | float(0) * 10.35  }}
        device_class: energy
        state_class: total
        unit_of_measurement: "kWh"

My sensor updates hourly but my usage is so low I don’t expect to be able to track things at a high temporal resolution, more likely I’ll see a sudden drop to a lower depth value some days. Over week timescales it should be nice and smooth.

3 Likes