thermferm/thermferm.c

changeset 219
ae720212accc
parent 215
5ad534c79a22
child 221
91a5e7281c35
equal deleted inserted replaced
218:311a293b3e46 219:ae720212accc
341 struct tm *tm; 341 struct tm *tm;
342 int row, key; 342 int row, key;
343 #else 343 #else
344 long t = 0; 344 long t = 0;
345 #endif 345 #endif
346 int current_step, time_in_step, time_until_now;
347 float previous_target;
346 348
347 if (lockprog((char *)"thermferm")) { 349 if (lockprog((char *)"thermferm")) {
348 syslog(LOG_NOTICE, "Can't lock"); 350 syslog(LOG_NOTICE, "Can't lock");
349 return 1; 351 return 1;
350 } 352 }
398 /* 400 /*
399 * Safety, turn everything off 401 * Safety, turn everything off
400 */ 402 */
401 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = 0; 403 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = 0;
402 if (unit->mode == UNITMODE_PROFILE) { 404 if (unit->mode == UNITMODE_PROFILE) {
403 if (unit->profile) 405 if (!unit->profile)
404 syslog(LOG_NOTICE, "Starting unit %s in profile mode, no profile defined.", unit->name); 406 syslog(LOG_NOTICE, "Starting unit %s in profile mode, no profile defined.", unit->name);
405 else 407 else
406 syslog(LOG_NOTICE, "Starting unit %s in profile state %s. Target %.1f degrees", unit->name, PROFSTATE[unit->prof_state], unit->prof_target); 408 syslog(LOG_NOTICE, "Starting unit %s in profile state %s.", unit->name, PROFSTATE[unit->prof_state]);
407 } else if (unit->mode == UNITMODE_BEER) { 409 } else if (unit->mode == UNITMODE_BEER) {
408 syslog(LOG_NOTICE, "Starting unit %s beer cooler at %.1f degrees", unit->name, unit->beer_set); 410 syslog(LOG_NOTICE, "Starting unit %s beer cooler at %.1f degrees", unit->name, unit->beer_set);
409 } else if (unit->mode == UNITMODE_FRIDGE) { 411 } else if (unit->mode == UNITMODE_FRIDGE) {
410 syslog(LOG_NOTICE, "Starting unit %s as refridgerator at %.1f degrees", unit->name, unit->fridge_set); 412 syslog(LOG_NOTICE, "Starting unit %s as refridgerator at %.1f degrees", unit->name, unit->fridge_set);
411 } else if (unit->mode == UNITMODE_NONE) { 413 } else if (unit->mode == UNITMODE_NONE) {
549 * unit->prof_target - Calculated target temperature. 551 * unit->prof_target - Calculated target temperature.
550 * unit->prof_paused - Internal pause counter. 552 * unit->prof_paused - Internal pause counter.
551 */ 553 */
552 for (profile = Config.profiles; profile; profile = profile->next) { 554 for (profile = Config.profiles; profile; profile = profile->next) {
553 if (strcmp(unit->profile, profile->uuid) == 0) { 555 if (strcmp(unit->profile, profile->uuid) == 0) {
554 /* 556
555 * Set initial temperature for this profile.
556 */
557 switch (unit->prof_state) { 557 switch (unit->prof_state) {
558 case PROFILE_OFF: 558 case PROFILE_OFF:
559 /* 559 unit->prof_target = profile->inittemp;
560 * Setup initial temperature.
561 */
562 unit->prof_target = profile->inittemp;
563 break; 560 break;
564 case PROFILE_PAUSE: 561 case PROFILE_PAUSE:
565 /* 562 /*
566 * Keep current temperature, measure pause time. 563 * Keep current temperature, measure pause time. For
564 * temperature fall thru.
567 */ 565 */
568 break; 566 unit->prof_paused++;
569 case PROFILE_RUN: 567 case PROFILE_RUN:
570 /* 568 /*
571 * Calculate current profile step en desired temperature. 569 * Calculate current profile step en desired temperature.
572 * When all done, set state to PROFILE_DONE. 570 * When all done, set state to PROFILE_DONE.
573 */ 571 */
572 previous_target = profile->inittemp;
573 time_until_now = 0;
574 current_step = 0;
574 run_seconds = (int)(now - unit->prof_started - unit->prof_paused); 575 run_seconds = (int)(now - unit->prof_started - unit->prof_paused);
575 run_minutes = run_seconds / 60; 576 run_minutes = run_seconds / 60;
576 run_hours = run_minutes / 60; 577 run_hours = run_minutes / 60;
577 if (debug) 578 if (debug)
578 fprintf(stdout, "run_hours=%d minutes=%d seconds=%d\n", run_hours, run_minutes, run_seconds); 579 fprintf(stdout, "run_hours=%d minutes=%d seconds=%d ", run_hours, run_minutes, run_seconds);
579 580
580 for (step = profile->steps; step; step = step->next) { 581 for (step = profile->steps; step; step = step->next) {
582
583 if (step->steptime == 0) {
584 unit->prof_state = PROFILE_DONE;
585 syslog(LOG_NOTICE, "Profile is done");
586 break;
587 }
588
589 /*
590 * step->steptime
591 * step->resttime
592 * step->target
593 */
594 time_in_step = step->steptime + step->resttime;
595 current_step++;
596 if ((run_hours >= time_until_now) && (run_hours < (time_until_now + time_in_step))) {
597 /*
598 * This is our current step
599 */
600 if (debug)
601 fprintf(stdout, "step=%d step_pos=%d step_length=%d steptime=%d resttime=%d target=%.1f ",
602 current_step, run_hours - time_until_now, time_in_step, step->steptime, step->resttime, step->target);
603 if ((run_hours - time_until_now) < step->steptime) {
604 unit->prof_target = previous_target + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target - previous_target));
605 if (debug)
606 fprintf(stdout, "tempshift=%.1f minutes=%d duration=%d temp_move=%.3f ",
607 step->target - previous_target, run_minutes - (time_until_now * 60),
608 step->steptime * 60,
609 previous_target + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target - previous_target))
610 );
611 } else {
612 unit->prof_target = step->target;
613 fprintf(stdout, "resting target=%.1f ", step->target);
614 }
615 break;
616 }
617 time_until_now += time_in_step;
618 previous_target = step->target;
581 } 619 }
620 if (debug)
621 fprintf(stdout, "\n");
582 break; 622 break;
583 case PROFILE_DONE: 623 case PROFILE_DONE:
584 /* 624 /*
585 * Keep this state. 625 * Keep this state, set target temperature to the last step.
586 */ 626 */
627 previous_target = profile->inittemp;
628 for (step = profile->steps; step; step = step->next) {
629 if (step->steptime == 0)
630 break;
631 previous_target = step->target;
632 }
633 unit->prof_target = previous_target;
587 break; 634 break;
588 } /* switch */ 635 } /* switch */
589 } 636 }
590 } 637 }
591 } 638 }
597 device_out(unit->heater_address, unit->heater_state); 644 device_out(unit->heater_address, unit->heater_state);
598 device_out(unit->cooler_address, unit->cooler_state); 645 device_out(unit->cooler_address, unit->cooler_state);
599 device_out(unit->fan_address, unit->fan_state); 646 device_out(unit->fan_address, unit->fan_state);
600 } 647 }
601 #ifdef HAVE_WIRINGPI_H 648 #ifdef HAVE_WIRINGPI_H
602 if (unit->heater_address) { 649 if (unit->heater_address && unit->cooler_address) {
603 lcd_buf_write(row++, "Heater %s ", unit->heater_state ? "On ":"Off"); 650 if (unit->heater_state)
604 } 651 lcd_buf_write(row++, "Heater On ");
605 if (unit->cooler_address) { 652 else if (unit->cooler_state)
606 lcd_buf_write(row++, "Cooler %s ", unit->cooler_state ? "On ":"Off"); 653 lcd_buf_write(row++, "Cooler On ");
654 else
655 lcd_buf_write(row++, "Standby ");
656 switch (unit->mode) {
657 case UNITMODE_BEER: lcd_buf_write(row++, "Target %.1f %cC ", unit->beer_set, 0xdf);
658 break;
659 case UNITMODE_FRIDGE: lcd_buf_write(row++, "Target %.1f %cC ", unit->fridge_set, 0xdf);
660 break;
661 case UNITMODE_PROFILE: if (unit->prof_state != PROFILE_OFF)
662 lcd_buf_write(row++, "Target %.1f %cC ", unit->prof_target, 0xdf);
663 else
664 lcd_buf_write(row++, "Target not set ");
665 break;
666 default: lcd_buf_write(row++, "Target not set ");
667 }
668 } else {
669 if (unit->heater_address) {
670 lcd_buf_write(row++, "Heat %s ", unit->heater_state ? "On ":"Off");
671 }
672 if (unit->cooler_address) {
673 lcd_buf_write(row++, "Cool %s ", unit->cooler_state ? "On ":"Off");
674 }
607 } 675 }
608 #endif 676 #endif
609 } 677 }
610 678
611 piddelay++; 679 piddelay++;

mercurial