Recent project that a combination of HA and ESPHome made much easier than I expected. Central heating is oil fired - and our tank has no sight tube. When installed it did have a remote level sensor, but the batteries in the sender died a while back and I hadn’t got round to replacing them - and the inside element was a rather bulky ugly plug.
Time for a proper sensor…a waterproof SR04 compatible sensor TE501 , a D1 mini and a 7 Neopixel disc (left over from previous projects) makes a compact oil level sensor.
SR04 was mounted in the filler cap with plenty of hot glue to seal. D1Mini (powered by an old USB charger) and the Neopixels are in a water proof box on the adjacent garage. The neopixels are bright enough to shine through without a problem. I added a DS1820 temp sensor because why not.
The d1mini converts the distance to a % - I dont allow for the odd shape of the tank just a simple % of distance to empty and luckily that is more or less exactly 25cm to 125cm for this tank so its very simple.
HA converts the % fill to an “OK”/“Alert”/“Critical” badge and turns on the light/sets color when it changes status via NodeRed. The light is also turned for a few minutes when the door/gate adjacent is opened as a reminder of current state.
Testing…
And Installed…
ESPHome yaml
esphomeyaml:
name: esp_oilsensor
platform: ESP8266
board: d1_mini
wifi:
domain: .local
ssid: xxxxx
password: xxxxxxx
manual_ip:
static_ip: 192.168.1.50
gateway: 192.168.1.254
subnet: 255.255.255.0
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
substitutions:
# Unique ID
esp_id: "esp_oil"
dallas:
- pin: D1
sensor:
- platform: ultrasonic
trigger_pin: D6
echo_pin: D5
name: "Oil Tank SR04"
unit_of_measurement: "cm"
id: ${esp_id}_sr04
update_interval: 5s
accuracy_decimals: 1
filters:
- multiply: 100
- sliding_window_moving_average:
window_size: 12
send_every: 12
- platform: dallas
address: 0x890008008D53E610
name: "Oil Tank Temperature"
id: ${esp_id}_temp
- platform: template
name: "Oil Tank Level"
id: ${esp_id}_level
accuracy_decimals: 0
unit_of_measurement: "%"
icon: "mdi:oil"
lambda: |-
if (id(${esp_id}_sr04).state > 160 ) {
return 999;
} else if (id(${esp_id}_sr04).state > 125) {
return 0;
} else {
return (125 - (int) id(${esp_id}_sr04).state);
}
update_interval: 30s
light:
- platform: neopixelbus
name: "Oil Tank Light"
id: ${esp_id}_light
type: GRB
method: BIT_BANG
default_transition_length: 0s
pin: D2
num_leds: 7
HA Template Sensor
- platform: template
sensors:
oil_status:
friendly_name: "Oil Status"
unit_of_measurement: ""
value_template: >
{% if states.sensor.oil_tank_level.state == 999 %}
Error
{% elif states.sensor.oil_tank_level.state | int > 15 %}
OK
{% elif states.sensor.oil_tank_level.state | int > 7 %}
Warning
{% else %}
Alert
{% endif %}
icon_template: >
{% if states.sensor.oil_tank_level.state == 999 %}
mdi:alert-decagram
{% elif states.sensor.oil_tank_level.state | int > 15 %}
mdi:check-circle-outline
{% elif states.sensor.oil_tank_level.state | int > 7 %}
mdi:alert-circle-outline
{% else %}
mdi:alert-circle
{% endif %}
entity_picture_template: >-
{% if states.sensor.oil_tank_level.state == 999 %}
/local/cancel.png
{% elif states.sensor.oil_tank_level.state | int > 15 %}
/local/ok.png
{% elif states.sensor.oil_tank_level.state | int > 7 %}
/local/warning-shield.png
{% else %}
/local/high-priority.png
{% endif %}