bmsd/fermenters.c

changeset 679
48f8f3fce7c0
parent 677
6e82fece1f8f
child 684
ccb9f24d0fe9
equal deleted inserted replaced
678:14322825cb3d 679:48f8f3fce7c0
25 25
26 #include "bms.h" 26 #include "bms.h"
27 #include "xutil.h" 27 #include "xutil.h"
28 #include "fermenters.h" 28 #include "fermenters.h"
29 #include "mysql.h" 29 #include "mysql.h"
30 #include "mqtt.h"
30 #include "websocket.h" 31 #include "websocket.h"
31 32
32 33
33 sys_fermenter_list *fermenters = NULL; 34 sys_fermenter_list *fermenters = NULL;
34 35
35 extern int debug; 36 extern int debug;
36 extern sys_config Config; 37 extern sys_config Config;
38
39
40 void fermenter_ws_send(sys_fermenter_list *fermenter)
41 {
42 char *msg = NULL, buf[65];
43
44 msg = xstrcpy((char *)"{\"device\":\"fermenters\",\"node\":\"");
45 msg = xstrcat(msg, fermenter->node);
46 msg = xstrcat(msg, (char *)"\",\"unit\":\"");
47 msg = xstrcat(msg, fermenter->alias);
48 msg = xstrcat(msg, (char *)"\",\"online\":");
49 msg = xstrcat(msg, fermenter->online ? (char *)"1":(char *)"0");
50 msg = xstrcat(msg, (char *)",\"mode\":\"");
51 msg = xstrcat(msg, fermenter->mode);
52 msg = xstrcat(msg, (char *)"\",\"beeruuid\":\"");
53 msg = xstrcat(msg, fermenter->beeruuid);
54 msg = xstrcat(msg, (char *)"\",\"beercode\":\"");
55 msg = xstrcat(msg, fermenter->beercode);
56 msg = xstrcat(msg, (char *)"\",\"beername\":\"");
57 msg = xstrcat(msg, fermenter->beername);
58 msg = xstrcat(msg, (char *)"\",\"yeast_lo\":");
59 snprintf(buf, 64, "%.3f", fermenter->yeast_lo);
60 msg = xstrcat(msg, buf);
61 msg = xstrcat(msg, (char *)",\"yeast_hi\":");
62 snprintf(buf, 64, "%.3f", fermenter->yeast_hi);
63 msg = xstrcat(msg, buf);
64 if (fermenter->air_address) {
65 msg = xstrcat(msg, (char *)",\"air_state\":\"");
66 msg = xstrcat(msg, fermenter->air_state);
67 msg = xstrcat(msg, (char *)"\",\"air_temperature\":");
68 snprintf(buf, 64, "%.3f", fermenter->air_temperature);
69 msg = xstrcat(msg, buf);
70 }
71 if (fermenter->beer_address) {
72 msg = xstrcat(msg, (char *)",\"beer_state\":\"");
73 msg = xstrcat(msg, fermenter->beer_state);
74 msg = xstrcat(msg, (char *)"\",\"beer_temperature\":");
75 snprintf(buf, 64, "%.3f", fermenter->beer_temperature);
76 msg = xstrcat(msg, buf);
77 }
78 if (fermenter->chiller_address) {
79 msg = xstrcat(msg, (char *)",\"chiller_state\":\"");
80 msg = xstrcat(msg, fermenter->chiller_state);
81 msg = xstrcat(msg, (char *)"\",\"chiller_temperature\":");
82 snprintf(buf, 64, "%.3f", fermenter->chiller_temperature);
83 msg = xstrcat(msg, buf);
84 }
85 if (fermenter->heater_address) {
86 msg = xstrcat(msg, (char *)",\"heater_state\":");
87 snprintf(buf, 64, "%d", fermenter->heater_state);
88 msg = xstrcat(msg, buf);
89 }
90 if (fermenter->cooler_address) {
91 msg = xstrcat(msg, (char *)",\"cooler_state\":");
92 snprintf(buf, 64, "%d", fermenter->cooler_state);
93 msg = xstrcat(msg, buf);
94 }
95 if (fermenter->fan_address) {
96 msg = xstrcat(msg, (char *)",\"fan_state\":");
97 snprintf(buf, 64, "%d", fermenter->fan_state);
98 msg = xstrcat(msg, buf);
99 }
100 if (fermenter->light_address) {
101 msg = xstrcat(msg, (char *)",\"light_address\":\"");
102 msg = xstrcat(msg, fermenter->light_address);
103 msg = xstrcat(msg, (char *)"\",\"light_state\":");
104 snprintf(buf, 64, "%d", fermenter->light_state);
105 msg = xstrcat(msg, buf);
106 }
107 if (fermenter->door_address) {
108 msg = xstrcat(msg, (char *)",\"door_address\":\"");
109 msg = xstrcat(msg, fermenter->door_address);
110 msg = xstrcat(msg, (char *)"\",\"door_state\":");
111 snprintf(buf, 64, "%d", fermenter->door_state);
112 msg = xstrcat(msg, buf);
113 }
114 if (fermenter->psu_address) {
115 msg = xstrcat(msg, (char *)",\"psu_address\":\"");
116 msg = xstrcat(msg, fermenter->psu_address);
117 msg = xstrcat(msg, (char *)"\",\"psu_state\":");
118 snprintf(buf, 64, "%d", fermenter->psu_state);
119 msg = xstrcat(msg, buf);
120 }
121 msg = xstrcat(msg, (char *)",\"setpoint_low\":");
122 snprintf(buf, 64, "%.3f", fermenter->setpoint_low);
123 msg = xstrcat(msg, buf);
124 msg = xstrcat(msg, (char *)",\"setpoint_high\":");
125 snprintf(buf, 64, "%.3f", fermenter->setpoint_high);
126 msg = xstrcat(msg, buf);
127 msg = xstrcat(msg, (char *)",\"alarm\":");
128 snprintf(buf, 64, "%d", fermenter->alarm);
129 msg = xstrcat(msg, buf);
130 msg = xstrcat(msg, (char *)",\"stage\":\"");
131 msg = xstrcat(msg, fermenter->stage);
132 msg = xstrcat(msg, (char *)"\"");
133
134 if (fermenter->profile_uuid) {
135 msg = xstrcat(msg, (char *)",\"profile_uuid\":\"");
136 msg = xstrcat(msg, fermenter->profile_uuid);
137 msg = xstrcat(msg, (char *)"\",\"profile_name\":\"");
138 msg = xstrcat(msg, fermenter->profile_name);
139 msg = xstrcat(msg, (char *)"\",\"profile_state\":\"");
140 msg = xstrcat(msg, fermenter->profile_state);
141 msg = xstrcat(msg, (char *)"\",\"profile_percent\":");
142 snprintf(buf, 64, "%d", fermenter->profile_percent);
143 msg = xstrcat(msg, buf);
144 msg = xstrcat(msg, (char *)",\"profile_inittemp_high\":");
145 snprintf(buf, 64, "%.3f", fermenter->profile_inittemp_high);
146 msg = xstrcat(msg, buf);
147 msg = xstrcat(msg, (char *)",\"profile_inittemp_low\":");
148 snprintf(buf, 64, "%.3f", fermenter->profile_inittemp_low);
149 msg = xstrcat(msg, buf);
150 msg = xstrcat(msg, (char *)",\"profile_steps\":");
151 msg = xstrcat(msg, fermenter->profile_steps);
152 }
153
154 msg = xstrcat(msg, (char *)",\"webcam_url\":\"");
155 msg = xstrcat(msg, fermenter->webcam_url);
156 msg = xstrcat(msg, (char *)"\",\"webcam_light\":");
157 snprintf(buf, 64, "%d", fermenter->webcam_light);
158 msg = xstrcat(msg, buf);
159 msg = xstrcat(msg, (char *)"}");
160 ws_broadcast(msg);
161 free(msg);
162 msg = NULL;
163 }
164
165
166
167 char *fermenter_paybase(void)
168 {
169 static char *tmp;
170 char buf[33];
171
172 tmp = xstrcpy((char *)"{\"timestamp\":");
173 snprintf(buf, 32, "%ld", time(NULL));
174 tmp = xstrcat(tmp, buf);
175 tmp = xstrcat(tmp, (char *)",\"metric\":");
176 return tmp;
177 }
178
179
180 void fermenter_ws_receive(char *payload)
181 {
182 struct json_object *jobj, *pobj, *iobj, *val;
183 char *node = NULL, *alias = NULL, *beeruuid = NULL, *beercode = NULL, *beername = NULL;
184 char *mode = NULL, *stage = NULL, *profile = NULL, *profile_uuid = NULL, *profile_name = NULL, *profile_steps = NULL;
185 char *topic = NULL, *pay = NULL, buf[75], *profile_command = NULL;
186 float setpoint_low = 0, setpoint_high = 0, yeast_lo = 0, yeast_hi = 0, inittemp_lo = 0, inittemp_hi = 0;
187 int heater_state = -1, cooler_state = -1, fan_state = -1, profile_fridgemode = -1;
188
189 syslog(LOG_NOTICE, "fermenter_ws_receive(%s)", payload);
190
191 /*
192 * Process the JSON formatted payload.
193 */
194 jobj = json_tokener_parse(payload);
195 if (json_object_object_get_ex(jobj, "node", &val))
196 node = xstrcpy((char *)json_object_get_string(val));
197 if (json_object_object_get_ex(jobj, "unit", &val))
198 alias = xstrcpy((char *)json_object_get_string(val));
199 if (json_object_object_get_ex(jobj, "beeruuid", &val))
200 beeruuid = xstrcpy((char *)json_object_get_string(val));
201 if (json_object_object_get_ex(jobj, "beercode", &val))
202 beercode = xstrcpy((char *)json_object_get_string(val));
203 if (json_object_object_get_ex(jobj, "beername", &val))
204 beername = xstrcpy((char *)json_object_get_string(val));
205 if (json_object_object_get_ex(jobj, "mode", &val))
206 mode = xstrcpy((char *)json_object_get_string(val));
207 if (json_object_object_get_ex(jobj, "stage", &val))
208 stage = xstrcpy((char *)json_object_get_string(val));
209 if (json_object_object_get_ex(jobj, "setpoint_low", &val))
210 setpoint_low = json_object_get_double(val);
211 if (json_object_object_get_ex(jobj, "setpoint_high", &val))
212 setpoint_high = json_object_get_double(val);
213 if (json_object_object_get_ex(jobj, "yeast_lo", &val))
214 yeast_lo = json_object_get_double(val);
215 if (json_object_object_get_ex(jobj, "yeast_hi", &val))
216 yeast_hi = json_object_get_double(val);
217 if (json_object_object_get_ex(jobj, "heater_state", &val))
218 heater_state = json_object_get_int(val);
219 if (json_object_object_get_ex(jobj, "cooler_state", &val))
220 cooler_state = json_object_get_int(val);
221 if (json_object_object_get_ex(jobj, "fan_state", &val))
222 fan_state = json_object_get_int(val);
223 if (json_object_object_get_ex(jobj, "profile", &pobj)) {
224 profile = xstrcpy((char *)json_object_get_string(pobj));
225 if (profile == NULL) { // clear profile request
226 profile = xstrcpy((char *)"null");
227 }
228 if (json_object_object_get_ex(pobj, "uuid", &val)) {
229 profile_uuid = xstrcpy((char *)json_object_get_string(val));
230 syslog(LOG_NOTICE, "profile uuid");
231 }
232 if (json_object_object_get_ex(pobj, "name", &val))
233 profile_name = xstrcpy((char *)json_object_get_string(val));
234 if (json_object_object_get_ex(pobj, "inittemp", &iobj)) {
235
236 if (json_object_object_get_ex(iobj, "low", &val))
237 inittemp_lo = json_object_get_double(val);
238 if (json_object_object_get_ex(iobj, "high", &val))
239 inittemp_hi = json_object_get_double(val);
240 }
241 if (json_object_object_get_ex(pobj, "fridgemode", &val))
242 profile_fridgemode = json_object_get_int(val);
243 if (json_object_object_get_ex(pobj, "steps", &val))
244 profile_steps = xstrcpy((char *)json_object_get_string(val));
245 if (json_object_object_get_ex(pobj, "command", &val)) {
246 profile_command = xstrcpy((char *)json_object_get_string(val));
247 syslog(LOG_NOTICE, "profile command %s", profile_command);
248 }
249 }
250 json_object_put(jobj);
251
252 /*
253 * Prepare MQTT topic
254 */
255 topic = xstrcpy((char *)"mbv1.0/fermenters/DCMD/");
256 topic = xstrcat(topic, node);
257 topic = xstrcat(topic, (char *)"/");
258 topic = xstrcat(topic, alias);
259
260 if (node && alias) {
261 if (mode) {
262 syslog(LOG_NOTICE, "Set fermenter %s/%s mode %s", node, alias, mode);
263 pay = fermenter_paybase();
264 pay = xstrcat(pay, (char *)"{\"mode\":\"");
265 pay = xstrcat(pay, mode);
266 pay = xstrcat(pay, (char *)"\"}}");
267 mqtt_publish(topic, pay);
268 free(pay);
269 pay = NULL;
270 }
271
272 if (stage) {
273 syslog(LOG_NOTICE, "Set fermenter %s/%s stage %s", node, alias, stage);
274 pay = fermenter_paybase();
275 pay = xstrcat(pay, (char *)"{\"stage\":\"");
276 pay = xstrcat(pay, stage);
277 pay = xstrcat(pay, (char *)"\"}}");
278 mqtt_publish(topic, pay);
279 free(pay);
280 pay = NULL;
281 }
282
283 if (setpoint_low > 0 && setpoint_high > 0 && setpoint_high >= setpoint_low) {
284 syslog(LOG_NOTICE, "Set fermenter %s/%s setpoint %.1f %.1f", node, alias, setpoint_low, setpoint_high);
285 pay = fermenter_paybase();
286 pay = xstrcat(pay, (char *)"{\"setpoint\":{\"low\":");
287 snprintf(buf, 64, "%.1f", setpoint_low);
288 pay = xstrcat(pay, buf);
289 pay = xstrcat(pay, (char *)",\"high\":");
290 snprintf(buf, 64, "%.1f", setpoint_high);
291 pay = xstrcat(pay, buf);
292 pay = xstrcat(pay, (char *)"}}}");
293 mqtt_publish(topic, pay);
294 free(pay);
295 pay = NULL;
296 }
297
298 if (heater_state >= 0) {
299 syslog(LOG_NOTICE, "Set fermenter %s/%s heater %d", node, alias, heater_state);
300 pay = fermenter_paybase();
301 pay = xstrcat(pay, (char *)"{\"heater\":{\"state\":");
302 snprintf(buf, 64, "%d", heater_state);
303 pay = xstrcat(pay, buf);
304 pay = xstrcat(pay, (char *)"}}}");
305 mqtt_publish(topic, pay);
306 free(pay);
307 pay = NULL;
308 }
309
310 if (cooler_state >= 0) {
311 syslog(LOG_NOTICE, "Set fermenter %s/%s cooler %d", node, alias, cooler_state);
312 pay = fermenter_paybase();
313 pay = xstrcat(pay, (char *)"{\"cooler\":{\"state\":");
314 snprintf(buf, 64, "%d", cooler_state);
315 pay = xstrcat(pay, buf);
316 pay = xstrcat(pay, (char *)"}}}");
317 mqtt_publish(topic, pay);
318 free(pay);
319 pay = NULL;
320 }
321
322 if (fan_state >= 0) {
323 syslog(LOG_NOTICE, "Set fermenter %s/%s fan %d", node, alias, fan_state);
324 pay = fermenter_paybase();
325 pay = xstrcat(pay, (char *)"{\"fan\":{\"state\":");
326 snprintf(buf, 64, "%d", fan_state);
327 pay = xstrcat(pay, buf);
328 pay = xstrcat(pay, (char *)"}}}");
329 mqtt_publish(topic, pay);
330 free(pay);
331 pay = NULL;
332 }
333
334 if (beeruuid && beercode && beername && (yeast_hi > yeast_lo) && (yeast_lo > 0)) {
335 syslog(LOG_NOTICE, "Set fermenter %s/%s beer %s %s", node, alias, beercode, beername);
336 pay = fermenter_paybase();
337 pay = xstrcat(pay, (char *)"{\"product\":{\"uuid\":\"");
338 pay = xstrcat(pay, beeruuid);
339 pay = xstrcat(pay, (char *)"\",\"code\":\"");
340 pay = xstrcat(pay, beercode);
341 pay = xstrcat(pay, (char *)"\",\"name\":\"");
342 pay = xstrcat(pay, beername);
343 pay = xstrcat(pay, (char *)"\",\"yeast_lo\":");
344 snprintf(buf, 64, "%.1f", yeast_lo);
345 pay = xstrcat(pay, buf);
346 pay = xstrcat(pay, (char *)",\"yeast_hi\":");
347 snprintf(buf, 64, "%.1f", yeast_hi);
348 pay = xstrcat(pay, buf);
349 pay = xstrcat(pay, (char *)"}}}");
350 mqtt_publish(topic, pay);
351 free(pay);
352 pay = NULL;
353 }
354
355 if (profile) {
356 syslog(LOG_NOTICE, "%s", profile);
357 if (strcmp(profile, (char *)"null") == 0) {
358 syslog(LOG_NOTICE, "Set fermenter %s/%s profile null", node, alias);
359 pay = fermenter_paybase();
360 pay = xstrcat(pay, (char *)"{\"profile\":null}}");
361 mqtt_publish(topic, pay);
362 free(pay);
363 pay = NULL;
364 } else if (profile_uuid && profile_name && profile_steps) {
365 syslog(LOG_NOTICE, "Set fermenter %s/%s profile %s", node, alias, profile_name);
366 pay = fermenter_paybase();
367 pay = xstrcat(pay, (char *)"{\"profile\":{\"uuid\":\"");
368 pay = xstrcat(pay, profile_uuid);
369 pay = xstrcat(pay, (char *)"\",\"name\":\"");
370 pay = xstrcat(pay, profile_name);
371 pay = xstrcat(pay, (char *)"\",\"inittemp\":{\"low\":");
372 snprintf(buf, 64, "%.1f", inittemp_lo);
373 pay = xstrcat(pay, buf);
374 pay = xstrcat(pay, (char *)",\"high\":");
375 snprintf(buf, 64, "%.1f", inittemp_hi);
376 pay = xstrcat(pay, buf);
377 pay = xstrcat(pay, (char *)"},\"fridgemode\":");
378 snprintf(buf, 64, "%d", profile_fridgemode);
379 pay = xstrcat(pay, buf);
380 pay = xstrcat(pay, (char *)",\"steps\":");
381 pay = xstrcat(pay, profile_steps);
382 pay = xstrcat(pay, (char *)"}}}");
383 mqtt_publish(topic, pay);
384 free(pay);
385 pay = NULL;
386 } else if (profile_command) {
387 syslog(LOG_NOTICE, "Set fermenter %s/%s profile command %s", node, alias, profile_command);
388 pay = fermenter_paybase();
389 pay = xstrcat(pay, (char *)"{\"profile\":{\"command\":\"");
390 pay = xstrcat(pay, profile_command);
391 pay = xstrcat(pay, (char *)"\"}}}");
392 mqtt_publish(topic, pay);
393 free(pay);
394 pay = NULL;
395 }
396 }
397 }
398
399 free(topic);
400 if (node)
401 free(node);
402 if (alias)
403 free(alias);
404 if (beeruuid)
405 free(beeruuid);
406 if (beercode)
407 free(beercode);
408 if (beername)
409 free(beername);
410 if (mode)
411 free(mode);
412 if (stage)
413 free(stage);
414 if (profile)
415 free(profile);
416 if (profile_uuid)
417 free(profile_uuid);
418 if (profile_name)
419 free(profile_name);
420 if (profile_steps)
421 free(profile_steps);
422 if (profile_command)
423 free(profile_command);
424 }
37 425
38 426
39 427
40 void fermenter_set(char *edge_node, char *alias, bool birth, char *payload) 428 void fermenter_set(char *edge_node, char *alias, bool birth, char *payload)
41 { 429 {
42 struct json_object *jobj, *val, *sensor, *temp; 430 struct json_object *jobj, *val, *sensor, *temp;
43 sys_fermenter_list *fermenter, *tmpp; 431 sys_fermenter_list *fermenter, *tmpp;
44 bool new_fermenter = true; 432 bool new_fermenter = true;
45 char *msg = NULL, buf[65]; 433
46 434 //syslog(LOG_NOTICE, "fermenter_set: %s/%s %s %s", edge_node, alias, birth ? "BIRTH":"DATA", payload);
47 // fprintf(stdout, "fermenter_set: %s/%s %s %s\n", edge_node, alias, birth ? "BIRTH":"DATA", payload);
48 435
49 /* 436 /*
50 * Search fermenter record in the memory array and use it if found. 437 * Search fermenter record in the memory array and use it if found.
51 */ 438 */
52 if (fermenters) { 439 if (fermenters) {
265 fermenter->setpoint_high = json_object_get_double(val); 652 fermenter->setpoint_high = json_object_get_double(val);
266 } 653 }
267 } 654 }
268 if (json_object_object_get_ex(jobj, "profile", &sensor)) { 655 if (json_object_object_get_ex(jobj, "profile", &sensor)) {
269 if (strcmp(json_object_to_json_string_ext(sensor, 0), "null")) { 656 if (strcmp(json_object_to_json_string_ext(sensor, 0), "null")) {
270 // printf("profile: %s\n", json_object_to_json_string_ext(sensor, 0));
271
272 if (json_object_object_get_ex(sensor, "uuid", &val)) { 657 if (json_object_object_get_ex(sensor, "uuid", &val)) {
273 if (fermenter->profile_uuid) 658 if (fermenter->profile_uuid)
274 free(fermenter->profile_uuid); 659 free(fermenter->profile_uuid);
275 fermenter->profile_uuid = xstrcpy((char *)json_object_get_string(val)); 660 fermenter->profile_uuid = xstrcpy((char *)json_object_get_string(val));
276 } 661 }
312 if (fermenter->profile_steps) 697 if (fermenter->profile_steps)
313 free(fermenter->profile_steps); 698 free(fermenter->profile_steps);
314 fermenter->profile_uuid = fermenter->profile_name = fermenter->profile_state = fermenter->profile_steps = NULL; 699 fermenter->profile_uuid = fermenter->profile_name = fermenter->profile_state = fermenter->profile_steps = NULL;
315 fermenter->profile_percent = 0; 700 fermenter->profile_percent = 0;
316 fermenter->profile_inittemp_high = fermenter->profile_inittemp_low = 0.0; 701 fermenter->profile_inittemp_high = fermenter->profile_inittemp_low = 0.0;
317 fermenter->yeast_lo = 12;
318 fermenter->yeast_hi = 24;
319 } 702 }
320 } 703 }
321 json_object_put(jobj); 704 json_object_put(jobj);
322 705
323 msg = xstrcpy((char *)"{\"device\":\"fermenters\",\"node\":\""); 706 fermenter_ws_send(fermenter);
324 msg = xstrcat(msg, edge_node);
325 msg = xstrcat(msg, (char *)"\",\"unit\":\"");
326 msg = xstrcat(msg, alias);
327 msg = xstrcat(msg, (char *)"\",\"online\":");
328 msg = xstrcat(msg, fermenter->online ? (char *)"1":(char *)"0");
329 msg = xstrcat(msg, (char *)",\"mode\":\"");
330 msg = xstrcat(msg, fermenter->mode);
331 msg = xstrcat(msg, (char *)"\",\"yeast_lo\":");
332 snprintf(buf, 64, "%.3f", fermenter->yeast_lo);
333 msg = xstrcat(msg, buf);
334 msg = xstrcat(msg, (char *)",\"yeast_hi\":");
335 snprintf(buf, 64, "%.3f", fermenter->yeast_hi);
336 msg = xstrcat(msg, buf);
337 if (fermenter->air_address) {
338 msg = xstrcat(msg, (char *)",\"air\":");
339 snprintf(buf, 64, "%.3f", fermenter->air_temperature);
340 msg = xstrcat(msg, buf);
341 }
342 if (fermenter->beer_address) {
343 msg = xstrcat(msg, (char *)",\"beer\":");
344 snprintf(buf, 64, "%.3f", fermenter->beer_temperature);
345 msg = xstrcat(msg, buf);
346 }
347 if (fermenter->chiller_address) {
348 msg = xstrcat(msg, (char *)",\"chiller\":");
349 snprintf(buf, 64, "%.3f", fermenter->chiller_temperature);
350 msg = xstrcat(msg, buf);
351 }
352 if (fermenter->heater_address) {
353 msg = xstrcat(msg, (char *)",\"heater\":");
354 snprintf(buf, 64, "%d", fermenter->heater_state);
355 msg = xstrcat(msg, buf);
356 }
357 if (fermenter->cooler_address) {
358 msg = xstrcat(msg, (char *)",\"cooler\":");
359 snprintf(buf, 64, "%d", fermenter->cooler_state);
360 msg = xstrcat(msg, buf);
361 }
362 if (fermenter->fan_address) {
363 msg = xstrcat(msg, (char *)",\"fan\":");
364 snprintf(buf, 64, "%d", fermenter->fan_state);
365 msg = xstrcat(msg, buf);
366 }
367 if (fermenter->light_address) {
368 msg = xstrcat(msg, (char *)",\"light\":");
369 snprintf(buf, 64, "%d", fermenter->light_state);
370 msg = xstrcat(msg, buf);
371 }
372 if (fermenter->door_address) {
373 msg = xstrcat(msg, (char *)",\"door\":");
374 snprintf(buf, 64, "%d", fermenter->door_state);
375 msg = xstrcat(msg, buf);
376 }
377 msg = xstrcat(msg, (char *)",\"sp_lo\":");
378 snprintf(buf, 64, "%.3f", fermenter->setpoint_low);
379 msg = xstrcat(msg, buf);
380 msg = xstrcat(msg, (char *)",\"sp_hi\":");
381 snprintf(buf, 64, "%.3f", fermenter->setpoint_high);
382 msg = xstrcat(msg, buf);
383 msg = xstrcat(msg, (char *)",\"alarm\":");
384 snprintf(buf, 64, "%d", fermenter->alarm);
385 msg = xstrcat(msg, buf);
386 msg = xstrcat(msg, (char *)",\"stage\":\"");
387 msg = xstrcat(msg, fermenter->stage);
388 msg = xstrcat(msg, (char *)"\"}");
389 ws_broadcast(msg);
390 free(msg);
391 msg = NULL;
392
393 // fermenter_dump(fermenter); 707 // fermenter_dump(fermenter);
394 708
395 if (new_fermenter) { 709 if (new_fermenter) {
396 if (fermenters == NULL) { 710 if (fermenters == NULL) {
397 fermenters = fermenter; 711 fermenters = fermenter;

mercurial