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) { |
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; |