]> mj.ucw.cz Git - home-hw.git/commitdiff
BSB: Proper daemon name
authorMartin Mares <mj@ucw.cz>
Fri, 28 Feb 2020 15:47:34 +0000 (16:47 +0100)
committerMartin Mares <mj@ucw.cz>
Fri, 28 Feb 2020 15:47:34 +0000 (16:47 +0100)
bsb/daemon/Makefile
bsb/daemon/burrow-bsb.c [deleted file]
bsb/daemon/burrow-bsbd.c [new file with mode: 0644]

index 9f2ce2bcefa8816a44aca8951e8b84a60c520c58..b602b510a56eabb740e48371564f41c6bafc66d8 100644 (file)
@@ -27,7 +27,10 @@ UCW_LDFLAGS := $(shell $(PC) --libs libucw)
 CFLAGS=$(USB_CFLAGS) $(UCW_CFLAGS) -std=gnu1x -O2 -Wall -Wextra -Wno-parentheses
 LDFLAGS=$(USB_LDFLAGS) $(UCW_LDFLAGS) -lmosquitto
 
-all: burrow-bsb bsb-monitor
+all: burrow-bsbd bsb-monitor
 
-# burrow-bsb: burrow-bsb.c ../firmware/interface.h
+# burrow-bsbd: burrow-bsbd.c ../firmware/interface.h
 # bsb-monitor: bsb-monitor.c ../firmware/interface.h
+
+upload:
+       rsync -av burrow-bsbd bsb-monitor micac:/root/burrow/
diff --git a/bsb/daemon/burrow-bsb.c b/bsb/daemon/burrow-bsb.c
deleted file mode 100644 (file)
index 6b83a5f..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- *     Boiler System Bus Interface Daemon
- *
- *     (c) 2020 Martin Mares <mj@ucw.cz>
- */
-
-#include <ucw/lib.h>
-#include <ucw/log.h>
-#include <ucw/opt.h>
-#include <ucw/string.h>
-#include <ucw/unaligned.h>
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <libusb.h>
-#include <mosquitto.h>
-
-typedef unsigned char byte;
-typedef uint32_t u32;
-typedef unsigned int uint;
-
-#include "../firmware/interface.h"
-
-/*** MQTT ***/
-
-static struct mosquitto *mosq;
-static bool mqtt_connected;
-
-static void mqtt_publish(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, true);
-               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;
-       } else if (mqtt_connected) {
-               msg(L_DEBUG, "MQTT: Connection lost");
-               mqtt_connected = false;
-       }
-}
-
-static void mqtt_log_callback(struct mosquitto *mosq UNUSED, void *obj UNUSED, int level, const char *message)
-{
-       msg(L_DEBUG, "MQTT(%d): %s", level, message);
-}
-
-static void mqtt_init(void)
-{
-       mosquitto_lib_init();
-
-       mosq = mosquitto_new("bsbd", 1, NULL);
-       if (!mosq)
-               die("Mosquitto: Initialization failed");
-
-       mosquitto_connect_callback_set(mosq, mqtt_conn_callback);
-       mosquitto_log_callback_set(mosq, mqtt_log_callback);
-
-       if (mosquitto_will_set(mosq, "status/bsb", 4, "dead", 0, true) != MOSQ_ERR_SUCCESS)
-               die("Mosquitto: Unable to set will");
-
-       if (mosquitto_connect_async(mosq, "127.0.0.1", 1883, 60) != MOSQ_ERR_SUCCESS)
-               die("Mosquitto: Unable to connect");
-
-       if (mosquitto_loop_start(mosq))
-               die("Mosquitto: Cannot start service thread");
-}
-
-/*** USB ***/
-
-static struct libusb_context *usb_ctxt;
-static struct libusb_device_handle *devh;
-
-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) {
-               libusb_close(devh);
-               devh = NULL;
-       }
-}
-
-static void open_device(void)
-{
-       int err;
-       libusb_device **devlist;
-       ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist);
-       if (devn < 0)
-               die("Cannot enumerate USB devices: error %d", (int) devn);
-
-       for (ssize_t i=0; i<devn; i++) {
-               struct libusb_device_descriptor desc;
-               libusb_device *dev = devlist[i];
-               if (!libusb_get_device_descriptor(dev, &desc)) {
-                       if (desc.idVendor == BSB_USB_VENDOR && desc.idProduct == BSB_USB_PRODUCT) {
-                               msg(L_INFO, "Found device at usb%d.%d", libusb_get_bus_number(dev), libusb_get_device_address(dev));
-
-                               if (err = libusb_open(dev, &devh)) {
-                                       usb_error("Cannot open device: error %d", err);
-                                       goto out;
-                               }
-                               libusb_reset_device(devh);
-                               if (err = libusb_claim_interface(devh, 0)) {
-                                       usb_error("Cannot claim interface: error %d", err);
-                                       goto out;
-                               }
-
-                               goto out;
-                       }
-               }
-       }
-
-out:
-       libusb_free_device_list(devlist, 1);
-}
-
-static void init_usb(void)
-{
-       int err;
-       if (err = libusb_init(&usb_ctxt))
-               die("Cannot initialize libusb: error %d", err);
-       // libusb_set_debug(usb_ctxt, 3);
-       open_device();
-
-}
-
-/*** Protocol ***/
-
-static const char * const stat_names[] = {
-#define P(x) #x,
-       BSB_STATS
-#undef P
-};
-
-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);
-       }
-}
-
-static void process_info(byte *p, uint len)
-{
-       if (len < 4)
-               return;
-
-       u32 addr = get_u32_be(p);
-       p += 4;
-       len -= 4;
-
-       switch (addr) {
-               case 0x05000219:
-                       if (len >= 4) {
-                               uint temp = get_u16_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.);
-                       }
-                       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.);
-                       }
-                       break;
-               case 0x05040227:
-                       // AGU.2 control
-                       if (len >= 2) {
-                               uint m = get_u16_be(p);
-                               mqtt_publish("burrow/heating/circuit1/mix-valve", "%u", m);
-                       }
-                       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.);
-                       }
-                       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.);
-                       }
-                       break;
-       }
-}
-
-static void process_answer(byte *p, uint len)
-{
-       if (len < 4)
-               return;
-
-       u32 addr = get_u32_be(p);
-       p += 4;
-       len -= 4;
-
-       switch (addr) {
-       }
-}
-
-static void process_frame(time_t t, byte *pkt, uint len)
-{
-       if (!len) {
-               msg(L_ERROR, "Received empty frame");
-               return;
-       }
-
-       byte status = *pkt++;
-       len--;
-
-       if (!len) {
-               msg(L_ERROR, "Frame transmit status: %u", status);
-               return;
-       }
-
-       if (len < 6) {
-               msg(L_ERROR, "Received truncated frame");
-               return;
-       }
-
-       char hex[3*len + 1];
-       mem_to_hex(hex, pkt, len, ' ');
-       mqtt_publish("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
-
-       switch (pkt[BF_OP]) {
-               case BSB_OP_INFO:
-                       process_info(params, param_len);
-                       break;
-               case BSB_OP_ANSWER:
-                       process_answer(params, param_len);
-                       break;
-       }
-}
-
-static int use_daemon;
-static int use_debug;
-
-static struct opt_section options = {
-       OPT_ITEMS {
-               OPT_HELP("A daemon for controlling the air conditioning controller via MQTT"),
-               OPT_HELP(""),
-               OPT_HELP("Options:"),
-               OPT_BOOL('d', "debug", use_debug, 0, "\tLog debugging messages"),
-               OPT_BOOL(0, "daemon", use_daemon, 0, "\tDaemonize"),
-               OPT_HELP_OPTION,
-               OPT_CONF_OPTIONS,
-               OPT_END
-       }
-};
-
-int main(int argc UNUSED, char **argv)
-{
-       log_init(argv[0]);
-       opt_parse(&options, argv+1);
-
-       if (use_daemon) {
-               struct log_stream *ls = log_new_syslog("daemon", LOG_PID);
-               log_set_default_stream(ls);
-       }
-       if (!use_debug)
-               log_default_stream()->levels &= ~(1U << L_DEBUG);
-
-       mqtt_init();
-       init_usb();
-
-       time_t now = time(NULL);
-       time_t last_stats = 0;
-       // time_t last_query = now;
-       int err, received;
-       byte resp[64];
-
-       for (;;) {
-               if (!devh) {
-                       msg(L_INFO, "Waiting for device to appear...");
-                       while (!devh) {
-                               sleep(5);
-                               open_device();
-                       }
-               }
-
-               now = time(NULL);
-               if (last_stats + 60 < now) {
-                       if ((received = libusb_control_transfer(devh, 0xc0, 0x00, 0, 0, resp, sizeof(resp), 1000)) < 0) {
-                               usb_error("Receive failed: error %d", received);
-                               continue;
-                       }
-
-                       process_stats(now, resp, received);
-                       last_stats = now;
-               }
-
-#if 0
-               if (last_query + 10 < now) {
-                       byte pkt[] = { 0xdc, 0xc2, 0x00, 0x0b, 0x06, 0x3d, 0x2e, 0x11, 0x25, 0x00, 0x00 };
-                       if (err = libusb_bulk_transfer(devh, 0x01, pkt, sizeof(pkt), &received, 2000)) {
-                               usb_error("Send failed: error %d", err);
-                               continue;
-                       } else {
-                               // msg(L_DEBUG"Send OK: %d bytes", received);
-                       }
-                       last_query = now;
-               }
-#endif
-
-               if (err = libusb_interrupt_transfer(devh, 0x82, resp, 64, &received, 1000)) {
-                       if (err != LIBUSB_ERROR_TIMEOUT)
-                               usb_error("Receive failed: error %d", err);
-                       continue;
-               }
-
-               process_frame(now, resp, received);
-       }
-}
diff --git a/bsb/daemon/burrow-bsbd.c b/bsb/daemon/burrow-bsbd.c
new file mode 100644 (file)
index 0000000..6b83a5f
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ *     Boiler System Bus Interface Daemon
+ *
+ *     (c) 2020 Martin Mares <mj@ucw.cz>
+ */
+
+#include <ucw/lib.h>
+#include <ucw/log.h>
+#include <ucw/opt.h>
+#include <ucw/string.h>
+#include <ucw/unaligned.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <libusb.h>
+#include <mosquitto.h>
+
+typedef unsigned char byte;
+typedef uint32_t u32;
+typedef unsigned int uint;
+
+#include "../firmware/interface.h"
+
+/*** MQTT ***/
+
+static struct mosquitto *mosq;
+static bool mqtt_connected;
+
+static void mqtt_publish(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, true);
+               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;
+       } else if (mqtt_connected) {
+               msg(L_DEBUG, "MQTT: Connection lost");
+               mqtt_connected = false;
+       }
+}
+
+static void mqtt_log_callback(struct mosquitto *mosq UNUSED, void *obj UNUSED, int level, const char *message)
+{
+       msg(L_DEBUG, "MQTT(%d): %s", level, message);
+}
+
+static void mqtt_init(void)
+{
+       mosquitto_lib_init();
+
+       mosq = mosquitto_new("bsbd", 1, NULL);
+       if (!mosq)
+               die("Mosquitto: Initialization failed");
+
+       mosquitto_connect_callback_set(mosq, mqtt_conn_callback);
+       mosquitto_log_callback_set(mosq, mqtt_log_callback);
+
+       if (mosquitto_will_set(mosq, "status/bsb", 4, "dead", 0, true) != MOSQ_ERR_SUCCESS)
+               die("Mosquitto: Unable to set will");
+
+       if (mosquitto_connect_async(mosq, "127.0.0.1", 1883, 60) != MOSQ_ERR_SUCCESS)
+               die("Mosquitto: Unable to connect");
+
+       if (mosquitto_loop_start(mosq))
+               die("Mosquitto: Cannot start service thread");
+}
+
+/*** USB ***/
+
+static struct libusb_context *usb_ctxt;
+static struct libusb_device_handle *devh;
+
+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) {
+               libusb_close(devh);
+               devh = NULL;
+       }
+}
+
+static void open_device(void)
+{
+       int err;
+       libusb_device **devlist;
+       ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist);
+       if (devn < 0)
+               die("Cannot enumerate USB devices: error %d", (int) devn);
+
+       for (ssize_t i=0; i<devn; i++) {
+               struct libusb_device_descriptor desc;
+               libusb_device *dev = devlist[i];
+               if (!libusb_get_device_descriptor(dev, &desc)) {
+                       if (desc.idVendor == BSB_USB_VENDOR && desc.idProduct == BSB_USB_PRODUCT) {
+                               msg(L_INFO, "Found device at usb%d.%d", libusb_get_bus_number(dev), libusb_get_device_address(dev));
+
+                               if (err = libusb_open(dev, &devh)) {
+                                       usb_error("Cannot open device: error %d", err);
+                                       goto out;
+                               }
+                               libusb_reset_device(devh);
+                               if (err = libusb_claim_interface(devh, 0)) {
+                                       usb_error("Cannot claim interface: error %d", err);
+                                       goto out;
+                               }
+
+                               goto out;
+                       }
+               }
+       }
+
+out:
+       libusb_free_device_list(devlist, 1);
+}
+
+static void init_usb(void)
+{
+       int err;
+       if (err = libusb_init(&usb_ctxt))
+               die("Cannot initialize libusb: error %d", err);
+       // libusb_set_debug(usb_ctxt, 3);
+       open_device();
+
+}
+
+/*** Protocol ***/
+
+static const char * const stat_names[] = {
+#define P(x) #x,
+       BSB_STATS
+#undef P
+};
+
+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);
+       }
+}
+
+static void process_info(byte *p, uint len)
+{
+       if (len < 4)
+               return;
+
+       u32 addr = get_u32_be(p);
+       p += 4;
+       len -= 4;
+
+       switch (addr) {
+               case 0x05000219:
+                       if (len >= 4) {
+                               uint temp = get_u16_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.);
+                       }
+                       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.);
+                       }
+                       break;
+               case 0x05040227:
+                       // AGU.2 control
+                       if (len >= 2) {
+                               uint m = get_u16_be(p);
+                               mqtt_publish("burrow/heating/circuit1/mix-valve", "%u", m);
+                       }
+                       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.);
+                       }
+                       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.);
+                       }
+                       break;
+       }
+}
+
+static void process_answer(byte *p, uint len)
+{
+       if (len < 4)
+               return;
+
+       u32 addr = get_u32_be(p);
+       p += 4;
+       len -= 4;
+
+       switch (addr) {
+       }
+}
+
+static void process_frame(time_t t, byte *pkt, uint len)
+{
+       if (!len) {
+               msg(L_ERROR, "Received empty frame");
+               return;
+       }
+
+       byte status = *pkt++;
+       len--;
+
+       if (!len) {
+               msg(L_ERROR, "Frame transmit status: %u", status);
+               return;
+       }
+
+       if (len < 6) {
+               msg(L_ERROR, "Received truncated frame");
+               return;
+       }
+
+       char hex[3*len + 1];
+       mem_to_hex(hex, pkt, len, ' ');
+       mqtt_publish("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
+
+       switch (pkt[BF_OP]) {
+               case BSB_OP_INFO:
+                       process_info(params, param_len);
+                       break;
+               case BSB_OP_ANSWER:
+                       process_answer(params, param_len);
+                       break;
+       }
+}
+
+static int use_daemon;
+static int use_debug;
+
+static struct opt_section options = {
+       OPT_ITEMS {
+               OPT_HELP("A daemon for controlling the air conditioning controller via MQTT"),
+               OPT_HELP(""),
+               OPT_HELP("Options:"),
+               OPT_BOOL('d', "debug", use_debug, 0, "\tLog debugging messages"),
+               OPT_BOOL(0, "daemon", use_daemon, 0, "\tDaemonize"),
+               OPT_HELP_OPTION,
+               OPT_CONF_OPTIONS,
+               OPT_END
+       }
+};
+
+int main(int argc UNUSED, char **argv)
+{
+       log_init(argv[0]);
+       opt_parse(&options, argv+1);
+
+       if (use_daemon) {
+               struct log_stream *ls = log_new_syslog("daemon", LOG_PID);
+               log_set_default_stream(ls);
+       }
+       if (!use_debug)
+               log_default_stream()->levels &= ~(1U << L_DEBUG);
+
+       mqtt_init();
+       init_usb();
+
+       time_t now = time(NULL);
+       time_t last_stats = 0;
+       // time_t last_query = now;
+       int err, received;
+       byte resp[64];
+
+       for (;;) {
+               if (!devh) {
+                       msg(L_INFO, "Waiting for device to appear...");
+                       while (!devh) {
+                               sleep(5);
+                               open_device();
+                       }
+               }
+
+               now = time(NULL);
+               if (last_stats + 60 < now) {
+                       if ((received = libusb_control_transfer(devh, 0xc0, 0x00, 0, 0, resp, sizeof(resp), 1000)) < 0) {
+                               usb_error("Receive failed: error %d", received);
+                               continue;
+                       }
+
+                       process_stats(now, resp, received);
+                       last_stats = now;
+               }
+
+#if 0
+               if (last_query + 10 < now) {
+                       byte pkt[] = { 0xdc, 0xc2, 0x00, 0x0b, 0x06, 0x3d, 0x2e, 0x11, 0x25, 0x00, 0x00 };
+                       if (err = libusb_bulk_transfer(devh, 0x01, pkt, sizeof(pkt), &received, 2000)) {
+                               usb_error("Send failed: error %d", err);
+                               continue;
+                       } else {
+                               // msg(L_DEBUG"Send OK: %d bytes", received);
+                       }
+                       last_query = now;
+               }
+#endif
+
+               if (err = libusb_interrupt_transfer(devh, 0x82, resp, 64, &received, 1000)) {
+                       if (err != LIBUSB_ERROR_TIMEOUT)
+                               usb_error("Receive failed: error %d", err);
+                       continue;
+               }
+
+               process_frame(now, resp, received);
+       }
+}