From c3e19bb69671e35db6cd44953ee71741f04bfdab Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 11 Aug 2018 15:14:58 +0200 Subject: [PATCH] SSR: Rudiments of MQTT <-> SSR gateway --- ssr/turris/Makefile | 7 +- ssr/turris/burrow-ssrd.c | 143 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 ssr/turris/burrow-ssrd.c diff --git a/ssr/turris/Makefile b/ssr/turris/Makefile index dd71f4a..35bccce 100644 --- a/ssr/turris/Makefile +++ b/ssr/turris/Makefile @@ -13,13 +13,14 @@ export PATH=$(TARGET_PATH_PKG) CC=$(TARGET_CC_NOCACHE) LD=$(TARGET_LD_NOCACHE) CFLAGS=$(TARGET_CFLAGS) $(USB_CFLAGS) $(UCW_CFLAGS) -std=gnu99 -LDFLAGS=$(TARGET_LDFLAGS) $(USB_LDFLAGS) $(UCW_LDFLAGS) +LDFLAGS=$(TARGET_LDFLAGS) $(USB_LDFLAGS) $(UCW_LDFLAGS) -lmosquitto -all: ssr-control upload +all: ssr-control burrow-ssrd upload ssr-control: ssr-control.c +burrow-ssrd: burrow-ssrd.c upload: - rsync -av ssr-control micac: + rsync -av ssr-control burrow-ssrd micac: .PHONY: upload diff --git a/ssr/turris/burrow-ssrd.c b/ssr/turris/burrow-ssrd.c new file mode 100644 index 0000000..6d15e36 --- /dev/null +++ b/ssr/turris/burrow-ssrd.c @@ -0,0 +1,143 @@ +/* + * A Control Daemon for the Solid State Relay module + * + * (c) 2018 Martin Mares + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +struct libusb_context *usb_ctxt; +struct libusb_device_handle *devh; + +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= 4) { + uint status = get_u32_be(resp); + if (status) + die("Received error status %08x", status); + } + + return received; +} + +static struct opt_section options = { + OPT_ITEMS { + OPT_HELP("A daemon for controlling the solid state relay module"), + OPT_HELP(""), + OPT_HELP("Options:"), + OPT_HELP_OPTION, + OPT_CONF_OPTIONS, + OPT_END + } +}; + +int main(int argc UNUSED, char **argv) +{ + opt_parse(&options, argv+1); + + int err; + if (err = libusb_init(&usb_ctxt)) + die("Cannot initialize libusb: error %d", err); + libusb_set_debug(usb_ctxt, 3); + open_device(); + + mosquitto_lib_init(); + struct mosquitto *mosq = mosquitto_new("ssrd", 1, NULL); + if (!mosq) + die("Mosquitto: initialization failed"); + + if (mosquitto_will_set(mosq, "burrow/loft/status", 4, "dead", 0, true) != MOSQ_ERR_SUCCESS) + die("Mosquitto: unable to set will"); + + if (mosquitto_connect(mosq, "127.0.0.1", 1883, 60) != MOSQ_ERR_SUCCESS) + die("Mosquitto: connect failed"); + + if (mosquitto_publish(mosq, NULL, "burrow/loft/status", 2, "ok", 0, true) != MOSQ_ERR_SUCCESS) + msg(L_ERROR, "Mosquitto: publish failed"); + + time_t next_run = 0; + for (;;) { + time_t now = time(NULL); + if (now < next_run) { + int err = mosquitto_loop(mosq, (next_run - now) * 1000, 1); + if (err != MOSQ_ERR_SUCCESS) + msg(L_ERROR, "Mosquitto: loop returned error %d", err); + continue; + } + + next_run = now + 5; + + put_u32_be(req, 2); + transaction(8, 8); + int t = get_u32_be(resp+4); + msg(L_DEBUG, "Measured raw temperature %d", t); + + byte mbuf[16]; + int mlen = snprintf(mbuf, sizeof(mbuf), "%.3f", t / 1000.); + if (mosquitto_publish(mosq, NULL, "burrow/loft/temperature", mlen, mbuf, 0, true) != MOSQ_ERR_SUCCESS) + msg(L_ERROR, "Mosquitto: publish failed"); + + byte tbuf[16]; + int tlen = snprintf(tbuf, sizeof(tbuf), "%u", (int) now); + if (mosquitto_publish(mosq, NULL, "burrow/loft/timestamp", tlen, tbuf, 0, true) != MOSQ_ERR_SUCCESS) + msg(L_ERROR, "Mosquitto: publish failed"); + } +} -- 2.39.2