/*
* Boiler System Bus Interface Daemon
*
- * (c) 2020 Martin Mares <mj@ucw.cz>
+ * (c) 2020-2025 Martin Mares <mj@ucw.cz>
*/
#include <ucw/lib.h>
if (len < 4)
return;
- u32 addr = get_u32_be(p);
+ u32 addr = get_u32_be(p); // Two highest-order bytes are swapped
p += 4;
len -= 4;
switch (addr) {
+ case 0x053d0834:
+ // Boiler modulation (format not decoded yet)
+ if (len >= 2) {
+ uint mod = get_u16_be(p);
+ mqtt_publish("burrow/heating/modulation", "%04x %lld", mod, (long long) t);
+ }
+ break;
case 0x313d052f:
// Hot water temperature
if (len >= 3) {
mqtt_publish("burrow/heating/water/temp", "%.2f %lld", temp / 64., (long long) t);
}
break;
+ case 0x113d051a:
+ // Boiler return temperature
+ if (len >= 3) {
+ int temp = get_s16_be(p + 1);
+ mqtt_publish("burrow/heating/return-temp", "%.2f %lld", temp / 64., (long long) t);
+ }
+ break;
}
}
+static u32 query_list[] = {
+ 0x3d31052f, // Hot water temperature
+ 0x3d050834, // Boiler modulation
+ 0x3d31052f, // Hot water temperature (measure more frequently)
+ 0x3d11051a, // Boiler return temperature
+};
+
static void process_frame(time_t t, byte *pkt, uint len)
{
if (!len) {
static struct opt_section options = {
OPT_ITEMS {
- OPT_HELP("A daemon for controlling the air conditioning controller via MQTT"),
+ OPT_HELP("A daemon for gathering BSB data and sending it to MQTT"),
OPT_HELP(""),
OPT_HELP("Options:"),
OPT_BOOL('d', "debug", use_debug, 0, "\tLog debugging messages"),
last_stats = now;
}
- if (last_query + 30 < now) {
+ if (last_query + 20 < now) {
+ static uint next_query_index;
+ u32 reg = query_list[next_query_index];
+ next_query_index = (next_query_index + 1) % ARRAY_SIZE(query_list);
byte pkt[] = {
0xdc, // start of frame
0x00, // source address (filled by firmware)
BSB_ADDR_BOILER, // destination address
0x0b, // length
BSB_OP_QUERY, // operation
- 0x3d, 0x31, 0x05, 0x2f, // address: hot water temperature (first 2 bytes swapped!)
+ 0x00, 0x00, 0x00, 0x00, // register address (filled below)
0x00, 0x00, // CRC (filled by firmware)
};
+ put_u32_be(pkt + 5, reg);
if (err = libusb_bulk_transfer(devh, 0x01, pkt, sizeof(pkt), &received, 2000)) {
usb_error("Send failed: error %d", err);
continue;