thermferm/websocket.c

changeset 678
cc49115e769e
parent 676
09b5efe0c633
child 680
8b3c86124a08
--- a/thermferm/websocket.c	Sun Apr 14 14:41:38 2024 +0200
+++ b/thermferm/websocket.c	Mon Apr 15 17:04:57 2024 +0200
@@ -26,12 +26,17 @@
 
 #include "thermferm.h"
 #include "xutil.h"
+#include "devices.h"
 #include "websocket.h"
 #include <libwebsockets.h>
 
 
 extern sys_config       Config;
 extern int		debug;
+extern const char	UNITMODE[5][8];
+extern const char	UNITSTAGE[4][12];
+//extern const char       PROFSTATE[5][6];
+//extern const char       TEMPSTATE[3][8];
 
 int			my_ws_shutdown = 0;
 int			my_ws_state = 0;
@@ -63,6 +68,157 @@
 
 
 
+void fermenter_ws_receive(char *buf)
+{
+    struct json_object	*val, *val2, *jobj;
+    units_list		*unit;
+    bool		changed;
+
+    jobj = json_tokener_parse(buf);
+    json_object_object_get_ex(jobj, "unit", &val);
+
+    for (unit = Config.units ; unit; unit = unit->next) {
+	if (strcmp((char *)json_object_get_string(val), unit->alias) == 0) {
+	    /*
+	     * Setpoints
+	     * {"type":"fermenter","unit":"unit0","setpoint_low":20.3,"setpoint_high":20.7}
+	     */
+	    if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) {
+		changed = false;
+		if (json_object_object_get_ex(jobj, "setpoint_low", &val)) {
+		    if (unit->PID_heat->SetP != json_object_get_double(val)) {
+			changed = true;
+		    	syslog(LOG_NOTICE, "ws: unit %s setpoint low from %.1f to %.1f", unit->alias, unit->PID_heat->SetP, json_object_get_double(val));
+		    	unit->PID_heat->SetP = json_object_get_double(val);
+		    }
+		}
+		if (json_object_object_get_ex(jobj, "setpoint_high", &val)) {
+		    if (unit->PID_cool->SetP != json_object_get_double(val)) {
+			changed = true;
+		    	syslog(LOG_NOTICE, "ws: unit %s setpoint high from %.1f to %.1f", unit->alias, unit->PID_cool->SetP, json_object_get_double(val));
+		    	unit->PID_cool->SetP = json_object_get_double(val);
+		    }
+		}
+		if (changed) {
+		    if (unit->mode == UNITMODE_FRIDGE) {
+		    	unit->fridge_set_lo = unit->PID_heat->SetP;
+		    	unit->fridge_set_hi = unit->PID_cool->SetP;
+                    } else {
+		    	unit->beer_set_lo = unit->PID_heat->SetP;
+		    	unit->beer_set_hi = unit->PID_cool->SetP;
+                    }
+		    unit->mqtt_flag |= MQTT_FLAG_DATA;
+		    break;
+		}
+	    }
+
+	    /*
+	     * Unit mode
+	     * {"type":"fermenter","unit":"unit0","mode":"NONE"}
+	     */
+	    if (json_object_object_get_ex(jobj, "mode", &val)) {
+		for (int i = 0; i < 5; i++) {
+		    if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) {
+			if (unit->mode != i) {
+			    unit->mqtt_flag |= MQTT_FLAG_DATA;
+			    /* Initialize log if the unit is turned on */
+			    if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) {
+				unit->mqtt_flag |= MQTT_FLAG_BIRTH;
+			    }
+			    if (i == UNITMODE_PROFILE) {
+				/* Do some checks and refuse profile mode cannot be set */
+				if (unit->profile_uuid == NULL) {
+				    syslog(LOG_NOTICE, "ws: unit %s refuse mode profile, not loaded", unit->alias);
+				    break;
+				}
+			    }
+			    syslog(LOG_NOTICE, "ws: unit %s mode to %s", unit->alias, UNITMODE[i]);
+			    unit->mode = i;
+			    if ((unit->mode != UNITMODE_OFF) && ! unit->event_msg)
+				unit->event_msg = xstrcpy((char *)UNITMODE[i]);
+			    /* Allways turn everything off after a mode change */
+			    unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0;
+			    unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE;
+			    unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = unit->light_timer = 0;
+			    unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
+			    device_out(unit->heater_address, unit->heater_state);
+			    device_out(unit->cooler_address, unit->cooler_state);
+			    device_out(unit->fan_address, unit->fan_state);
+			    device_out(unit->light_address, unit->light_state);
+			    if (unit->mode == UNITMODE_PROFILE) {
+				/*
+				 * Set a sane default until it will be overruled by the
+				 * main processing loop.
+				 */
+				unit->prof_target_lo = unit->profile_inittemp_lo;
+				unit->prof_target_hi = unit->profile_inittemp_hi;;
+				unit->prof_fridge_mode = 0;
+				unit->prof_state = PROFILE_OFF;
+				unit->prof_started = unit->prof_paused = unit->prof_primary_done = 0;
+				unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
+			    }
+			}
+			break;
+		    }
+		}
+	    }
+
+	    /*
+	     * Unit stage
+	     * {"type":"fermenter","unit":"unit0","stage":"SECONDARY"}
+	     */
+	    if (json_object_object_get_ex(jobj, "stage", &val)) {
+		for (int i = 0; i < 4; i++) {
+		    if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) {
+			if (unit->stage != i) {
+			    syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", unit->alias, UNITSTAGE[i]);
+			    unit->mqtt_flag |= MQTT_FLAG_DATA;
+			    unit->stage = i;
+			    if ((unit->mode != UNITMODE_OFF) && ! unit->event_msg)
+				unit->event_msg = xstrcpy((char *)UNITSTAGE[i]);
+			}
+			break;
+		    }
+		}
+	    }
+
+	    /*
+	     * Unit heater and cooler switch
+	     * {"type":"fermenter","unit":"unit0","heater_state":100,"cooler_state":0}
+	     */
+	    if ((json_object_object_get_ex(jobj, "heater_state", &val)) &&
+		(json_object_object_get_ex(jobj, "cooler_state", &val2)) &&
+		(unit->mode == UNITMODE_NONE)) {
+		if (json_object_get_int(val) != unit->heater_state)
+		    unit->heater_state = json_object_get_int(val);
+		if (json_object_get_int(val2) != unit->cooler_state)
+		    unit->cooler_state = json_object_get_int(val2);
+		if (unit->heater_state || unit->cooler_state)
+		    unit->heater_state = unit->cooler_state = 0;	// Safety
+		unit->mqtt_flag |= MQTT_FLAG_DATA;
+		syslog(LOG_NOTICE, "ws: unit %s heater_state to %d, cooler_state to %d", unit->alias, unit->heater_state, unit->cooler_state);
+		break;
+	    }
+
+	    /*
+             * Unit fan switch
+	     * {"type":"fermenter","unit":"unit0","fan_state":0}
+             */
+	    if ((json_object_object_get_ex(jobj, "fan_state", &val)) && (unit->mode == UNITMODE_NONE)) {
+                if (json_object_get_int(val) != unit->fan_state)
+                    unit->fan_state = json_object_get_int(val);
+                unit->mqtt_flag |= MQTT_FLAG_DATA;
+                syslog(LOG_NOTICE, "ws: unit %s fan_state to %d", unit->alias, unit->fan_state);
+                break;
+            }
+
+	    return;
+	}
+    }
+    syslog(LOG_NOTICE, "fermenter_ws_receive(%s)", buf);
+}
+
+
 static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
 {
     struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user;
@@ -123,15 +279,15 @@
 		 * {"node":"rpi01","group_id":"fermenters","control":"reboot"}
 		 * {"node":"rpi01","group_id":"fermenters","control":"rebirth"}
 		 */
-//		if (strncmp(buf, (char *)"{\"device\":\"fermenters\",", 23) == 0) {
-//		    fermenter_ws_receive(buf);
+		if (strncmp(buf, (char *)"{\"type\":\"fermenter\",", 20) == 0) {
+		    fermenter_ws_receive(buf);
 //		} else if (strncmp(buf, (char *)"{\"device\":\"co2meters\",", 22) == 0) {
 //		    co2meter_ws_receive(buf);
 //		} else if (strncmp(buf, (char *)"{\"device\":\"ispindels\",", 22) == 0) {
 //		    ispindel_ws_receive(buf);
 //		} else if (strncmp(buf, (char *)"{\"node\":\"", 9) == 0) {
 //		    node_ws_receive(buf);
-//		}
+		}
 
                 break;
 

mercurial