Connecting DeltaSol controller to Home Assistant with ESPHome
Browsing the list of ESPHome components I noticed a picture that looked very familiar. In my house I have this device branded as "Joule" and labeled "DeltaSolⓇ BS HE" and on ESPHome site they show "Resol DeltaSolⓇ BS Plus":
Two devices look very similar and apparently Resol OEMs its devices to other brands. These devices are solar panel controller. Not for the photovoltaic solar panels that I would usually have in mind but instead for solar thermal collectors, which harness solar heat and in my case use it to heat hot water.
The ESPHome component I noticed is called VBus. It does not explicitly list my device (labeled "DeltaSol BS HE" on the outside and "DeltaSol BS/2 HE" inside) as supported. However it provides some guidance in connecting pretty much arbitrary devices that speak VBus protocol.
Connecting VBus device to UART requires adjustment of electrical levels. ESPHome component mentions two schemes. I first tried building an electrically isolated version with an opto-coupler because this should provide better protection of ESP8266/ESP32 device. But it didn't work. I could see adjusted signal levels but neither ESP nor simple TTL-UART USB converter was picking them up.
My second attempt with a more traditional scheme (the first one listed on ESPHome component page) worked and ESP8266 I was using in this case indicated that it was receiving some data.
Prototype on a breadboard:
To decoded the data I had to specify the address of my controller and describe how to extract interesting data from the packet.
Identifying the address is covered in Supported Models section. I just had to enable verbose logging to get the address which in my case was 0x4720.
To extract values from packets I had to define custom VBus sensors. The location of specific values in the packet can be found in VBus Specification - search for specific device and switch to "bytes" mode.
My controller was sending data every second which I think is way too often and is both not useful and unhealthy for the performance of Home Assistant so I applied some throttling.
My Home Assistant widget:
The "Heat quantity" sensor is 0 because my hardware configuration does not count the amount of energy. It would require a sensor on the return flow of the heat-transfer fluid which is not installed.
Here's my configuration of VBus sensor:
# https://esphome.io/components/vbus.html
# http://danielwippermann.github.io/resol-vbus/#/vsf/bytes/00_0010_4720_10_0100
# DeltaSol BS/2 HE
sensor:
- platform: vbus
model: custom
dest: 0x10
source: 0x4720
command: 0x100
sensors:
- id: temperature_1
name: Temperature 1
device_class: temperature
state_class: measurement
unit_of_measurement: "°C"
accuracy_decimals: 1
lambda: |-
unsigned lsb = x[4];
unsigned msb = x[5];
if (msb > 127) {
return (65536 - msb * 256 - lsb) * -0.1f;
}
return (msb * 256 + lsb) * 0.1f;
filters:
- sliding_window_moving_average:
window_size: 30
send_every: 30
- id: temperature_2
name: Temperature 2
device_class: temperature
state_class: measurement
unit_of_measurement: "°C"
accuracy_decimals: 1
lambda: return ((x[7] << 8) + x[6]) * 0.1f;
filters:
- sliding_window_moving_average:
window_size: 30
send_every: 30
- id: temperature_3
name: Temperature 3
device_class: temperature
state_class: measurement
unit_of_measurement: "°C"
accuracy_decimals: 1
lambda: return ((x[9] << 8) + x[8]) * 0.1f;
filters:
- sliding_window_moving_average:
window_size: 30
send_every: 30
- id: pump_speed
name: Pump speed
device_class: power_factor
state_class: measurement
unit_of_measurement: "%"
accuracy_decimals: 0
lambda: return x[16];
filters:
- or:
- throttle: 30s
- delta: 1
- id: heat_quantity
name: Heat quantity
device_class: energy
state_class: total_increasing
unit_of_measurement: "Wh"
accuracy_decimals: 0
lambda: return ((x[23] << 24) + (x[22] << 16) + (x[21] << 8) + x[20]);
filters:
- or:
- throttle: 30s
- delta: 1
- id: software_version
name: Software version
entity_category: diagnostic
accuracy_decimals: 2
lambda: return ((x[25] << 8) + x[24]) * 0.01f;
filters:
- or:
- throttle: 30s
- delta: 0.01
- id: operating_hours
name: Operating hours
device_class: duration
state_class: total_increasing
unit_of_measurement: "h"
accuracy_decimals: 0
lambda: return ((x[31] << 24) + (x[30] << 16) + (x[29] << 8) + x[28]);
filters:
- or:
- throttle: 30s
- delta: 1
- id: error_mask
name: Error mask
entity_category: diagnostic
lambda: return ((x[71] << 24) + (x[70] << 16) + (x[69] << 8) + x[68]);
filters:
- or:
- throttle: 30s
- delta: 1
Update 2023-12-02: The configuration of temperature_1
sensor has been updated
to correctly report negative temperatures. This sensor is in (or on) the panel
itself and so can report negative temperatures when it gets cold outside.