149 unit->next = NULL; |
148 unit->next = NULL; |
150 unit->version = 1; |
149 unit->version = 1; |
151 unit->uuid = malloc(37); |
150 unit->uuid = malloc(37); |
152 uuid_generate(uu); |
151 uuid_generate(uu); |
153 uuid_unparse(uu, unit->uuid); |
152 uuid_unparse(uu, unit->uuid); |
|
153 if (current_unit) |
|
154 free(current_unit); |
|
155 current_unit = xstrcpy(unit->uuid); |
154 unit->name = xstrcpy(param); |
156 unit->name = xstrcpy(param); |
155 unit->air_address = unit->beer_address = unit->io1_address = unit->io2_address = unit->profile = NULL; |
157 unit->air_address = unit->beer_address = unit->io1_address = unit->io2_address = unit->profile = NULL; |
156 unit->volume = 0.0; |
158 unit->volume = 0.0; |
157 unit->air_state = unit->beer_state = 1; |
159 unit->air_state = unit->beer_state = 1; |
158 unit->heater_available = unit->cooler_available = unit->fan_available = FALSE; |
160 unit->heater_available = unit->cooler_available = unit->fan_available = FALSE; |
167 |
169 |
168 if (Config.units == NULL) { |
170 if (Config.units == NULL) { |
169 Config.units = unit; |
171 Config.units = unit; |
170 } else { |
172 } else { |
171 for (tmpu = Config.units; tmpu; tmpu = tmpu->next) { |
173 for (tmpu = Config.units; tmpu; tmpu = tmpu->next) { |
172 id++; |
|
173 if (tmpu->next == NULL) { |
174 if (tmpu->next == NULL) { |
174 tmpu->next = unit; |
175 tmpu->next = unit; |
175 break; |
176 break; |
176 } |
177 } |
177 } |
178 } |
178 } |
179 } |
179 |
180 |
180 syslog(LOG_NOTICE, "Unit %d with uuid %s added", id, unit->uuid); |
181 syslog(LOG_NOTICE, "Unit with uuid %s added", unit->uuid); |
181 srv_send((char *)"211 Unit %d with uuid %s added", id, unit->uuid); |
182 srv_send((char *)"211 Unit with uuid %s added", unit->uuid); |
182 current_unit = id; |
|
183 return 0; |
183 return 0; |
184 } |
184 } |
185 |
185 |
186 srv_send((char *)"502 Unknown command option"); |
186 srv_send((char *)"502 Unknown command option"); |
187 return 1; |
187 return 1; |
213 if (opt == NULL) { |
213 if (opt == NULL) { |
214 /* |
214 /* |
215 * Default, list available units |
215 * Default, list available units |
216 */ |
216 */ |
217 srv_send((char *)"212 Fermenter list follows:"); |
217 srv_send((char *)"212 Fermenter list follows:"); |
218 i = 0; |
|
219 for (unit = Config.units; unit; unit = unit->next) { |
218 for (unit = Config.units; unit; unit = unit->next) { |
220 i++; |
219 srv_send((char *)"%s,%s,%s", unit->uuid, unit->name, UNITMODE[unit->mode]); |
221 srv_send((char *)"%d,%s,%s,%s", i, unit->uuid, unit->name, UNITMODE[unit->mode]); |
|
222 } |
220 } |
223 srv_send((char *)"."); |
221 srv_send((char *)"."); |
224 return 0; |
222 return 0; |
225 |
223 |
226 } else if (strcmp(opt, (char *)"BUS") == 0) { |
224 } else if (strcmp(opt, (char *)"BUS") == 0) { |
285 |
283 |
286 } else if (strcmp(opt, (char *)"LOG") == 0) { |
284 } else if (strcmp(opt, (char *)"LOG") == 0) { |
287 /* |
285 /* |
288 * Get the logfile data and emit only one line per hour. |
286 * Get the logfile data and emit only one line per hour. |
289 */ |
287 */ |
290 if (current_unit == -1) { |
288 if (current_unit == NULL) { |
291 srv_send((char *)"401 No fermenter unit selected"); |
289 srv_send((char *)"401 No fermenter unit selected"); |
292 return 1; |
290 return 1; |
293 } |
291 } |
294 |
292 |
295 i = 0; |
|
296 q[0] = q[1] = 'a'; |
293 q[0] = q[1] = 'a'; |
297 for (unit = Config.units; unit; unit = unit->next) { |
294 for (unit = Config.units; unit; unit = unit->next) { |
298 i++; |
295 if (strcmp(current_unit, unit->uuid) == 0) |
299 if (i == current_unit) |
|
300 break; |
296 break; |
301 } |
297 } |
302 |
298 |
303 srv_send((char *)"212 Logfile list follows:"); |
299 srv_send((char *)"212 Logfile list follows:"); |
304 if (getenv((char *)"USER") == NULL) { |
300 if (getenv((char *)"USER") == NULL) { |
330 } else if (strcmp(opt, (char *)"PROFILES") == 0) { |
326 } else if (strcmp(opt, (char *)"PROFILES") == 0) { |
331 /* |
327 /* |
332 * Fermenting profiles |
328 * Fermenting profiles |
333 */ |
329 */ |
334 srv_send((char *)"212 profiles:"); |
330 srv_send((char *)"212 profiles:"); |
335 i = 0; |
|
336 for (profile = Config.profiles; profile; profile = profile->next) { |
331 for (profile = Config.profiles; profile; profile = profile->next) { |
337 i++; |
|
338 j = 0; |
332 j = 0; |
339 for (step = profile->steps; step; step = step->next) |
333 for (step = profile->steps; step; step = step->next) |
340 j++; |
334 j++; |
341 srv_send((char *)"%d,%s,%s,%d", i, profile->uuid, profile->name, j); |
335 srv_send((char *)"%s,%s,%d", profile->uuid, profile->name, j); |
342 } |
336 } |
343 srv_send((char *)"."); |
337 srv_send((char *)"."); |
344 return 0; |
338 return 0; |
345 |
339 |
346 } else if (strcmp(opt, (char *)"UNIT") == 0) { |
340 } else if (strcmp(opt, (char *)"UNIT") == 0) { |
347 /* |
341 /* |
348 * List configured and selected fermenter unit |
342 * List configured and selected fermenter unit |
349 */ |
343 */ |
350 if (current_unit == -1) { |
344 if (current_unit == NULL) { |
351 srv_send((char *)"401 No fermenter unit selected"); |
345 srv_send((char *)"401 No fermenter unit selected"); |
352 return 1; |
346 return 1; |
353 } |
347 } |
354 |
348 |
355 srv_send((char *)"213 Unit %d listing follows:", current_unit); |
349 srv_send((char *)"213 Unit %s listing follows:", current_unit); |
356 i = 0; |
|
357 for (unit = Config.units; unit; unit = unit->next) { |
350 for (unit = Config.units; unit; unit = unit->next) { |
358 i++; |
351 if (strcmp(current_unit, unit->uuid) == 0) { |
359 if (i == current_unit) { |
|
360 srv_send((char *)"NAME,%s", unit->name); |
352 srv_send((char *)"NAME,%s", unit->name); |
361 srv_send((char *)"UUID,%s", unit->uuid); |
353 srv_send((char *)"UUID,%s", unit->uuid); |
362 if (unit->air_address) { |
354 if (unit->air_address) { |
363 srv_send((char *)"AIR_ADDRESS,%s", unit->air_address); |
355 srv_send((char *)"AIR_ADDRESS,%s", unit->air_address); |
364 srv_send((char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]); |
356 srv_send((char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]); |
454 fprintf(stdout, "opt='%s' param='%s' rc=%d fval=%.1f\n", opt, param, rc, fval); |
446 fprintf(stdout, "opt='%s' param='%s' rc=%d fval=%.1f\n", opt, param, rc, fval); |
455 |
447 |
456 /* |
448 /* |
457 * Commands below need a selected unit |
449 * Commands below need a selected unit |
458 */ |
450 */ |
459 if (current_unit == -1) { |
451 if (current_unit == NULL) { |
460 srv_send((char *)"401 No fermenter unit selected"); |
452 srv_send((char *)"401 No fermenter unit selected"); |
461 return 1; |
453 return 1; |
462 } |
454 } |
463 |
455 |
464 i = 0; |
|
465 for (unit = Config.units; unit; unit = unit->next) { |
456 for (unit = Config.units; unit; unit = unit->next) { |
466 i++; |
457 if (strcmp(current_unit, unit->uuid) == 0) |
467 if (i == current_unit) |
|
468 break; |
458 break; |
469 } |
459 } |
470 |
460 |
471 /* |
461 /* |
472 * If a valid parameter float value |
462 * If a valid parameter float value |
473 */ |
463 */ |
474 if (rc == 1) { |
464 if (rc == 1) { |
475 if (strcmp(opt, (char *)"BEER") == 0) { |
465 if (strcmp(opt, (char *)"BEER") == 0) { |
476 if ((fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) { |
466 if ((fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) { |
477 unit->beer_set = fval; |
467 unit->beer_set = fval; |
478 srv_send((char *)"214 Unit %d BEER set to %.1f", current_unit, fval); |
468 srv_send((char *)"214 Unit %s BEER set to %.1f", current_unit, fval); |
479 return 0; |
469 return 0; |
480 } else { |
470 } else { |
481 srv_send((char *)"510 New temperature not between %.1f and %.1f", unit->temp_set_min, unit->temp_set_max); |
471 srv_send((char *)"510 New temperature not between %.1f and %.1f", unit->temp_set_min, unit->temp_set_max); |
482 return 1; |
472 return 1; |
483 } |
473 } |
484 } else if (strcmp(opt, (char *)"FRIDGE") == 0) { |
474 } else if (strcmp(opt, (char *)"FRIDGE") == 0) { |
485 if ((fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) { |
475 if ((fval >= unit->temp_set_min) && (fval <= unit->temp_set_max)) { |
486 unit->fridge_set = fval; |
476 unit->fridge_set = fval; |
487 srv_send((char *)"214 Unit %d BEER set to %.1f", current_unit, fval); |
477 srv_send((char *)"214 Unit %s BEER set to %.1f", current_unit, fval); |
488 return 0; |
478 return 0; |
489 } else { |
479 } else { |
490 srv_send((char *)"510 New temperature not between %.1f and %.1f", unit->temp_set_min, unit->temp_set_max); |
480 srv_send((char *)"510 New temperature not between %.1f and %.1f", unit->temp_set_min, unit->temp_set_max); |
491 return 1; |
481 return 1; |
492 } |
482 } |
494 /* |
484 /* |
495 * Must fit in a 2 TEU container |
485 * Must fit in a 2 TEU container |
496 */ |
486 */ |
497 if ((fval >= 0.0) && (fval <= 77020.0)) { |
487 if ((fval >= 0.0) && (fval <= 77020.0)) { |
498 unit->volume = fval; |
488 unit->volume = fval; |
499 srv_send((char *)"214 Unit %d VOLUME set to %.1f", current_unit, fval); |
489 srv_send((char *)"214 Unit %s VOLUME set to %.1f", current_unit, fval); |
500 return 0; |
490 return 0; |
501 } else { |
491 } else { |
502 srv_send((char *)"510 New volume not between 0 and 77020"); |
492 srv_send((char *)"510 New volume not between 0 and 77020"); |
503 return 1; |
493 return 1; |
504 } |
494 } |
505 } else if (strcmp(opt, (char *)"IDLE_LOW") == 0) { |
495 } else if (strcmp(opt, (char *)"IDLE_LOW") == 0) { |
506 if ((fval >= -5.0) && (fval <= -0.1)) { |
496 if ((fval >= -5.0) && (fval <= -0.1)) { |
507 unit->idle_rangeL = fval; |
497 unit->idle_rangeL = fval; |
508 srv_send((char *)"214 Unit %d IDLE_LOW set to %.1f", current_unit, fval); |
498 srv_send((char *)"214 Unit %s IDLE_LOW set to %.1f", current_unit, fval); |
509 return 0; |
499 return 0; |
510 } else { |
500 } else { |
511 srv_send((char *)"510 New value not between -5.0 and -0.1"); |
501 srv_send((char *)"510 New value not between -5.0 and -0.1"); |
512 return 1; |
502 return 1; |
513 } |
503 } |
514 } else if (strcmp(opt, (char *)"IDLE_HIGH") == 0) { |
504 } else if (strcmp(opt, (char *)"IDLE_HIGH") == 0) { |
515 if ((fval >= 0.1) && (fval <= 5.0)) { |
505 if ((fval >= 0.1) && (fval <= 5.0)) { |
516 unit->idle_rangeH = fval; |
506 unit->idle_rangeH = fval; |
517 srv_send((char *)"214 Unit %d IDLE_HIGH set to %.1f", current_unit, fval); |
507 srv_send((char *)"214 Unit %s IDLE_HIGH set to %.1f", current_unit, fval); |
518 return 0; |
508 return 0; |
519 } else { |
509 } else { |
520 srv_send((char *)"510 New value not between -5.0 and -0.1"); |
510 srv_send((char *)"510 New value not between -5.0 and -0.1"); |
521 return 1; |
511 return 1; |
522 } |
512 } |
523 } else if (strcmp(opt, (char *)"TEMP_MIN") == 0) { |
513 } else if (strcmp(opt, (char *)"TEMP_MIN") == 0) { |
524 if ((fval >= -2.0) && (fval <= 35.0) && (fval < unit->temp_set_max)) { |
514 if ((fval >= -2.0) && (fval <= 35.0) && (fval < unit->temp_set_max)) { |
525 unit->temp_set_min = fval; |
515 unit->temp_set_min = fval; |
526 srv_send((char *)"214 Unit %d TEMP_MIN set to %.1f", current_unit, fval); |
516 srv_send((char *)"214 Unit %s TEMP_MIN set to %.1f", current_unit, fval); |
527 return 0; |
517 return 0; |
528 } else { |
518 } else { |
529 srv_send((char *)"510 New value not between -2.0 and 35.0 and lower then TEMP_MAX"); |
519 srv_send((char *)"510 New value not between -2.0 and 35.0 and lower then TEMP_MAX"); |
530 return 1; |
520 return 1; |
531 } |
521 } |
532 } else if (strcmp(opt, (char *)"TEMP_MAX") == 0) { |
522 } else if (strcmp(opt, (char *)"TEMP_MAX") == 0) { |
533 if ((fval >= -2.0) && (fval <= 35.0) && (fval > unit->temp_set_min)) { |
523 if ((fval >= -2.0) && (fval <= 35.0) && (fval > unit->temp_set_min)) { |
534 unit->temp_set_max = fval; |
524 unit->temp_set_max = fval; |
535 srv_send((char *)"214 Unit %d TEMP_MAX set to %.1f", current_unit, fval); |
525 srv_send((char *)"214 Unit %s TEMP_MAX set to %.1f", current_unit, fval); |
536 return 0; |
526 return 0; |
537 } else { |
527 } else { |
538 srv_send((char *)"510 New value not between -2.0 and 35.0 and higher then TEMP_MIN"); |
528 srv_send((char *)"510 New value not between -2.0 and 35.0 and higher then TEMP_MIN"); |
539 return 1; |
529 return 1; |
540 } |
530 } |
546 */ |
536 */ |
547 if (strcmp(opt, (char *)"NAME") == 0) { |
537 if (strcmp(opt, (char *)"NAME") == 0) { |
548 if (unit->name) |
538 if (unit->name) |
549 free(unit->name); |
539 free(unit->name); |
550 unit->name = xstrcpy(param); |
540 unit->name = xstrcpy(param); |
551 srv_send((char *)"214 Unit %d NAME set to '%s'", current_unit, param); |
541 srv_send((char *)"214 Unit %s NAME set to '%s'", current_unit, param); |
552 // TODO: change logfile name |
542 // TODO: change logfile name |
553 return 0; |
543 return 0; |
554 } else if (strcmp(opt, (char *)"PROFILE") == 0) { |
544 } else if (strcmp(opt, (char *)"PROFILE") == 0) { |
555 // check profile file, excists, type, at least one profile item |
545 // check profile file, excists, type, at least one profile item |
556 } |
546 } |
560 } |
550 } |
561 |
551 |
562 |
552 |
563 |
553 |
564 /* |
554 /* |
565 * UNIT n |
|
566 * UNIT uuid |
555 * UNIT uuid |
567 */ |
556 */ |
568 int cmd_unit(char *buf) |
557 int cmd_unit(char *buf) |
569 { |
558 { |
570 char *opt; |
559 char *opt; |
571 units_list *tmp; |
560 units_list *tmp; |
572 int i, unit_no; |
|
573 |
561 |
574 opt = strtok(buf, " \0"); |
562 opt = strtok(buf, " \0"); |
575 opt = strtok(NULL, " \0"); |
563 opt = strtok(NULL, " \0"); |
576 |
564 |
577 if (opt == NULL) { |
565 if (opt == NULL) { |
578 srv_send((char *)"501 Parameter missing"); |
566 srv_send((char *)"501 Parameter missing"); |
579 return 1; |
567 return 1; |
580 } |
568 } |
581 |
569 |
582 i = 0; |
|
583 if (strlen(opt) == 36) { |
570 if (strlen(opt) == 36) { |
584 /* |
571 /* |
585 * Search using uuid |
572 * Search using uuid |
586 */ |
573 */ |
587 for (tmp = Config.units; tmp; tmp = tmp->next) { |
574 for (tmp = Config.units; tmp; tmp = tmp->next) { |
588 i++; |
|
589 if (strcmp(opt, tmp->uuid) == 0) { |
575 if (strcmp(opt, tmp->uuid) == 0) { |
590 srv_send((char *)"210 Unit %d selected", i); |
576 srv_send((char *)"210 Unit %s selected", tmp->uuid); |
591 current_unit = i; |
577 if (current_unit) |
592 return 0; |
578 free(current_unit); |
593 } |
579 current_unit = xstrcpy(tmp->uuid);; |
594 } |
|
595 srv_send((char *)"410 No such unit"); |
|
596 return 1; |
|
597 } |
|
598 |
|
599 if (sscanf(opt, "%d", &unit_no) == 1) { |
|
600 /* |
|
601 * We got a number, see if it is valid. |
|
602 */ |
|
603 for (tmp = Config.units; tmp; tmp = tmp->next) { |
|
604 i++; |
|
605 if (unit_no == i) { |
|
606 srv_send((char *)"210 Unit %d selected", i); |
|
607 current_unit = i; |
|
608 return 0; |
580 return 0; |
609 } |
581 } |
610 } |
582 } |
611 srv_send((char *)"410 No such unit"); |
583 srv_send((char *)"410 No such unit"); |
612 return 1; |
584 return 1; |
676 srv_send((char *)"SET BEER val Set beer temperature"); |
648 srv_send((char *)"SET BEER val Set beer temperature"); |
677 srv_send((char *)"SET FRIDGE val Set fridge temperature"); |
649 srv_send((char *)"SET FRIDGE val Set fridge temperature"); |
678 srv_send((char *)"SET IDLE_LOW val Set idle temperature low (-5.0 .. -0.1)"); |
650 srv_send((char *)"SET IDLE_LOW val Set idle temperature low (-5.0 .. -0.1)"); |
679 srv_send((char *)"SET IDLE_HIGH val Set idle temperature high (0.1 .. 5.0)"); |
651 srv_send((char *)"SET IDLE_HIGH val Set idle temperature high (0.1 .. 5.0)"); |
680 srv_send((char *)"SET NAME name Set name or beername for the unit"); |
652 srv_send((char *)"SET NAME name Set name or beername for the unit"); |
681 // srv_send((char *)"SET PROFILE name Set named profile"); |
653 // srv_send((char *)"SET PROFILE uuid,name Set named profile"); |
682 srv_send((char *)"SET TEMP_MIN val Set unit minimum temperature"); |
654 srv_send((char *)"SET TEMP_MIN val Set unit minimum temperature"); |
683 srv_send((char *)"SET TEMP_MAX val Set unit maximum temperature"); |
655 srv_send((char *)"SET TEMP_MAX val Set unit maximum temperature"); |
684 srv_send((char *)"SET VOLUME val Set unit volume"); |
656 srv_send((char *)"SET VOLUME val Set unit volume"); |
685 srv_send((char *)"UNIT n|uuid Select unit by number or uuid"); |
657 srv_send((char *)"UNIT uuid Select unit by uuid"); |
686 srv_send((char *)"."); |
658 srv_send((char *)"."); |
687 } else if (strncmp(buf, "LCD", 3) == 0) { |
659 } else if (strncmp(buf, "LCD", 3) == 0) { |
688 #ifdef HAVE_WIRINGPI_H |
660 #ifdef HAVE_WIRINGPI_H |
689 srv_send((char *)"201 information follows"); |
661 srv_send((char *)"201 information follows"); |
690 for (j = 0; j < 4; j++) { |
662 for (j = 0; j < 4; j++) { |