thermferm/one-wire.c

changeset 693
3518c07737d8
parent 692
6d97eb820cc1
child 694
0f1ef5e6418e
--- a/thermferm/one-wire.c	Sat Apr 20 11:48:20 2024 +0200
+++ b/thermferm/one-wire.c	Mon Apr 22 11:33:04 2024 +0200
@@ -25,6 +25,7 @@
 #include "one-wire.h"
 #include "devices.h"
 #include "delay.h"
+#include "websocket.h"
 #include "futil.h"
 #include "xutil.h"
 
@@ -33,6 +34,8 @@
 
 extern sys_config	Config;
 extern pthread_mutex_t	mutexes[5];
+extern const char	DEVPRESENT[4][6];
+
 
 int			my_one_wire_state = 0;
 int			my_one_wire_shutdown = 0;
@@ -41,6 +44,58 @@
 
 static int one_wire(void);
 
+
+/*
+ * Return json data for one device.
+ */
+char *one_wire_json(w1_list *dev_w1)
+{
+    char        *payload;
+    char        vbuf[64];
+
+    payload = xstrcpy((char *)"{\"address\":\"");
+    payload = xstrcat(payload, dev_w1->address);
+    payload = xstrcat(payload, (char *)"\",\"family\":\"");
+    payload = xstrcat(payload, dev_w1->family);
+    payload = xstrcat(payload, (char *)"\",\"present\":\"");
+    payload = xstrcat(payload, (char *)DEVPRESENT[dev_w1->present]);
+    payload = xstrcat(payload, (char *)"\",\"value\":");
+    snprintf(vbuf, 63, "%d", dev_w1->value);
+    payload = xstrcat(payload, vbuf);
+    payload = xstrcat(payload, (char *)"\",\"timestamp\":");
+    snprintf(vbuf, 63, "%ld", (long)dev_w1->timestamp);
+    payload = xstrcat(payload, vbuf);
+    payload = xstrcat(payload, (char *)"}");
+
+    return payload;
+}
+
+
+void one_wire_ws(void)
+{
+    bool	comma = false;
+    char	*payload = NULL, *payloadu = NULL;
+    w1_list	*dev_w1;
+
+    payload = xstrcpy((char *)"{\"type\":\"onewire\",\"metric\":[");
+    for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
+        if (comma)
+            payload = xstrcat(payload, (char *)",");
+        payloadu = one_wire_json(dev_w1);
+        payload = xstrcat(payload, payloadu);
+        comma = true;
+        free(payloadu);
+        payloadu = NULL;
+    }
+    payload = xstrcat(payload, (char *)"]}");
+    syslog(LOG_NOTICE, "%s", payload);
+    ws_broadcast(payload);
+    free(payload);
+    payload = NULL;
+}
+
+
+
 void *my_one_wire_loop(void *threadid)
 {
     my_one_wire_state = 1;
@@ -69,13 +124,15 @@
     ScanDel,
     Read2413,
     ReadTemp,
-    Missing
+    Missing,
+    Websocket
 SM_NAMES
     (char *)"ScanNew",
     (char *)"ScanDel",
     (char *)"Read2413",
     (char *)"ReadTemp",
-    (char *)"Missing"
+    (char *)"Missing",
+    (char *)"Websocket"
 SM_EDECL
 
     int			found, i, rc, value, conv_time;
@@ -84,6 +141,7 @@
     w1_list		*dev_w1, *n_w1, *cur_w1 = NULL;
     char		buffer[25], w1type[10], *devfile = NULL;
     uint8_t		state, output, newval;
+    bool		changed;
 
 SM_START(ScanNew)
 
@@ -93,6 +151,7 @@
 	SM_SUCCESS;
     }
 
+    changed = false;
     /*
      * Scan for current one-wire devices.
      */
@@ -116,12 +175,13 @@
 	    for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
 		if (strcmp(dev_w1->address, buffer) == 0) {
 		    found = TRUE;
-		    dev_w1->timestamp = time(NULL);
 		    if (dev_w1->present != DEVPRESENT_YES) {
 			syslog(LOG_NOTICE, "One-wire device %s is back", buffer);
 			pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
 			dev_w1->present = DEVPRESENT_YES;
+			dev_w1->timestamp = time(NULL);
 			pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
+			changed = true;
 			for (device = Config.devices; device; device = device->next) {
 			    if (strcmp(dev_w1->address, device->address) == 0) {
 //				pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
@@ -143,6 +203,7 @@
 		n_w1->present = DEVPRESENT_YES;
 		n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1;
 		n_w1->timestamp = time(NULL);
+		changed = true;
 
 		pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
 		if (w1_devices == NULL) {
@@ -185,7 +246,9 @@
 	    syslog(LOG_NOTICE, "One-wire device %s is missing", dev_w1->address);
 	    pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
 	    dev_w1->present = DEVPRESENT_NO;
+	    dev_w1->timestamp = time(NULL);
 	    pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
+	    changed = true;
 	    for (device = Config.devices; device; device = device->next) {
 		if (strcmp(dev_w1->address, device->address) == 0) {
 //		    pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
@@ -239,6 +302,8 @@
 			    if (newval != dev_w1->value) {
 			    	syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d => %d", dev_w1->address, i, state, dev_w1->value, newval);
 			    	dev_w1->value = newval;
+				dev_w1->timestamp = time(NULL);
+				changed = true;
 			    }
 
 //			    pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
@@ -273,6 +338,8 @@
 				if ((write_w1(dev_w1->address, (char *)"output", newval)) == 0) {
 				    syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, newval);
 				    dev_w1->value = newval;
+				    dev_w1->timestamp = time(NULL);
+				    changed = true;
 				}
 			    }
 			}
@@ -335,8 +402,11 @@
 		    mDelay(conv_time);
 		    if ((fgets(buffer, 25, fp))) {
 			sscanf(buffer, "%d", &value);
-//			if (cur_w1->value != value)
+			if (cur_w1->value != value) {
+			    dev_w1->timestamp = time(NULL);
+			    changed = true;
 //			    syslog(LOG_NOTICE, "One-wire device %s temperature read %d => %d", cur_w1->address, cur_w1->value, value);
+			}
 			cur_w1->value = value;		/* devices.c will pick this up */
 		    } else {
 			syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address);
@@ -374,7 +444,19 @@
 	SM_SUCCESS;
     }
 
-    sleep(1);
+    SM_PROCEED(Websocket);
+
+SM_STATE(Websocket)
+
+    for (i = 0; i < 10; i++) {
+	if (my_one_wire_shutdown) {
+	    SM_SUCCESS;
+	}
+
+	mDelay(100);
+	if (changed && i == 5)
+	    one_wire_ws();
+    }
     SM_PROCEED(ScanNew);
 
 SM_END

mercurial