The problem
It started simply enough. I have a cheap Chinese diesel heater in my summerhouse — a Sunster (masquarading as a Vevor 218E, but more on this later) — and I wanted to add thermostat control. These heaters don’t have one built in as standard which I think is a massive oversight. Turn em on, and they just keep getting warmer and warmer and warmer! A quick Google suggested a few approaches including: spoofing the Bluetooth protocol, or splicing wires into the controller’s signal lines to simulate button presses.
What followed was a two-month rabbit hole that ended with a fully automated summerhouse controlled by a touchscreen panel, a Raspberry Pi, an ESP32 sensor node, and Home Assistant — all tied together with Bluetooth, Wi-Fi, and a surprising amount of patience.
The hardware
Here’s what ended up in the build:
- Raspberry Pi 4 — running Home Assistant OS, the brains of the operation
- Raspberry Pi 3B+ — running Raspberry Pi OS as a dedicated kiosk display
- Waveshare 7″ HDMI LCD (H) — 1024×600 capacitive touchscreen
- ESP32-WROOM-32 (AZ-Delivery) — sensor node for outdoor temperature and fuel monitoring
- Sunster (Vevor 218E) diesel heater with rotary controller
- Victron SmartSolar MPPT — solar charge controller with Bluetooth
- Smart Life / Tuya smart plugs and bulbs — lights, arcade machine, sprinklers
- DS18B20 waterproof temperature probe — outdoor temperature
- HX711 load cell amplifier + 20kg load cell — fuel tank weight monitoring
The approach: Bluetooth all the way
The first big decision was whether to physically splice wires into the heater controller or go the Bluetooth route. After some research, it turned out the heater’s Bluetooth protocol had already been reverse engineered by the community. A HACS integration called homeassistant-diesel-heater supports the Vevor/Sunster/BYD family of heaters using the AA55 protocol.
This was massively better than the relay approach:
- No physical modifications to the heater
- Full sensor data back from the heater — room temperature, running step, voltage, fault codes, fuel consumption estimates
- The heater’s own running state (Standby, Running, Cooling) could be used directly in automations
The Pi 4’s built-in Bluetooth handled the connection. No dongles, no extra hardware.
The thermostat automation
This was the core of the project. The heater needed smart on/off control with a few important constraints:
- Don’t restart the heater during its cooldown/shutdown cycle
- If the thermostat is enabled and the room is already cold, start immediately
- Handle the case where the room cools during cooldown and the heater needs to restart once it’s safe
The solution used Home Assistant’s automation engine with four triggers and a choose block:
trigger:
- platform: numeric_state
entity_id: sensor.diesel_heater_interior_temperature
below: 23
id: too_cold
- platform: template
value_template: >
{{ states('sensor.diesel_heater_interior_temperature') | float > 25.9
and states('switch.diesel_heater_power') == 'on' }}
id: warm_enough
- platform: state
entity_id: sensor.diesel_heater_running_step
to: Standby
id: cooldown_complete
- platform: state
entity_id: input_boolean.thermostat_enabled
to: "on"
id: thermostat_turned_on
The clever bit is the warm_enough trigger — rather than a simple numeric_state above trigger (which only fires on crossing), a template trigger evaluates continuously. This solved a frustrating bug where the heater wouldn’t turn off if the temperature was already above the threshold when the automation was saved.
The cooldown_complete trigger watches for the heater’s running step to return to Standby, then checks if the room is still cold — if so, it restarts the heater automatically. No blind timers needed.
The Kiosk touchscreen
Getting a proper kiosk display working on Raspberry Pi OS turned out to be trickier than expected. The key lessons:
- Use Raspberry Pi OS with Desktop, not Lite — building a display stack from scratch is painful
- Switch to X11, not Wayland — touch scrolling in Chromium works properly on X11
- Use a
while trueloop with a generous sleep to restart Chromium if it crashes, but not so aggressively that you get runaway process spawning
The final working autostart:
Exec=bash -c "sleep 10 && while true; do chromium-browser --noerrdialogs --disable-infobars --kiosk --touch-events=enabled --disable-dev-shm-usage --memory-pressure-off --enable-pinch --overscroll-history-navigation=0 'http://192.168.0.152:8123/dashboard-summerhouse/home?kiosk&access_token=YOUR_TOKEN'; sleep 30; done"
The sleep 10 at the start gives the network time to come up before Chromium launches — skipping this caused Chromium to crash-loop on boot and eventually exhaust all RAM, freezing the Pi completely.
Screen blanking after 5 minutes of inactivity, with instant wake on touch:
@xset s 300
@xset dpms 300 300 300
@xset s blank
The ESP32 sensor node
An AZ-Delivery ESP32-WROOM-32 running ESPHome handles two sensors. Now if you know how much I hate soldering, you can guess this was a nightmare part! Still trying to find a tidier/easier way than soldering to make this all work TBH!
DS18B20 outdoor temperature
A waterproof stainless steel temperature probe, wired with a 5.1kΩ pull-up resistor between VCC and the data line (4.7kΩ is standard but 5.1kΩ works fine):
one_wire:
- platform: gpio
pin: GPIO4
sensor:
- platform: dallas_temp
name: "Temperature Outside"
update_interval: 60s
Fuel tank weight (Load cell + HX711)
At first I tried an ultrasonic sensor mounted in the tank, but this was problematic for a small 5L jerry can because it had a minimum range of 20cm. Instead, a 20kg load cell sits under the fuel tank. The HX711 amplifier reads it via two GPIO pins:
- platform: hx711
name: "Fuel Tank Weight"
dout_pin: GPIO17
clk_pin: GPIO16
gain: 128
update_interval: 60s
unit_of_measurement: kg
filters:
- calibrate_linear:
- 667083 -> 0
- 559977 -> 1
- offset: -0.90
- median:
window_size: 5
send_every: 5
send_first_at: 5
- lambda: return max(x, 0.0f);
Calibration required two reference points — empty (raw value) and a known 1kg weight. The median filter smooths out the inevitable noise from a load cell in a non-lab environment.
A template sensor converts weight to litres (diesel ≈ 0.835 kg/L):
template:
- sensor:
- name: "Fuel Tank Litres"
unit_of_measurement: "L"
state: "{{ (states('sensor.shed_sensor_fuel_tank_weight') | float / 0.835) | round(1) }}"
The dashboard
The summerhouse dashboard uses a two-column layout with layout-card, showing:
- Weather forecast (Met.no — no API key needed, works immediately)
- Inside and outside temperature gauges
- Solar power and battery voltage from the Victron
- Heater thermostat toggle and power switch
- Heater level slider
- Fuel tank gauge with colour-coded severity
- Arcade machine and sprinkler controls
- All lights master switch with individual colour controls
- London air quality from the TfL API (because, why not?)

The TfL air quality integration uses HA’s RESTful sensor:
rest:
- resource: https://api.tfl.gov.uk/AirQuality/
scan_interval: 43200
sensor:
- name: "TfL Air Quality"
value_template: "{{ value_json.currentForecast[0].forecastBand }}"
json_attributes_path: "$.currentForecast[0]"
json_attributes:
- forecastSummary
- nO2Band
- o3Band
- pM10Band
- pM25Band
- sO2Band
Other automations
Low fuel warning — wakes the kiosk screen and creates a persistent notification when fuel drops below 0.5L:
action:
- service: shell_command.wake_kiosk
- service: persistent_notification.create
data:
title: "⛽ Low Fuel Warning"
message: "Fuel tank is below 0.5 litres!"
Arcade machine + Wake on LAN — tapping the Arcade Machine button turns on the smart plug. I tried to get it to send a WOL magic packet to wake my Windows 10 Boot Camp MacBook, but I couldn’t get this to work how I wanted. The Mac would just remain on indefinitely so the battery would run down too much to wake it.
Sprinkler automation — waters at 7am and 9pm for 5 minutes, skipping if it has rained recently according to the Met.no forecast.
Lessons learnt?
- HA OS disk space — 16GB is not enough. 64GB minimum. The Docker containers for add-ons alone consume 11GB.
- The supervisor DNS bug — after fresh installs, the HA supervisor incorrectly reports no internet connection, blocking add-on installation. Fix: temporarily set DNS to 8.8.8.8 in network settings.
- Bluetooth device discovery — if your phone’s Bluetooth app is connected to a device, HA can’t discover it. Always disconnect from phone apps before pairing in HA.
- Chromium touch scrolling on Wayland — doesn’t work properly. Switch to X11 via raspi-config.
- Load cell minimum range — ultrasonic sensors have a ~20cm minimum range, useless for a small fuel tank. A load cell is the right solution.
What’s next
- CO monitor (Heiman Matter device — no hub needed)
- ESP32 in a weatherproof enclosure near the fuel tank
- Onkyo AV receiver integration for the games room
The takeaway
What started as “can I add a thermostat to a cheap diesel heater” became a fully integrated smart building with Bluetooth sensors, an ESP32 sensor node, a touchscreen control panel, solar monitoring, fuel tracking, air quality data, automated watering, and remote Wake on LAN for a retro gaming setup.
The key insight was that Home Assistant, once running, makes adding each new thing incrementally easy — the hard part is getting the foundation right. Once that’s done, everything else is just YAML.
Total cost of the automation hardware (not including the heater, solar setup, or gaming equipment that was already there): roughly £60-80, mostly the Raspberry Pi 4, SD card, and ESP32.
Nice little project! But would I extend it to the rest of my house? I don’t know… HA still seems a bit buggy here and there, so I don’t know if the rest of my family would appreciate having to google things if they just want to turn on the TV!