thermferm/mqtt.c

changeset 570
1e0192b295b9
parent 569
9c69d43bfb06
child 571
6f8eda55ec2c
equal deleted inserted replaced
569:9c69d43bfb06 570:1e0192b295b9
19 * along with ThermFerm; see the file COPYING. If not, write to the Free 19 * along with ThermFerm; see the file COPYING. If not, write to the Free
20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 20 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *****************************************************************************/ 21 *****************************************************************************/
22 22
23 #include "thermferm.h" 23 #include "thermferm.h"
24 #include "rdconfig.h"
24 #include "logger.h" 25 #include "logger.h"
25 #include "devices.h" 26 #include "devices.h"
26 #include "xutil.h" 27 #include "xutil.h"
27 #include "mqtt.h" 28 #include "mqtt.h"
28 29
150 151
151 152
152 153
153 void my_log_callback(struct mosquitto *my_mosq, void *obj, int level, const char *str) 154 void my_log_callback(struct mosquitto *my_mosq, void *obj, int level, const char *str)
154 { 155 {
155 syslog(LOG_NOTICE, "MQTT: %s", str); 156 // syslog(LOG_NOTICE, "MQTT: %s", str);
156 if (debug) 157 if (debug)
157 fprintf(stdout, "MQTT: %s\n", str); 158 fprintf(stdout, "MQTT: %s\n", str);
158 } 159 }
159 160
160 161
161 162
162 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message) 163 void my_message_callback(struct mosquitto *my_mosq, void *userdata, const struct mosquitto_message *message)
163 { 164 {
164 char *message_type, *message_node, *message_alias; 165 char *message_type, *message_node, *message_alias;
165 units_list *unit; 166 units_list *unit;
166 struct json_object *jobj, *metric, *val, *setpoint; 167 prof_step *step, *oldstep;
168 struct json_object *jobj, *metric, *val, *setpoint, *profile, *profile1, *steps, *step1;
167 time_t timestamp; 169 time_t timestamp;
168 int timediff; 170 int timediff;
169 171
170 if (message->payloadlen) { 172 if (message->payloadlen) {
171 /* 173 /*
203 publishNData(true, 0); 205 publishNData(true, 0);
204 publishDBirthAll(); 206 publishDBirthAll();
205 return; 207 return;
206 } 208 }
207 } 209 }
210
211 /*
212 * DCMD, commands and configuration changes for a single fermenter.
213 */
208 if ((strcmp(message_type, "DCMD") == 0) && message_node && message_alias) { 214 if ((strcmp(message_type, "DCMD") == 0) && message_node && message_alias) {
209 syslog(LOG_NOTICE, "%s", (char *)json_object_get_string(metric)); 215 syslog(LOG_NOTICE, "%s", (char *)json_object_get_string(metric));
210 for (unit = Config.units ; unit; unit = unit->next) { 216 for (unit = Config.units ; unit; unit = unit->next) {
211 if (strcmp(unit->alias, message_alias) == 0) { 217 if (strcmp(unit->alias, message_alias) == 0) {
212 syslog(LOG_NOTICE, "MQTT: DCMD for %s/%s", (char *)message_node, (char *)message_alias); 218 syslog(LOG_NOTICE, "MQTT: DCMD for %s/%s", (char *)message_node, (char *)message_alias);
213 if (json_object_object_get_ex(metric, "stage", &val)) { 219 if (json_object_object_get_ex(metric, "stage", &val)) {
214 // syslog(LOG_NOTICE, "Change state %s", UNITSTAGE[unit->stage]);
215 for (int i = 0; i < 4; i++) { 220 for (int i = 0; i < 4; i++) {
216 if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) { 221 if (strcmp((char *)json_object_get_string(val), UNITSTAGE[i]) == 0) {
217 if (unit->stage != i) { 222 if (unit->stage != i) {
218 syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", message_alias, UNITSTAGE[i]); 223 syslog(LOG_NOTICE, "DCMD change fermenter %s: stage to %s", message_alias, UNITSTAGE[i]);
219 unit->mqtt_flag |= MQTT_FLAG_DATA; 224 unit->mqtt_flag |= MQTT_FLAG_DATA;
221 } 226 }
222 break; 227 break;
223 } 228 }
224 } 229 }
225 } 230 }
226 printf("start mode\n"); 231
227 if (json_object_object_get_ex(metric, "mode", &val)) { 232 if (json_object_object_get_ex(metric, "mode", &val)) {
228 for (int i = 0; i < 4; i++) { 233 for (int i = 0; i < 4; i++) {
229 if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) { 234 if (strcmp((char *)json_object_get_string(val), UNITMODE[i]) == 0) {
230 if (unit->mode != i) { 235 if (unit->mode != i) {
231 syslog(LOG_NOTICE, "DCMD change fermenter %s: mode to %s", message_alias, UNITMODE[i]); 236 syslog(LOG_NOTICE, "DCMD change fermenter %s: mode to %s", message_alias, UNITMODE[i]);
253 * Set a sane default until it will be overruled by the 258 * Set a sane default until it will be overruled by the
254 * main processing loop. 259 * main processing loop.
255 */ 260 */
256 unit->prof_target_lo = unit->prof_target_hi = 20.0; 261 unit->prof_target_lo = unit->prof_target_hi = 20.0;
257 unit->prof_fridge_mode = 0; 262 unit->prof_fridge_mode = 0;
258 if (unit->profile) { 263 if (unit->profile_uuid) {
259 unit->mqtt_flag |= MQTT_FLAG_DATA; 264 unit->mqtt_flag |= MQTT_FLAG_DATA;
260 } 265 }
261 } 266 }
262 } 267 }
263 break; 268 break;
264 } 269 }
265 } 270 }
266 } 271 }
267 printf("start setpoint\n"); 272
268 if (json_object_object_get_ex(metric, "setpoint", &setpoint)) { 273 if (json_object_object_get_ex(metric, "setpoint", &setpoint)) {
269 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) { 274 if ((unit->mode == UNITMODE_FRIDGE) || (unit->mode == UNITMODE_BEER)) {
270 /* 275 /*
271 * Only set new setpoints if running as FRIDGE or in BEER mode. 276 * Only set new setpoints if running in FRIDGE or in BEER mode.
272 */ 277 */
273 if (json_object_object_get_ex(setpoint, "low", &val)) { 278 if (json_object_object_get_ex(setpoint, "low", &val))
274 unit->PID_heat->SetP = json_object_get_double(val); 279 unit->PID_heat->SetP = json_object_get_double(val);
275 } 280 if (json_object_object_get_ex(setpoint, "high", &val))
276 if (json_object_object_get_ex(setpoint, "high", &val)) {
277 unit->PID_cool->SetP = json_object_get_double(val); 281 unit->PID_cool->SetP = json_object_get_double(val);
278 } 282 if (unit->mode == UNITMODE_FRIDGE)
279 if (unit->mode == UNITMODE_FRIDGE) {
280 unit->fridge_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2); 283 unit->fridge_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2);
281 } else { 284 else
282 unit->beer_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2); 285 unit->beer_set = unit->PID_heat->SetP + ((unit->PID_cool->SetP - unit->PID_heat->SetP) / 2);
283 }
284 unit->mqtt_flag |= MQTT_FLAG_DATA; 286 unit->mqtt_flag |= MQTT_FLAG_DATA;
285 syslog(LOG_NOTICE, "DCMD change fermenter %s: setpoints %.1f %.1f", message_alias, unit->PID_heat->SetP, unit->PID_cool->SetP); 287 syslog(LOG_NOTICE, "DCMD change fermenter %s: setpoints %.1f %.1f", message_alias, unit->PID_heat->SetP, unit->PID_cool->SetP);
286 } 288 }
287 } 289 }
288 printf("start heater\n"); 290
289 if ((json_object_object_get_ex(metric, "heater", &setpoint)) && (unit->mode == UNITMODE_NONE)) { 291 if ((json_object_object_get_ex(metric, "heater", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
290 if (json_object_object_get_ex(setpoint, "state", &val)) { 292 if (json_object_object_get_ex(setpoint, "state", &val)) {
291 if (json_object_get_int(val) != unit->heater_state) { 293 if (json_object_get_int(val) != unit->heater_state) {
292 unit->heater_state = json_object_get_int(val); 294 unit->heater_state = json_object_get_int(val);
293 if (unit->heater_state) // Safety 295 if (unit->heater_state) // Safety
295 unit->mqtt_flag |= MQTT_FLAG_DATA; 297 unit->mqtt_flag |= MQTT_FLAG_DATA;
296 syslog(LOG_NOTICE, "DCMD change fermenter %s: heater_state to %d", message_alias, unit->heater_state); 298 syslog(LOG_NOTICE, "DCMD change fermenter %s: heater_state to %d", message_alias, unit->heater_state);
297 } 299 }
298 } 300 }
299 } 301 }
302
300 if ((json_object_object_get_ex(metric, "cooler", &setpoint)) && (unit->mode == UNITMODE_NONE)) { 303 if ((json_object_object_get_ex(metric, "cooler", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
301 if (json_object_object_get_ex(setpoint, "state", &val)) { 304 if (json_object_object_get_ex(setpoint, "state", &val)) {
302 if (json_object_get_int(val) != unit->cooler_state) { 305 if (json_object_get_int(val) != unit->cooler_state) {
303 unit->cooler_state = json_object_get_int(val); 306 unit->cooler_state = json_object_get_int(val);
304 if (unit->cooler_state) 307 if (unit->cooler_state)
306 unit->mqtt_flag |= MQTT_FLAG_DATA; 309 unit->mqtt_flag |= MQTT_FLAG_DATA;
307 syslog(LOG_NOTICE, "DCMD change fermenter %s: cooler_state to %d", message_alias, unit->cooler_state); 310 syslog(LOG_NOTICE, "DCMD change fermenter %s: cooler_state to %d", message_alias, unit->cooler_state);
308 } 311 }
309 } 312 }
310 } 313 }
314
311 if ((json_object_object_get_ex(metric, "fan", &setpoint)) && (unit->mode == UNITMODE_NONE)) { 315 if ((json_object_object_get_ex(metric, "fan", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
312 if (json_object_object_get_ex(setpoint, "state", &val)) { 316 if (json_object_object_get_ex(setpoint, "state", &val)) {
313 if (json_object_get_int(val) != unit->fan_state) { 317 if (json_object_get_int(val) != unit->fan_state) {
314 unit->fan_state = json_object_get_int(val); 318 unit->fan_state = json_object_get_int(val);
315 unit->mqtt_flag |= MQTT_FLAG_DATA; 319 unit->mqtt_flag |= MQTT_FLAG_DATA;
316 syslog(LOG_NOTICE, "DCMD change fermenter %s: fan_state to %d", message_alias, unit->fan_state); 320 syslog(LOG_NOTICE, "DCMD change fermenter %s: fan_state to %d", message_alias, unit->fan_state);
317 } 321 }
318 } 322 }
319 } 323 }
324
320 if ((json_object_object_get_ex(metric, "light", &setpoint)) && (unit->mode == UNITMODE_NONE)) { 325 if ((json_object_object_get_ex(metric, "light", &setpoint)) && (unit->mode == UNITMODE_NONE)) {
321 if (json_object_object_get_ex(setpoint, "state", &val)) { 326 if (json_object_object_get_ex(setpoint, "state", &val)) {
322 if (json_object_get_int(val) != unit->light_state) { 327 if (json_object_get_int(val) != unit->light_state) {
323 unit->light_state = json_object_get_int(val); 328 unit->light_state = json_object_get_int(val);
324 unit->mqtt_flag |= MQTT_FLAG_DATA; 329 unit->mqtt_flag |= MQTT_FLAG_DATA;
325 syslog(LOG_NOTICE, "DCMD change fermenter %s: light_state to %d", message_alias, unit->light_state); 330 syslog(LOG_NOTICE, "DCMD change fermenter %s: light_state to %d", message_alias, unit->light_state);
326 } 331 }
327 } 332 }
328 } 333 }
329 printf("start product\n"); 334
330 if ((json_object_object_get_ex(metric, "product", &setpoint)) && (unit->mode == UNITMODE_OFF)) { 335 if ((json_object_object_get_ex(metric, "product", &setpoint)) && (unit->mode == UNITMODE_OFF)) {
331 if (json_object_object_get_ex(setpoint, "code", &val)) { 336 if (json_object_object_get_ex(setpoint, "code", &val)) {
332 if (strcmp((char *)json_object_get_string(val), unit->product_code)) { 337 if (strcmp((char *)json_object_get_string(val), unit->product_code)) {
333 free(unit->product_code); 338 free(unit->product_code);
334 unit->product_code = xstrcpy((char *)json_object_get_string(val)); 339 unit->product_code = xstrcpy((char *)json_object_get_string(val));
343 unit->mqtt_flag |= MQTT_FLAG_DATA; 348 unit->mqtt_flag |= MQTT_FLAG_DATA;
344 syslog(LOG_NOTICE, "DCMD change fermenter %s: product_name to `%s'", message_alias, unit->product_name); 349 syslog(LOG_NOTICE, "DCMD change fermenter %s: product_name to `%s'", message_alias, unit->product_name);
345 } 350 }
346 } 351 }
347 } 352 }
353
354 if (json_object_object_get_ex(metric, "profile", &profile)) {
355 if (json_object_object_get_ex(profile, "command", &profile1)) {
356 syslog(LOG_NOTICE, "profile command");
357
358 } else if (json_object_object_get_ex(profile, "uuid", &profile1)) {
359 // syslog(LOG_NOTICE, "profile new profile");
360 if ((unit->prof_state == PROFILE_OFF) || (unit->prof_state == PROFILE_DONE) || (unit->prof_state == PROFILE_ABORT)) {
361 if (unit->profile_uuid)
362 free(unit->profile_uuid);
363 if (unit->profile_name)
364 free(unit->profile_name);
365 if (unit->profile_steps) {
366 for (step = unit->profile_steps; step; step = oldstep) {
367 if (step->name)
368 free(step->name);
369 oldstep = step->next;
370 free(step);
371 }
372 }
373 unit->profile_steps = NULL;
374 unit->profile_duration = unit->profile_totalsteps = 0;
375 // syslog(LOG_NOTICE, "profile new profile: old cleared");
376
377 unit->profile_uuid = xstrcpy((char *)json_object_get_string(profile1));
378 if (json_object_object_get_ex(profile, "name", &val)) {
379 unit->profile_name = xstrcpy((char *)json_object_get_string(val));
380 }
381 if (json_object_object_get_ex(profile, "inittemp", &setpoint)) {
382 if (json_object_object_get_ex(setpoint, "low", &val)) {
383 unit->profile_inittemp_lo = json_object_get_double(val);
384 }
385 if (json_object_object_get_ex(setpoint, "high", &val)) {
386 unit->profile_inittemp_hi = json_object_get_double(val);
387 }
388 }
389 if (json_object_object_get_ex(profile, "fridgemode", &val)) {
390 unit->profile_fridge_mode = json_object_get_int(val);
391 if (unit->profile_fridge_mode)
392 unit->profile_fridge_mode = 100;
393 }
394 if (json_object_object_get_ex(profile, "steps", &steps)) {
395 int arraylen = json_object_array_length(steps);
396 syslog(LOG_NOTICE, "profile new profile: start %d steps", arraylen);
397 for (int i = 0; i < arraylen; i++) {
398 /*
399 * Parse the array of steps
400 */
401 step1 = json_object_array_get_idx(steps, i);
402 unit->profile_totalsteps++;
403
404 step = (prof_step *)malloc(sizeof(prof_step));
405 step->next = NULL;
406 step->name = NULL;
407 step->steptime = step->resttime = step->fridge_mode = 0;
408 step->target_lo = step->target_hi = 20.0;
409
410 if (json_object_object_get_ex(step1, "name", &val)) {
411 step->name = xstrcpy((char *)json_object_get_string(val));
412 }
413 if (json_object_object_get_ex(step1, "steptime", &val)) {
414 step->steptime = json_object_get_int(val);
415 unit->profile_duration += step->steptime;
416 }
417 if (json_object_object_get_ex(step1, "resttime", &val)) {
418 step->resttime = json_object_get_int(val);
419 unit->profile_duration += step->resttime;
420 }
421 if (json_object_object_get_ex(step1, "fridgemode", &val)) {
422 step->fridge_mode = json_object_get_int(val);
423 if (step->fridge_mode)
424 step->fridge_mode = 100;
425 }
426 if (json_object_object_get_ex(step1, "target_lo", &val)) {
427 step->target_lo = json_object_get_double(val);
428 }
429 if (json_object_object_get_ex(step1, "target_hi", &val)) {
430 step->target_hi = json_object_get_double(val);
431 }
432
433 syslog(LOG_NOTICE, "profile new profile: add step %d", unit->profile_totalsteps);
434 if (unit->profile_steps == NULL) {
435 unit->profile_steps = step;
436 } else {
437 for (oldstep = unit->profile_steps; oldstep; oldstep = oldstep->next) {
438 if (oldstep->next == NULL) {
439 oldstep->next = step;
440 break;
441 }
442 }
443 }
444 }
445 }
446 unit->mqtt_flag |= MQTT_FLAG_DATA;
447 syslog(LOG_NOTICE, "DCMD change fermenter %s: install profile `%s'", message_alias, unit->profile_name);
448 wrconfig();
449 }
450 } else {
451 if ((unit->prof_state == PROFILE_OFF) || (unit->prof_state == PROFILE_DONE) || (unit->prof_state == PROFILE_ABORT)) {
452 syslog(LOG_NOTICE, "DCMD change fermenter %s: delete profile `%s'", message_alias, unit->profile_name);
453 if (unit->profile_uuid)
454 free(unit->profile_uuid);
455 if (unit->profile_name)
456 free(unit->profile_name);
457 unit->profile_uuid = unit->profile_name = NULL;
458 if (unit->profile_steps) {
459 for (step = unit->profile_steps; step; step = oldstep) {
460 if (step->name)
461 free(step->name);
462 oldstep = step->next;
463 free(step);
464 }
465 }
466 unit->profile_steps = NULL;
467 unit->profile_inittemp_lo = unit->profile_inittemp_hi = 20.0;
468 unit->prof_percent = unit->profile_fridge_mode = 0;
469 unit->prof_state = PROFILE_OFF;
470 unit->profile_duration = unit->profile_totalsteps = 0;
471 unit->prof_started = unit->prof_paused = unit->prof_primary_done = (time_t)0;
472 unit->prof_peak_abs = unit->prof_peak_rel = 0.0;
473 unit->mqtt_flag |= MQTT_FLAG_DATA;
474 wrconfig();
475 }
476 }
477 }
348 } 478 }
479
349 if (unit->mqtt_flag) { 480 if (unit->mqtt_flag) {
350 printf("do mqtt flag\n");
351 if (debug)
352 fprintf(stdout, "flag value %d\n", unit->mqtt_flag);
353 if (unit->mqtt_flag & MQTT_FLAG_BIRTH) { 481 if (unit->mqtt_flag & MQTT_FLAG_BIRTH) {
354 publishDBirth(unit); 482 publishDBirth(unit);
355 } else { 483 } else {
356 publishDData(unit); 484 publishDData(unit);
357 } 485 }
358 if (unit->mqtt_flag & MQTT_FLAG_DEATH) { 486 if (unit->mqtt_flag & MQTT_FLAG_DEATH) {
359 publishDDeath(unit); 487 publishDDeath(unit);
360 } 488 }
361 unit->mqtt_flag |= MQTT_FLAG_DLOG; // Something to log 489 unit->mqtt_flag |= MQTT_FLAG_DLOG; // Something to log
362 } 490 }
363 printf("einde unit %s\n", unit->alias);
364 } 491 }
365 printf("return\n");
366 return; 492 return;
367 } 493 }
368 printf("metric: %s\n", (char *)json_object_get_string(metric));
369 syslog(LOG_NOTICE, "MQTT: %s payload not understood\n", (char *)message->payload); 494 syslog(LOG_NOTICE, "MQTT: %s payload not understood\n", (char *)message->payload);
370 return; 495 return;
371 } 496 }
372 } else { 497 } else {
373 syslog(LOG_NOTICE, "MQTT: got payload with timestamp %d seconds error", timediff); 498 syslog(LOG_NOTICE, "MQTT: got payload with timestamp %d seconds error", timediff);
445 char *unit_data(units_list *unit, bool birth) 570 char *unit_data(units_list *unit, bool birth)
446 { 571 {
447 char *payload = NULL; 572 char *payload = NULL;
448 char buf[128]; 573 char buf[128];
449 bool comma = false; 574 bool comma = false;
450 profiles_list *profile;
451 prof_step *pstep; 575 prof_step *pstep;
452 576
453 payload = xstrcpy((char *)"{"); 577 payload = xstrcpy((char *)"{");
454 578
455 /* 579 /*
616 */ 740 */
617 if (unit->door_address) { 741 if (unit->door_address) {
618 payload = xstrcat(payload, (char *)",\"door\":{\"address\":\""); 742 payload = xstrcat(payload, (char *)",\"door\":{\"address\":\"");
619 payload = xstrcat(payload, unit->door_address); 743 payload = xstrcat(payload, unit->door_address);
620 payload = xstrcat(payload, (char *)"\",\"state\":"); 744 payload = xstrcat(payload, (char *)"\",\"state\":");
621 sprintf(buf, "%d", unit->door_state); 745 sprintf(buf, "%d", (unit->door_state) ? 0:1);
622 payload = xstrcat(payload, buf); 746 payload = xstrcat(payload, buf);
623 payload = xstrcat(payload, (char *)"}"); 747 payload = xstrcat(payload, (char *)"}");
624 } else { 748 } else {
625 payload = xstrcat(payload, (char *)",\"door\":null"); 749 payload = xstrcat(payload, (char *)",\"door\":null");
626 } 750 }
657 payload = xstrcat(payload, buf); 781 payload = xstrcat(payload, buf);
658 782
659 /* 783 /*
660 * Loaded profile and state 784 * Loaded profile and state
661 */ 785 */
662 if (unit->profile) { 786 if (unit->profile_uuid) {
663 for (profile = Config.profiles; profile; profile = profile->next) { 787 payload = xstrcat(payload, (char *)",\"profile\":{\"uuid\":\"");
664 if (strcmp(unit->profile, profile->uuid) == 0) { 788 payload = xstrcat(payload, unit->profile_uuid);
665 payload = xstrcat(payload, (char *)",\"profile\":{\"uuid\":\""); 789 payload = xstrcat(payload, (char *)"\",\"name\":\"");
666 payload = xstrcat(payload, unit->profile); 790 payload = xstrcat(payload, unit->profile_name);
667 payload = xstrcat(payload, (char *)"\",\"name\":\""); 791 payload = xstrcat(payload, (char *)"\",\"state\":\"");
668 payload = xstrcat(payload, profile->name); 792 payload = xstrcat(payload, (char *)PROFSTATE[unit->prof_state]);
669 payload = xstrcat(payload, (char *)"\",\"state\":\""); 793 payload = xstrcat(payload, (char *)"\",\"percent\":");
670 payload = xstrcat(payload, (char *)PROFSTATE[unit->prof_state]); 794 sprintf(buf, "%d", unit->prof_percent);
671 payload = xstrcat(payload, (char *)"\",\"percent\":"); 795 payload = xstrcat(payload, buf);
672 sprintf(buf, "%d", unit->prof_percent); 796 payload = xstrcat(payload, (char *)",\"inittemp\":{\"low\":");
797 sprintf(buf, "%.1f", unit->profile_inittemp_lo);
798 payload = xstrcat(payload, buf);
799 payload = xstrcat(payload, (char *)",\"high\":");
800 sprintf(buf, "%.1f", unit->profile_inittemp_hi);
801 payload = xstrcat(payload, buf);
802 payload = xstrcat(payload, (char *)"},\"fridgemode\":");
803 sprintf(buf, "%d", unit->profile_fridge_mode);
804 payload = xstrcat(payload, buf);
805 comma = false;
806 if (unit->profile_steps) {
807 payload = xstrcat(payload, (char *)",\"steps\":[");
808 for (pstep = unit->profile_steps; pstep; pstep = pstep->next) {
809 if (comma)
810 payload = xstrcat(payload, (char *)",");
811 payload = xstrcat(payload, (char *)"{\"resttime\":");
812 sprintf(buf, "%d", pstep->resttime);
673 payload = xstrcat(payload, buf); 813 payload = xstrcat(payload, buf);
674 payload = xstrcat(payload, (char *)",\"inittemp\":{\"low\":"); 814 payload = xstrcat(payload, (char *)",\"steptime\":");
675 sprintf(buf, "%.1f", profile->inittemp_lo); 815 sprintf(buf, "%d", pstep->steptime);
816 payload = xstrcat(payload, buf);
817 payload = xstrcat(payload, (char *)",\"target\":{\"low\":");
818 sprintf(buf, "%.1f", pstep->target_lo);
676 payload = xstrcat(payload, buf); 819 payload = xstrcat(payload, buf);
677 payload = xstrcat(payload, (char *)",\"high\":"); 820 payload = xstrcat(payload, (char *)",\"high\":");
678 sprintf(buf, "%.1f", profile->inittemp_hi); 821 sprintf(buf, "%.1f", pstep->target_hi);
679 payload = xstrcat(payload, buf); 822 payload = xstrcat(payload, buf);
680 payload = xstrcat(payload, (char *)"},\"fridgemode\":"); 823 payload = xstrcat(payload, (char *)"},\"fridgemode\":");
681 sprintf(buf, "%d", profile->fridge_mode); 824 sprintf(buf, "%d", pstep->fridge_mode);
682 payload = xstrcat(payload, buf); 825 payload = xstrcat(payload, buf);
683 comma = false; 826 if (pstep->name) {
684 if (profile->steps) { 827 payload = xstrcat(payload, (char *)",\"name\":\"");
685 payload = xstrcat(payload, (char *)",\"steps\":["); 828 payload = xstrcat(payload, pstep->name);
686 for (pstep = profile->steps; pstep; pstep = pstep->next) { 829 payload = xstrcat(payload, (char *)"\"");
687 if (comma)
688 payload = xstrcat(payload, (char *)",");
689 payload = xstrcat(payload, (char *)"{\"resttime\":");
690 sprintf(buf, "%d", pstep->resttime);
691 payload = xstrcat(payload, buf);
692 payload = xstrcat(payload, (char *)",\"steptime\":");
693 sprintf(buf, "%d", pstep->steptime);
694 payload = xstrcat(payload, buf);
695 payload = xstrcat(payload, (char *)",\"target\":{\"low\":");
696 sprintf(buf, "%.1f", pstep->target_lo);
697 payload = xstrcat(payload, buf);
698 payload = xstrcat(payload, (char *)",\"high\":");
699 sprintf(buf, "%.1f", pstep->target_hi);
700 payload = xstrcat(payload, buf);
701 payload = xstrcat(payload, (char *)"},\"fridgemode\":");
702 sprintf(buf, "%d", pstep->fridge_mode);
703 payload = xstrcat(payload, buf);
704 payload = xstrcat(payload, (char *)"}");
705 comma = true;
706 }
707 payload = xstrcat(payload, (char *)"]");
708 } else {
709 payload = xstrcat(payload, (char *)",\"steps\":null");
710 } 830 }
711 payload = xstrcat(payload, (char *)"}"); 831 payload = xstrcat(payload, (char *)"}");
712 break; 832 comma = true;
713 } 833 }
714 } 834 payload = xstrcat(payload, (char *)"]");
835 } else {
836 payload = xstrcat(payload, (char *)",\"steps\":null");
837 }
838 payload = xstrcat(payload, (char *)"}");
715 } else { 839 } else {
716 payload = xstrcat(payload, (char *)",\"profile\":null"); 840 payload = xstrcat(payload, (char *)",\"profile\":null");
717 } 841 }
718 payload = xstrcat(payload, (char *)"}"); 842 payload = xstrcat(payload, (char *)"}");
719 843

mercurial