thermferm/websocket.c

changeset 678
cc49115e769e
parent 676
09b5efe0c633
child 680
8b3c86124a08
equal deleted inserted replaced
677:c867eb3f7fc1 678:cc49115e769e
24 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 */ 25 */
26 26
27 #include "thermferm.h" 27 #include "thermferm.h"
28 #include "xutil.h" 28 #include "xutil.h"
29 #include "devices.h"
29 #include "websocket.h" 30 #include "websocket.h"
30 #include <libwebsockets.h> 31 #include <libwebsockets.h>
31 32
32 33
33 extern sys_config Config; 34 extern sys_config Config;
34 extern int debug; 35 extern int debug;
36 extern const char UNITMODE[5][8];
37 extern const char UNITSTAGE[4][12];
38 //extern const char PROFSTATE[5][6];
39 //extern const char TEMPSTATE[3][8];
35 40
36 int my_ws_shutdown = 0; 41 int my_ws_shutdown = 0;
37 int my_ws_state = 0; 42 int my_ws_state = 0;
38 struct lws_context *context; 43 struct lws_context *context;
39 int ws_clients = 0; 44 int ws_clients = 0;
59 64
60 65
61 static struct a_message ringbuffer[MAX_MESSAGE_QUEUE]; 66 static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
62 static int ringbuffer_head; 67 static int ringbuffer_head;
63 68
69
70
71 void fermenter_ws_receive(char *buf)
72 {
73 struct json_object *val, *val2, *jobj;
74 units_list *unit;
75 bool changed;
76
77 jobj = json_tokener_parse(buf);
78 json_object_object_get_ex(jobj, "unit", &val);
79
80 for (unit = Config.units ; unit; unit = unit->next) {
81 if (strcmp((char *)json_object_get_string(val), unit->alias) == 0) {
82 /*
83 * Setpoints
84 * {"type":"fermenter","unit":"unit0","setpoint_low":20.3,"setpoint_high":20.7}
85 */
86 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) {
87 changed = false;
88 if (json_object_object_get_ex(jobj, "setpoint_low", &val)) {
89 if (unit->PID_heat->SetP != json_object_get_double(val)) {
90 changed = true;
91 syslog(LOG_NOTICE, "ws: unit %s setpoint low from %.1f to %.1f", unit->alias, unit->PID_heat->SetP, json_object_get_double(val));
92 unit->PID_heat->SetP = json_object_get_double(val);
93 }
94 }
95 if (json_object_object_get_ex(jobj, "setpoint_high", &val)) {
96 if (unit->PID_cool->SetP != json_object_get_double(val)) {
97 changed = true;
98 syslog(LOG_NOTICE, "ws: unit %s setpoint high from %.1f to %.1f", unit->alias, unit->PID_cool->SetP, json_object_get_double(val));
99 unit->PID_cool->SetP = json_object_get_double(val);
100 }
101 }
102 if (changed) {
103 if (unit->mode == UNITMODE_FRIDGE) {
104 unit->fridge_set_lo = unit->PID_heat->SetP;
105 unit->fridge_set_hi = unit->PID_cool->SetP;
106 } else {
107 unit->beer_set_lo = unit->PID_heat->SetP;
108 unit->beer_set_hi = unit->PID_cool->SetP;
109 }
110 unit->mqtt_flag |= MQTT_FLAG_DATA;
111 break;
112 }
113 }
114
115 /*
116 * Unit mode
117 * {"type":"fermenter","unit":"unit0","mode":"NONE"}
118 */
119 if (json_object_object_get_ex(jobj, "mode", &val)) {
120 for (int i = 0; i < 5; i++) {
121 if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) {
122 if (unit->mode != i) {
123 unit->mqtt_flag |= MQTT_FLAG_DATA;
124 /* Initialize log if the unit is turned on */
125 if ((unit->mode == UNITMODE_OFF) && (i != UNITMODE_OFF)) {
126 unit->mqtt_flag |= MQTT_FLAG_BIRTH;
127 }
128 if (i == UNITMODE_PROFILE) {
129 /* Do some checks and refuse profile mode cannot be set */
130 if (unit->profile_uuid == NULL) {
131 syslog(LOG_NOTICE, "ws: unit %s refuse mode profile, not loaded", unit->alias);
132 break;
133 }
134 }
135 syslog(LOG_NOTICE, "ws: unit %s mode to %s", unit->alias, UNITMODE[i]);
136 unit->mode = i;
137 if ((unit->mode != UNITMODE_OFF) && ! unit->event_msg)
138 unit->event_msg = xstrcpy((char *)UNITMODE[i]);
139 /* Allways turn everything off after a mode change */
140 unit->PID_cool->OutP = unit->PID_heat->OutP = 0.0;
141 unit->PID_cool->Mode = unit->PID_heat->Mode = PID_MODE_NONE;
142 unit->heater_state = unit->cooler_state = unit->fan_state = unit->light_state = unit->light_timer = 0;
143 unit->heater_wait = unit->cooler_wait = unit->fan_wait = unit->light_wait = 0;
144 device_out(unit->heater_address, unit->heater_state);
145 device_out(unit->cooler_address, unit->cooler_state);
146 device_out(unit->fan_address, unit->fan_state);
147 device_out(unit->light_address, unit->light_state);
148 if (unit->mode == UNITMODE_PROFILE) {
149 /*
150 * Set a sane default until it will be overruled by the
151 * main processing loop.
152 */
153 unit->prof_target_lo = unit->profile_inittemp_lo;
154 unit->prof_target_hi = unit->profile_inittemp_hi;;
155 unit->prof_fridge_mode = 0;
156 unit->prof_state = PROFILE_OFF;
157 unit->prof_started = unit->prof_paused = unit->prof_primary_done = 0;
158 unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
159 }
160 }
161 break;
162 }
163 }
164 }
165
166 /*
167 * Unit stage
168 * {"type":"fermenter","unit":"unit0","stage":"SECONDARY"}
169 */
170 if (json_object_object_get_ex(jobj, "stage", &val)) {
171 for (int i = 0; i < 4; i++) {
172 if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) {
173 if (unit->stage != i) {
174 syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", unit->alias, UNITSTAGE[i]);
175 unit->mqtt_flag |= MQTT_FLAG_DATA;
176 unit->stage = i;
177 if ((unit->mode != UNITMODE_OFF) && ! unit->event_msg)
178 unit->event_msg = xstrcpy((char *)UNITSTAGE[i]);
179 }
180 break;
181 }
182 }
183 }
184
185 /*
186 * Unit heater and cooler switch
187 * {"type":"fermenter","unit":"unit0","heater_state":100,"cooler_state":0}
188 */
189 if ((json_object_object_get_ex(jobj, "heater_state", &val)) &&
190 (json_object_object_get_ex(jobj, "cooler_state", &val2)) &&
191 (unit->mode == UNITMODE_NONE)) {
192 if (json_object_get_int(val) != unit->heater_state)
193 unit->heater_state = json_object_get_int(val);
194 if (json_object_get_int(val2) != unit->cooler_state)
195 unit->cooler_state = json_object_get_int(val2);
196 if (unit->heater_state || unit->cooler_state)
197 unit->heater_state = unit->cooler_state = 0; // Safety
198 unit->mqtt_flag |= MQTT_FLAG_DATA;
199 syslog(LOG_NOTICE, "ws: unit %s heater_state to %d, cooler_state to %d", unit->alias, unit->heater_state, unit->cooler_state);
200 break;
201 }
202
203 /*
204 * Unit fan switch
205 * {"type":"fermenter","unit":"unit0","fan_state":0}
206 */
207 if ((json_object_object_get_ex(jobj, "fan_state", &val)) && (unit->mode == UNITMODE_NONE)) {
208 if (json_object_get_int(val) != unit->fan_state)
209 unit->fan_state = json_object_get_int(val);
210 unit->mqtt_flag |= MQTT_FLAG_DATA;
211 syslog(LOG_NOTICE, "ws: unit %s fan_state to %d", unit->alias, unit->fan_state);
212 break;
213 }
214
215 return;
216 }
217 }
218 syslog(LOG_NOTICE, "fermenter_ws_receive(%s)", buf);
219 }
64 220
65 221
66 static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) 222 static int callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
67 { 223 {
68 struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user; 224 struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user;
121 * These are send by bmsapp to bmsd. Then bmsd resends these via MQTT. 277 * These are send by bmsapp to bmsd. Then bmsd resends these via MQTT.
122 * Do we want to change that? Or use it for the new web pages. 278 * Do we want to change that? Or use it for the new web pages.
123 * {"node":"rpi01","group_id":"fermenters","control":"reboot"} 279 * {"node":"rpi01","group_id":"fermenters","control":"reboot"}
124 * {"node":"rpi01","group_id":"fermenters","control":"rebirth"} 280 * {"node":"rpi01","group_id":"fermenters","control":"rebirth"}
125 */ 281 */
126 // if (strncmp(buf, (char *)"{\"device\":\"fermenters\",", 23) == 0) { 282 if (strncmp(buf, (char *)"{\"type\":\"fermenter\",", 20) == 0) {
127 // fermenter_ws_receive(buf); 283 fermenter_ws_receive(buf);
128 // } else if (strncmp(buf, (char *)"{\"device\":\"co2meters\",", 22) == 0) { 284 // } else if (strncmp(buf, (char *)"{\"device\":\"co2meters\",", 22) == 0) {
129 // co2meter_ws_receive(buf); 285 // co2meter_ws_receive(buf);
130 // } else if (strncmp(buf, (char *)"{\"device\":\"ispindels\",", 22) == 0) { 286 // } else if (strncmp(buf, (char *)"{\"device\":\"ispindels\",", 22) == 0) {
131 // ispindel_ws_receive(buf); 287 // ispindel_ws_receive(buf);
132 // } else if (strncmp(buf, (char *)"{\"node\":\"", 9) == 0) { 288 // } else if (strncmp(buf, (char *)"{\"node\":\"", 9) == 0) {
133 // node_ws_receive(buf); 289 // node_ws_receive(buf);
134 // } 290 }
135 291
136 break; 292 break;
137 293
138 case LWS_CALLBACK_CLOSED: 294 case LWS_CALLBACK_CLOSED:
139 ws_clients--; 295 ws_clients--;

mercurial