From 338dcccc8d8532a446fa60dc65092b5510c06e3a Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 Apr 2022 11:57:42 +0100 Subject: various improvements --- rx.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 165 insertions(+), 5 deletions(-) (limited to 'rx.c') diff --git a/rx.c b/rx.c index 427dcd3..7f39d6d 100644 --- a/rx.c +++ b/rx.c @@ -6,33 +6,191 @@ #include "sia.h" #include "email.h" +#include "mqtt.h" +#include "util.h" -static void msg (char *account, char *event, char *ascii, int log, const char *email) + +typedef struct thing_struct { + struct thing_struct *next; + char *msg; + unsigned seq; +} Thing; + +static Thing *thing_list = NULL; + +void dump_state (const char *file) +{ + Thing *thing; + FILE *f; + char fn[1024]; + + strcpy (fn, file); + strcat (fn, ".next"); + + f = fopen (fn, "w"); + + if (!f) return; + + for (thing = thing_list; thing; thing = thing->next) { + fprintf (f, "%d ", thing->seq); + fputs (thing->msg, f); + fputc ('\n', f); + } + + fclose (f); + + rename (fn, file); +} + + +static void maintain_state (const char *msg, const char *state_file) +{ + Thing *thing; + + + switch (*msg) { + case '+': + case '-': + break; + + default: + return; + } + + + for (thing = thing_list; thing; thing = thing->next) { + + if (!strcmp (&msg[1], &thing->msg[1])) { + strcpy (thing->msg, msg); + dump_state (state_file); + return; + } + } + + thing = malloc (sizeof (Thing)); + thing->next = thing_list; + thing->msg = strdup (msg); + thing->seq = 1; + + thing_list = thing; + + dump_state (state_file); +} + + + +static void send_mqtt (const char *msg, const char *host) +{ + char value[1024]; + char topic[1024]; + char prefix[] = "stat/alarm/"; + const char *rptr; + char *wptr; + int retain = 0; + + + if (!host) return; + + + switch (*msg) { + case '+': + case '-': + retain = 1; + break; + } + + + + for (rptr = msg, wptr = value; (*rptr) && ((*rptr) != ' '); rptr++, wptr++) + *wptr = *rptr; + + if (!*rptr) return; + + *wptr = 0; + + while (*rptr == ' ') rptr++; + + strcpy (topic, prefix); + + wptr = topic + (sizeof (prefix) - 1); + + if (!*rptr) + strcpy (wptr, value + 1); + + else { + for (; *rptr; rptr++, wptr++) { + if (local_isalnum (*rptr)) + *wptr = *rptr; + + else + *wptr = '_'; + } + + *wptr = 0; + } + + mqtt (host, topic, value, retain); + +#if 0 + /* JMM and an ugly hack */ + + if (!strcmp (topic, "stat/alarm/Rain_Sensor")) { + if (value[0] == '+') + mqtt (host, "cmnd/vent/POWER1", "0", 0); + + else if (value[0] == '-') + mqtt (host, "cmnd/vent/POWER1", "1", 0); + } + +#endif +} + +static void msg (char *account, char *event, char *ascii, int log, const char *email, const char *state_file, const char *mqtt_host) { char body[256]; char subject[256]; + if (state_file) + maintain_state (ascii, state_file); + + if (strstr (ascii, "FULL SET")) + send_mqtt ("+ARMED SYSTEM", mqtt_host); + + else if (strstr (ascii, "UNSET")) + send_mqtt ("-ARMED SYSTEM", mqtt_host); + + else + send_mqtt (ascii, mqtt_host); + snprintf (body, sizeof (body) - 1, "%s %64s %s", account, event, ascii); body[sizeof (body) - 1] = 0; if (log) syslog (LOG_WARNING, "SIA: %s", body); - printf ("%s\n", body); if (!email) return; if (strstr (body, "HEARTBT")) return; + if (strstr (body, "Valid")) return; + + if (strstr (body, "Rejct")) return; + + if (strstr (body, "CUSTOM")) return; + + if (strstr (body, "LOG")) return; + + snprintf (subject, sizeof (subject) - 1, "Galaxy SIA: %s", ascii); send_email (email, subject, body); } -int new_block (int fd, SIA_Block *b, int log, const char *email) +int new_block (int fd, SIA_Block *b, int log, const char *email, const char *state_file, const char *mqtt_host) { static int have_ascii_messages = 0; /*SIA level 3 doesn't have ascii, SIA level 4 does */ @@ -56,7 +214,7 @@ int new_block (int fd, SIA_Block *b, int log, const char *email) memcpy (event, b->data, len); event[len] = 0; - if (!have_ascii_messages) msg (account, event, "", log, email); + if (!have_ascii_messages) msg (account, event, "", log, email, state_file, mqtt_host); break; @@ -65,7 +223,7 @@ int new_block (int fd, SIA_Block *b, int log, const char *email) memcpy (ascii, b->data, len); ascii[len] = 0; - msg (account, event, ascii, log, email); + msg (account, event, ascii, log, email, state_file, mqtt_host); break; } @@ -77,3 +235,5 @@ void periodic_task (void) } + + -- cgit v1.2.3