diff -r 311a293b3e46 -r ae720212accc thermferm/thermferm.c --- a/thermferm/thermferm.c Mon Aug 11 12:34:49 2014 +0200 +++ b/thermferm/thermferm.c Mon Aug 11 18:38:57 2014 +0200 @@ -343,6 +343,8 @@ #else long t = 0; #endif + int current_step, time_in_step, time_until_now; + float previous_target; if (lockprog((char *)"thermferm")) { syslog(LOG_NOTICE, "Can't lock"); @@ -400,10 +402,10 @@ */ unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = 0; if (unit->mode == UNITMODE_PROFILE) { - if (unit->profile) + if (!unit->profile) syslog(LOG_NOTICE, "Starting unit %s in profile mode, no profile defined.", unit->name); else - syslog(LOG_NOTICE, "Starting unit %s in profile state %s. Target %.1f degrees", unit->name, PROFSTATE[unit->prof_state], unit->prof_target); + syslog(LOG_NOTICE, "Starting unit %s in profile state %s.", unit->name, PROFSTATE[unit->prof_state]); } else if (unit->mode == UNITMODE_BEER) { syslog(LOG_NOTICE, "Starting unit %s beer cooler at %.1f degrees", unit->name, unit->beer_set); } else if (unit->mode == UNITMODE_FRIDGE) { @@ -551,39 +553,84 @@ */ for (profile = Config.profiles; profile; profile = profile->next) { if (strcmp(unit->profile, profile->uuid) == 0) { - /* - * Set initial temperature for this profile. - */ + switch (unit->prof_state) { case PROFILE_OFF: - /* - * Setup initial temperature. - */ - unit->prof_target = profile->inittemp; + unit->prof_target = profile->inittemp; break; case PROFILE_PAUSE: /* - * Keep current temperature, measure pause time. + * Keep current temperature, measure pause time. For + * temperature fall thru. */ - break; + unit->prof_paused++; case PROFILE_RUN: /* * Calculate current profile step en desired temperature. * When all done, set state to PROFILE_DONE. */ + previous_target = profile->inittemp; + time_until_now = 0; + current_step = 0; run_seconds = (int)(now - unit->prof_started - unit->prof_paused); run_minutes = run_seconds / 60; run_hours = run_minutes / 60; if (debug) - fprintf(stdout, "run_hours=%d minutes=%d seconds=%d\n", run_hours, run_minutes, run_seconds); + fprintf(stdout, "run_hours=%d minutes=%d seconds=%d ", run_hours, run_minutes, run_seconds); for (step = profile->steps; step; step = step->next) { + + if (step->steptime == 0) { + unit->prof_state = PROFILE_DONE; + syslog(LOG_NOTICE, "Profile is done"); + break; + } + + /* + * step->steptime + * step->resttime + * step->target + */ + time_in_step = step->steptime + step->resttime; + current_step++; + if ((run_hours >= time_until_now) && (run_hours < (time_until_now + time_in_step))) { + /* + * This is our current step + */ + if (debug) + fprintf(stdout, "step=%d step_pos=%d step_length=%d steptime=%d resttime=%d target=%.1f ", + current_step, run_hours - time_until_now, time_in_step, step->steptime, step->resttime, step->target); + if ((run_hours - time_until_now) < step->steptime) { + unit->prof_target = previous_target + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target - previous_target)); + if (debug) + fprintf(stdout, "tempshift=%.1f minutes=%d duration=%d temp_move=%.3f ", + step->target - previous_target, run_minutes - (time_until_now * 60), + step->steptime * 60, + previous_target + (((run_minutes - (time_until_now * 60.0)) / (step->steptime * 60.0)) * (step->target - previous_target)) + ); + } else { + unit->prof_target = step->target; + fprintf(stdout, "resting target=%.1f ", step->target); + } + break; + } + time_until_now += time_in_step; + previous_target = step->target; } + if (debug) + fprintf(stdout, "\n"); break; case PROFILE_DONE: /* - * Keep this state. + * Keep this state, set target temperature to the last step. */ + previous_target = profile->inittemp; + for (step = profile->steps; step; step = step->next) { + if (step->steptime == 0) + break; + previous_target = step->target; + } + unit->prof_target = previous_target; break; } /* switch */ } @@ -599,11 +646,32 @@ device_out(unit->fan_address, unit->fan_state); } #ifdef HAVE_WIRINGPI_H - if (unit->heater_address) { - lcd_buf_write(row++, "Heater %s ", unit->heater_state ? "On ":"Off"); - } - if (unit->cooler_address) { - lcd_buf_write(row++, "Cooler %s ", unit->cooler_state ? "On ":"Off"); + if (unit->heater_address && unit->cooler_address) { + if (unit->heater_state) + lcd_buf_write(row++, "Heater On "); + else if (unit->cooler_state) + lcd_buf_write(row++, "Cooler On "); + else + lcd_buf_write(row++, "Standby "); + switch (unit->mode) { + case UNITMODE_BEER: lcd_buf_write(row++, "Target %.1f %cC ", unit->beer_set, 0xdf); + break; + case UNITMODE_FRIDGE: lcd_buf_write(row++, "Target %.1f %cC ", unit->fridge_set, 0xdf); + break; + case UNITMODE_PROFILE: if (unit->prof_state != PROFILE_OFF) + lcd_buf_write(row++, "Target %.1f %cC ", unit->prof_target, 0xdf); + else + lcd_buf_write(row++, "Target not set "); + break; + default: lcd_buf_write(row++, "Target not set "); + } + } else { + if (unit->heater_address) { + lcd_buf_write(row++, "Heat %s ", unit->heater_state ? "On ":"Off"); + } + if (unit->cooler_address) { + lcd_buf_write(row++, "Cool %s ", unit->cooler_state ? "On ":"Off"); + } } #endif }