thermferm/thermferm.c

changeset 219
ae720212accc
parent 215
5ad534c79a22
child 221
91a5e7281c35
--- 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
 	    }

mercurial