]> mj.ucw.cz Git - home-hw.git/blobdiff - bsb/daemon/burrow-bsbd.c
burrow-bsbd: Removed surplus newline
[home-hw.git] / bsb / daemon / burrow-bsbd.c
index 6b83a5fa03754341caef4d5ab4ec0b6cd0913539..ca9e66d8102b3d00f92a8aa6d827dbcdff2719ac 100644 (file)
@@ -49,12 +49,28 @@ static void mqtt_publish(const char *topic, const char *fmt, ...)
        va_end(args);
 }
 
+static void mqtt_publish_ephemeral(const char *topic, const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+
+       if (mqtt_connected) {
+               char m[256];
+               int l = vsnprintf(m, sizeof(m), fmt, args);
+               int err = mosquitto_publish(mosq, NULL, topic, l, m, 0, false);
+               if (err != MOSQ_ERR_SUCCESS)
+                       msg(L_ERROR, "Mosquitto: Publish failed, error=%d", err);
+       }
+
+       va_end(args);
+}
+
 static void mqtt_conn_callback(struct mosquitto *mosq UNUSED, void *obj UNUSED, int status)
 {
        if (!status) {
                msg(L_DEBUG, "MQTT: Connection established");
-               mqtt_publish("status/bsb", "ok");
                mqtt_connected = true;
+               mqtt_publish("status/bsb", "ok");
        } else if (mqtt_connected) {
                msg(L_DEBUG, "MQTT: Connection lost");
                mqtt_connected = false;
@@ -97,7 +113,6 @@ static void usb_error(const char *msg, ...)
        va_list args;
        va_start(args, msg);
        ucw_vmsg(L_ERROR, msg, args);
-       fputc('\n', stderr);
        va_end(args);
 
        if (devh) {
@@ -158,16 +173,25 @@ static const char * const stat_names[] = {
 #undef P
 };
 
+static int get_s16_be(const byte *x)
+{
+       int val = get_u16_be(x);
+       if (val >= 0x8000)
+               return val - 0x10000;
+       else
+               return val;
+}
+
 static void process_stats(time_t t, byte *resp, uint len)
 {
        for (uint i=0; i < ARRAY_SIZE(stat_names) && 4*i + 3 < (uint) len; i++) {
                char item[64];
-               snprintf(item, sizeof(item), "burrow/bsb/stats/%s", stat_names[i]);
-               mqtt_publish(item, "%u", (uint) get_u32_le(resp+4*i), t);
+               snprintf(item, sizeof(item), "bsb/stats/%s", stat_names[i]);
+               mqtt_publish(item, "%u %lld", (uint) get_u32_le(resp+4*i), (long long) t);
        }
 }
 
-static void process_info(byte *p, uint len)
+static void process_info(time_t t, byte *p, uint len)
 {
        if (len < 4)
                return;
@@ -177,46 +201,79 @@ static void process_info(byte *p, uint len)
        len -= 4;
 
        switch (addr) {
+               case 0x0500006b:
+                       if (len >= 2) {
+                               int err = get_u16_be(p);
+                               mqtt_publish("burrow/heating/error", "%d %lld", err, (long long) t);
+                       }
+                       break;
+               case 0x0500006c:
+                       if (len >= 7) {
+                               mqtt_publish("burrow/heating/clock", "%04d-%02d-%02dT%02d:%02d %lld",
+                                       get_u16_be(p) + 1900, p[2], p[3],
+                                       p[5], p[6],
+                                       (long long) t);
+                       }
+                       break;
                case 0x05000219:
                        if (len >= 4) {
-                               uint temp = get_u16_be(p);
+                               int temp = get_s16_be(p);
                                uint press = get_u16_be(p + 2);
-                               mqtt_publish("burrow/heating/outside-temp", "%.2f", temp / 64.);
-                               mqtt_publish("burrow/heating/water-pressure", "%.1f", press / 10.);
+                               mqtt_publish("burrow/heating/outside-temp", "%.2f %lld", temp / 64., (long long) t);
+                               mqtt_publish("burrow/heating/water-pressure", "%.1f %lld", press / 10., (long long) t);
                        }
                        break;
                case 0x05000229:
                        // AGU.2 status
                        if (len >= 2) {
-                               uint temp = get_u16_be(p);
-                               mqtt_publish("burrow/heating/circuit1/mix-temp", "%.2f", temp / 64.);
+                               int temp = get_s16_be(p);
+                               mqtt_publish("burrow/heating/circuit1/mix-temp", "%.2f %lld", temp / 64., (long long) t);
                        }
                        break;
                case 0x05040227:
                        // AGU.2 control
-                       if (len >= 2) {
+                       if (len >= 4) {
                                uint m = get_u16_be(p);
-                               mqtt_publish("burrow/heating/circuit1/mix-valve", "%u", m);
+                               mqtt_publish("burrow/heating/circuit1/mix-valve", "%u %lld", m, (long long) t);
+                               mqtt_publish("burrow/heating/circuit1/pump", "%u %lld", (p[3] == 3), (long long) t);
+                       }
+                       break;
+               case 0x2d000211:
+                       // Circuit 1 status
+                       if (len >= 10) {
+                               mqtt_publish("burrow/heating/circuit1/active", "%u %lld", (p[8] != 0), (long long) t);
+                       }
+                       break;
+               case 0x2e000211:
+                       // Circuit 2 status
+                       if (len >= 10) {
+                               mqtt_publish("burrow/heating/circuit2/active", "%u %lld", (p[8] != 0), (long long) t);
+                       }
+                       break;
+               case 0x31000212:
+                       // Hot water status
+                       if (len >= 3) {
+                               mqtt_publish("burrow/heating/water/active", "%u %lld", (p[1] != 0), (long long) t);
                        }
                        break;
                case 0x3d2d0215:
                        // Room 1 status
                        if (len >= 2) {
-                               uint temp = get_u16_be(p);
-                               mqtt_publish("burrow/heating/circuit1/room-temp", "%.2f", temp / 64.);
+                               int temp = get_s16_be(p);
+                               mqtt_publish("burrow/heating/circuit1/room-temp", "%.2f %lld", temp / 64., (long long) t);
                        }
                        break;
                case 0x3e2e0215:
                        // Room 2 status
                        if (len >= 2) {
-                               uint temp = get_u16_be(p);
-                               mqtt_publish("burrow/heating/circuit2/room-temp", "%.2f", temp / 64.);
+                               int temp = get_s16_be(p);
+                               mqtt_publish("burrow/heating/circuit2/room-temp", "%.2f %lld", temp / 64., (long long) t);
                        }
                        break;
        }
 }
 
-static void process_answer(byte *p, uint len)
+static void process_answer(time_t t, byte *p, uint len)
 {
        if (len < 4)
                return;
@@ -251,19 +308,19 @@ static void process_frame(time_t t, byte *pkt, uint len)
 
        char hex[3*len + 1];
        mem_to_hex(hex, pkt, len, ' ');
-       mqtt_publish("bsb/frame", "%s", hex, t);
+       mqtt_publish_ephemeral("bsb/frame", "%s", hex, t);
 
        msg(L_DEBUG, "<< %s", hex);
 
-       byte *params = pkt + BF_PARAMS;
-       uint param_len = len - BF_PARAMS - 2;   // 2 for CRC
+       byte *body = pkt + BF_BODY;
+       uint body_len = len - BF_BODY - 2;      // 2 for CRC
 
        switch (pkt[BF_OP]) {
                case BSB_OP_INFO:
-                       process_info(params, param_len);
+                       process_info(t, body, body_len);
                        break;
                case BSB_OP_ANSWER:
-                       process_answer(params, param_len);
+                       process_answer(t, body, body_len);
                        break;
        }
 }