main/automation.c

changeset 77
66c77497d86d
parent 75
224851e81117
child 78
b58e0c9897e1
--- a/main/automation.c	Mon Jun 01 20:27:00 2020 +0200
+++ b/main/automation.c	Sat Jun 06 13:28:46 2020 +0200
@@ -104,7 +104,7 @@
 	case MAIN_AUTO_INIT1:
 		log_msg(TAG, "Automation startup");
 #ifdef CONFIG_TEMP_SENSORS_SIMULATOR
-		Fake_MLT = recipe.MashStep[0].Temperature - 10;
+		Fake_MLT = recipe.MashStep[0].Step_temp - 10;
 		Fake_HLT = recipe.SpargeTemp - 15;
                 if (xSemaphoreTake(xSemaphoreDS18B20, 10) == pdTRUE) {
                     ds18b20_state->mlt_temperature = ((int)(Fake_MLT * 16)) / 16.0;
@@ -112,10 +112,10 @@
                     xSemaphoreGive(xSemaphoreDS18B20);
                 }
 #endif
-                for (int i = 0; i < 7; i++) {
-                    if (recipe.MashStep[i].Resttime)
-                        LastMashStep = i;
-                }
+		if (recipe.Mashsteps > 1)
+		    LastMashStep = recipe.Mashsteps - 2;
+		else
+		    LastMashStep = 0;
                 log_msg(TAG, "Last mash step %d", LastMashStep);
 
                 // Check for a crashed session.
@@ -178,6 +178,8 @@
 		runtime.HopAddition = 0;
 		runtime.Logfile[0] = '\0';
 		runtime.PumpCooling = false;
+		runtime.MashStep = 0;
+		runtime.MaltAdded = false;
 		write_runtime();
                 power_MLT = power_HLT = counts = 0;
 		log_clean();
@@ -200,17 +202,10 @@
 		}
 		break;
 
-	case MAIN_AUTO_MASH_IN:
-        case MAIN_AUTO_MASH_1:
-        case MAIN_AUTO_MASH_2:
-        case MAIN_AUTO_MASH_3:
-        case MAIN_AUTO_MASH_4:
-        case MAIN_AUTO_MASH_5:
-        case MAIN_AUTO_MASH_6:
-        case MAIN_AUTO_MASH_OUT:
-                if (Main_Screen == MAIN_AUTO_MASH_IN) {
+	case MAIN_AUTO_MASH:
+                if (runtime.MashStep == 0) {
                     MinMash = 38.0;
-                    MaxMash = recipe.MashStep[1].Temperature + 10.0;
+                    MaxMash = recipe.MashStep[0].Step_temp+ 10.0;
                     TimeBrewing = 0;
 		    runtime.TimeBrewing = 0;
                     if (System_TimeOk) {
@@ -223,20 +218,19 @@
 			runtime.BrewStart = (time_t)0;
                     }
 		    updateRuntime = true;
-                } else if (Main_Screen == MAIN_AUTO_MASH_OUT) {
+                } else if (runtime.MashStep == (recipe.Mashsteps - 1)) {
                     MinMash = 75.0;
                     MaxMash = 80.0;
                 } else {
-                    MinMash = recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN - 1].Temperature;
-                    if (recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN + 1].Resttime) {
-                        MaxMash = recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN + 1].Temperature;
-                    } else {
-                        MaxMash = 75.0;
-                    }
+                    MinMash = recipe.MashStep[runtime.MashStep - 1].Step_temp;
+                    MaxMash = recipe.MashStep[runtime.MashStep + 1].Step_temp;
+		    if (MaxMash >= 75.0)
+			MaxMash = 74.75;
                 }
                 MashState = Sub_Screen = MASH_NONE;
-		snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen);
+		snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen, runtime.MashStep);
 		ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
+		ESP_LOGI(TAG, "%s", msg);
                 pumpTime = 0;
                 pumpRest = false;
 		runtime.StageResume = Main_Screen;
@@ -446,7 +440,7 @@
 		y += 16;
 		ShowText(2,y,(char *)"Recept", recipe.Name);
 		y += 16;
-		ShowFloat(2, y, (char *)"Maisch in", (char *)" C", recipe.MashStep[0].Temperature, 2);
+		ShowFloat(2, y, (char *)"Maisch in", (char *)" C", recipe.MashStep[0].Infuse_temp, 3);
 		ShowFloat(162, y, (char *)"Spoelwater", (char *)" C", recipe.SpargeTemp, 2);
 		y += 16;
 		_fg = TFT_WHITE;
@@ -456,18 +450,19 @@
 		TFT_print((char *)"Rust", 280, y);
 		_fg = TFT_YELLOW;
 		y += 16;
-		for (int i = 1; i < 8; i++) {
-		    if (recipe.MashStep[i].Resttime) {
-			TFT_print(recipe.MashStep[i].Name, 2, y);
-			strcpy(tmp, mashTypes[recipe.MashStep[i].Type]);
-			tmp[1] = '\0';
-			TFT_print(tmp, 200, y);
-			sprintf(tmp, "%.2f", recipe.MashStep[i].Temperature);
-			TFT_print(tmp, 220, y);
-			sprintf(tmp, "%2d m", recipe.MashStep[i].Resttime);
-			TFT_print(tmp, 280, y);
-			y += 16;
-		    }
+		for (int i = 0; i < recipe.Mashsteps; i++) {
+		    TFT_print(recipe.MashStep[i].Name, 2, y);
+		    if (recipe.MashStep[i].Type < 3)
+		    	strcpy(tmp, mashTypes[recipe.MashStep[i].Type]);
+		    else
+			tmp[0] = '?';
+		    tmp[1] = '\0';
+		    TFT_print(tmp, 200, y);
+		    sprintf(tmp, "%.2f", recipe.MashStep[i].Step_temp);
+		    TFT_print(tmp, 220, y);
+		    sprintf(tmp, "%2d m", recipe.MashStep[i].Step_time);
+		    TFT_print(tmp, 280, y);
+		    y += 16;
 		}
 		ShowInteger(2, y, (char *)"Kooktijd", (char *)" min", recipe.BoilTime);
 		ShowFloat(162, y, (char *)"Koel tot", (char *)" C", recipe.CoolTemp, 2);
@@ -589,7 +584,7 @@
                      */
                     int AvailableTime = 0;
                     for (int i = 1; i < 6; i++) // Only normal Mash steps
-                        AvailableTime += recipe.MashStep[i].Resttime;
+                        AvailableTime += recipe.MashStep[i].Step_time;
                     if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
                         driver_state->hlt_sp = recipe.SpargeTemp - ((AvailableTime / 2) + 2);
                         log_msg(TAG, "HLT preheat set to %4.2f", driver_state->hlt_sp);
@@ -606,7 +601,7 @@
 
 	case MAIN_AUTO_HEATUP:
                 if (! runtime.UseHLT) {         // Skip if HLT is off
-                    Main_Screen = MAIN_AUTO_MASH_IN;
+                    Main_Screen = MAIN_AUTO_MASH;
                     break;
                 }
 
@@ -614,7 +609,7 @@
                 HLT_info(71,150, true, false);
                 if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
                     if (driver_state->hlt_pv >= driver_state->hlt_sp) {
-                        Main_Screen = MAIN_AUTO_MASH_IN;
+                        Main_Screen = MAIN_AUTO_MASH;
                         driver_state->hlt_sp = recipe.SpargeTemp;       // Set final setpoint
 			log_msg(TAG, "HLT preheat done");
                     }
@@ -622,24 +617,17 @@
                 }
                 break;
 
-	case MAIN_AUTO_MASH_IN:
-	case MAIN_AUTO_MASH_1:
-	case MAIN_AUTO_MASH_2:
-	case MAIN_AUTO_MASH_3:
-	case MAIN_AUTO_MASH_4:
-	case MAIN_AUTO_MASH_5:
-	case MAIN_AUTO_MASH_6:
-	case MAIN_AUTO_MASH_OUT:
+	case MAIN_AUTO_MASH:
                 temp_MLT = 0.0;
                 if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
                     temp_MLT = driver_state->mlt_pv;
 
-		    if (MashState == MASH_ADD || MashState == MASH_REMOVE) {
+		    if (MashState == MASH_ADD || MashState == MASH_REMOVE || MashState == MASH_INFUSE) {
 			driver_state->pump_run = 0;
 		    } else if (MashState != MASH_NONE) {
-                        if (Main_Screen == MAIN_AUTO_MASH_IN) {
+                        if (runtime.MashStep == 0) {
                             driver_state->pump_run = (equipment.PumpPreMash && ! pumpRest) ? 1 : 0;
-                        } else if (Main_Screen == MAIN_AUTO_MASH_OUT) {
+                        } else if (runtime.MashStep == (recipe.Mashsteps -1)) {
                             driver_state->pump_run = (equipment.PumpMashOut && ! pumpRest) ? 1 : 0;
                         } else {
                             driver_state->pump_run = (equipment.PumpOnMash && ! pumpRest) ? 1 : 0;
@@ -648,44 +636,47 @@
                     xSemaphoreGive(xSemaphoreDriver);
                 }
                 if (MashState == MASH_NONE) {
-                    stageTemp = recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Temperature;
-                    stageTime = recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Resttime;
+		    if (runtime.MashStep == 0 && ! runtime.MaltAdded && recipe.MashStep[0].Infuse_temp) {
+			stageTemp = recipe.MashStep[0].Infuse_temp;
+		    } else {
+                    	stageTemp = recipe.MashStep[runtime.MashStep].Step_temp;
+		    }
+                    stageTime = recipe.MashStep[runtime.MashStep].Step_time;
                     TempReached = false;
-                    if (stageTime == 0) {
-                        ESP_LOGI(TAG, "Mash step %d skipped", Main_Screen - MAIN_AUTO_MASH_IN);
-                        Main_Screen++;
-                        break;
-                    }
                     if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
                         driver_state->mlt_sp = stageTemp;
                         driver_state->mlt_mode = MLT_MODE_PID;
                         xSemaphoreGive(xSemaphoreDriver);
                     }
                     MashState = Sub_Screen = MASH_WAITTEMP;
-		    snprintf(msg, 255, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen);
+		    ESP_LOGI(TAG, "** Step %d Stage %d Malt %s", runtime.MashStep, MashState, runtime.MaltAdded ? (char *)"yes":(char *)"no");
+		    snprintf(msg, 255, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen, runtime.MashStep);
                     ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
-                    log_msg(TAG, "Mash step %d type: %s time: %d sp: %4.2f  sv: %4.3f",
-				    Main_Screen - MAIN_AUTO_MASH_IN, mashTypes[recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Type],
+                    log_msg(TAG, "Mash step %d type: %s time: %d sp: %6.4f  sv: %6.4f",
+				    runtime.MashStep, mashTypes[recipe.MashStep[runtime.MashStep].Type],
                                     stageTime, stageTemp, temp_MLT);
 
-		    if (Main_Screen > MAIN_AUTO_MASH_IN) {
+		    if (runtime.MashStep) {
 			// Do not annotate before the log is open.
-			if (Main_Screen == MAIN_AUTO_MASH_OUT) {
+			if (runtime.MashStep == (recipe.Mashsteps -1)) {
 			    log_annotation(ANNOTATION_STAGE, (char *)"Uitmaischen");
 			} else {
-                    	    sprintf(logline, "Maisch: %d", Main_Screen - MAIN_AUTO_MASH_IN);
+                    	    sprintf(logline, "Maisch: %d", runtime.MashStep);
 		    	    log_annotation(ANNOTATION_STAGE, logline);
 			}
 		    }
 
-                    if (strlen(recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Name)) {
-                        TopMessage(recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Name);
+		    if (! runtime.MaltAdded) {
+			TopMessage((char *)"Opwarmen MLT");
+                    } else if (strlen(recipe.MashStep[runtime.MashStep].Name)) {
+                        TopMessage(recipe.MashStep[runtime.MashStep].Name);
                     } else {
-                        sprintf(temp_buf, "Maisch stap #%d", Main_Screen - MAIN_AUTO_MASH_IN);
+                        sprintf(temp_buf, "Maisch stap #%d", runtime.MashStep);
                         TopMessage(temp_buf);
                     }
-		    if ((Main_Screen > MAIN_AUTO_MASH_IN) && (Main_Screen < MAIN_AUTO_MASH_OUT) && 
-			 (recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Type == MASHTYPE_INFUSION)) {
+		    if (runtime.MashStep && (runtime.MashStep < recipe.Mashsteps) && (recipe.MashStep[runtime.MashStep].Type != MASHTYPE_TEMPERATURE)) {
+			TFT_fillRect(0, 120, 320, 50, TFT_BLACK);
+                        Buttons_Clear();
 			Buttons_Add(  5,120, 60, 40, (char *)"Halt", 0);
 			Buttons[0].dark = true;
 			Buttons_Add(255,120, 60, 40, (char *)"Ok",   1);
@@ -693,20 +684,29 @@
 			_fg = TFT_WHITE;
 			_bg = TFT_BLACK;
 			TFT_setFont(DEJAVU18_FONT, NULL);
-			sprintf(temp_buf, "Infuse %.1f L/%.1f C", recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Infusion_amount,
-					recipe.MashStep[Main_Screen - MAIN_AUTO_MASH_IN].Infusion_temp);
+			if (recipe.MashStep[runtime.MashStep].Type == MASHTYPE_INFUSION) {
+			    sprintf(temp_buf, "Infusie %.1f L/%.1f C", recipe.MashStep[runtime.MashStep].Infuse_amount,
+					recipe.MashStep[runtime.MashStep].Infuse_temp);
+			    MashState = Sub_Screen = MASH_INFUSE;
+			    log_msg(TAG, "Mash infusion prompt");
+			} else if (recipe.MashStep[runtime.MashStep].Type == MASHTYPE_DECOCTION) {
+			    sprintf(temp_buf, "Decoctie %.1f Liter", recipe.MashStep[runtime.MashStep].Infuse_amount);
+			    MashState = Sub_Screen = MASH_DECOCT;
+			    log_msg(TAG, "Mash decoction prompt");
+			}
 			TFT_print(temp_buf, CENTER, 135);
 			SoundPlay(SOUND_Prompt);
-			MashState = Sub_Screen = MASH_INFUSE;
-			snprintf(msg, 255, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"%s\"}", Main_Screen, Sub_Screen, temp_buf);
+			snprintf(msg, 255, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"%s\"}",
+					Main_Screen, Sub_Screen, runtime.MashStep, temp_buf);
                 	ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
-			if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
-			    // No heating during the infusion.
-			    driver_state->mlt_sp = stageTemp;
-			    driver_state->mlt_mode = MLT_MODE_OFF;
-			    xSemaphoreGive(xSemaphoreDriver);
+			if (recipe.MashStep[runtime.MashStep].Type == MASHTYPE_INFUSION) {
+			    if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
+			    	// No heating during the infusion.
+			    	driver_state->mlt_sp = stageTemp;
+			    	driver_state->mlt_mode = MLT_MODE_OFF;
+			    	xSemaphoreGive(xSemaphoreDriver);
+			    }
 			}
-			log_msg(TAG, "Mash infusion prompt");
 		    } else {
 			Buttons_Add(  5,  30, 60, 40, (char *)"+sp",   0);
 			Buttons_Add(255,  30, 60, 40, (char *)"-sp",   1);
@@ -722,9 +722,10 @@
                         SoundPlay(SOUND_TempReached);
                         TempReached = true;
                         MashState = Sub_Screen = MASH_REST;
-			snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen);
+			ESP_LOGI(TAG, "** Step %d Stage %d Malt %s", runtime.MashStep, MashState, runtime.MaltAdded ? (char *)"yes":(char *)"no");
+			snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen, runtime.MashStep);
                 	ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
-                        if (Main_Screen == MAIN_AUTO_MASH_IN) {
+                        if (! runtime.MaltAdded && runtime.MashStep == 0) {
                             TimerSet(0);
                         } else {
                             if (Resume && (runtime.StageTimeLeft < stageTime))
@@ -735,7 +736,7 @@
 			Resume = false;
 			runtime.StageTimeLeft = TimeLeft / 60;
 			updateRuntime = true;
-                        log_msg(TAG, "Mash step %d temperature reached, rest %d minutes", Main_Screen - MAIN_AUTO_MASH_IN, TimeLeft / 60);
+                        log_msg(TAG, "Mash step %d temperature reached, rest %d minutes", runtime.MashStep, TimeLeft / 60);
                         Buttons_Clear();
                         Buttons_Add(  0, 120, 60, 40, (char *)"+1m",   0);
                         Buttons_Add(260, 120, 60, 40, (char *)"-1m",   1);
@@ -760,8 +761,8 @@
                     /*
                      * Mash step rest time and pump control
                      */
-                    if (((Main_Screen == MAIN_AUTO_MASH_OUT) && equipment.PumpMashOut) ||
-                        ((Main_Screen != MAIN_AUTO_MASH_OUT) && equipment.PumpOnMash)) {
+                    if (((runtime.MashStep == (recipe.Mashsteps -1)) && equipment.PumpMashOut) ||
+                        ((runtime.MashStep < recipe.Mashsteps) && equipment.PumpOnMash)) {
                         float DeltaTemp = equipment.PumpRest * stageTemp / 120; // Maximum temperature drop before heating again.
                         if (pumpTime >= (equipment.PumpCycle + equipment.PumpRest) || ((stageTemp - temp_MLT) > DeltaTemp)) {
                             pumpTime = 0;
@@ -795,13 +796,20 @@
                     }
 
                     if (TimeLeft == 0) {
+			ESP_LOGI(TAG, "** Step %d Stage %d Malt %s", runtime.MashStep, MashState, runtime.MaltAdded ? (char *)"yes":(char *)"no");
 			runtime.StageTimeLeft = 0;
 			updateRuntime = true;
-                        if ((Main_Screen == MAIN_AUTO_MASH_IN) && config.AskAdd) {
+                        if (runtime.MashStep == 0 && ! runtime.MaltAdded && config.AskAdd) {
                             /*
                              * Add Mash prompt.
                              */
+			    stageTemp = recipe.MashStep[runtime.MashStep].Step_temp; // Set normal step temperature
+                    	    if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
+                        	driver_state->mlt_sp = stageTemp;
+                        	xSemaphoreGive(xSemaphoreDriver);
+                    	    }
 			    log_annotation(ANNOTATION_EVENT, (char *)"Mout storten");
+			    TFT_fillRect(0, 120, 320, 50, TFT_BLACK);
                             Buttons_Clear();
                             Buttons_Add(  5,120, 60, 40, (char *)"Halt", 0);
 			    Buttons[0].dark = true;
@@ -813,12 +821,13 @@
                             TFT_print((char *)"Mout storten?", CENTER, 135);
                             SoundPlay(SOUND_Prompt);
 			    MashState = Sub_Screen = MASH_ADD;
-			    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"Mout storten?\"}", Main_Screen, Sub_Screen);
+			    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"Mout storten?\"}",
+						Main_Screen, Sub_Screen, runtime.MashStep);
                 	    ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
 			    log_msg(TAG, "Mash add prompt");
 			    break;
                         }
-                        if (((Main_Screen - MAIN_AUTO_MASH_IN) == LastMashStep) && config.AskIodine) {
+                        if ((runtime.MashStep == LastMashStep) && config.AskIodine) {
                             /*
                              * Iodone test prompt.
                              */
@@ -837,12 +846,14 @@
                             beeped = false;
                             TimerSet(config.IodineTime * 60);
 			    MashState = Sub_Screen = MASH_IODINE;
-			    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"Jodium test?\"}", Main_Screen, Sub_Screen);
+		ESP_LOGI(TAG, "** Step %d Stage %d Malt %s", runtime.MashStep, MashState, runtime.MaltAdded ? (char *)"yes":(char *)"no");
+			    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"Jodium test?\"}",
+						Main_Screen, Sub_Screen, runtime.MashStep);
                 	    ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
 			    log_msg(TAG, "Mash iodine test prompt");
 			    break;
                         }
-                        if ((Main_Screen == MAIN_AUTO_MASH_OUT) && config.AskRemove) {
+                        if ((runtime.MashStep == (recipe.Mashsteps - 1)) && config.AskRemove) {
                             /*
                              * Mash remove prompt.
                              */
@@ -859,13 +870,20 @@
                             TFT_print((char *)"Mout verwijderen?", CENTER, 135);
                             SoundPlay(SOUND_Prompt);
 			    MashState = Sub_Screen = MASH_REMOVE;
-			    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"Mout verwijderen?\"}", Main_Screen, Sub_Screen);
+		ESP_LOGI(TAG, "** Step %d Stage %d Malt %s", runtime.MashStep, MashState, runtime.MaltAdded ? (char *)"yes":(char *)"no");
+			    snprintf(msg, 127, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"Mout verwijderen?\"}",
+						Main_Screen, Sub_Screen, runtime.MashStep);
                 	    ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
 			    log_msg(TAG, "Mash remove prompt");
 			    break;
                         }
-                        if (Main_Screen != MAIN_AUTO_ABORT)
-                            Main_Screen++;
+                        if (Main_Screen != MAIN_AUTO_ABORT) {
+                            runtime.MashStep++;
+			    MashState = Sub_Screen = MASH_NONE;
+			    if (runtime.MashStep == recipe.Mashsteps)
+				Main_Screen = MAIN_AUTO_TOBOIL;
+			    updateRuntime = true;
+			}
                         TempReached = false;
                     } else {
                         TimerShow(TimeLeft, 65, 122);
@@ -888,32 +906,72 @@
 		    switch (Buttons_Scan()) {
 			case 0:     Main_Screen = MAIN_AUTO_ABORT;
 				    break;
-			case 1:     Main_Screen++;
+			case 1:     //Main_Screen++;
+				    if (MashState == MASH_ADD) {
+					MashState = Sub_Screen = MASH_NONE;
+					runtime.MaltAdded = true;
+					updateRuntime = true;
+				    } else if (MashState == MASH_IODINE) {
+					MashState = Sub_Screen = MASH_NONE;
+					runtime.MashStep++;
+					if (runtime.MashStep == recipe.Mashsteps)
+					    Main_Screen = MAIN_AUTO_TOBOIL;
+					updateRuntime = true;
+				    } else if (MashState == MASH_REMOVE) {
+					Main_Screen = MAIN_AUTO_TOBOIL;
+				    }
+				    TFT_fillRect(0, 120, 320, 50, TFT_BLACK);
+				    Buttons_Clear();
+		ESP_LOGI(TAG, "** Step %d Stage %d Malt %s", runtime.MashStep, MashState, runtime.MaltAdded ? (char *)"yes":(char *)"no");	
 				    break;
 			default:    break;
 		    }
 		    if (MashState == MASH_IODINE && TimeLeft == 0) {
-			Main_Screen++;
+			MashState = Sub_Screen = MASH_NONE;
+                        runtime.MashStep++;
+                        if (runtime.MashStep == recipe.Mashsteps)
+                            Main_Screen = MAIN_AUTO_TOBOIL;
+                        updateRuntime = true;
+			TFT_fillRect(0, 120, 320, 50, TFT_BLACK);
+			Buttons_Clear();
 		    }
-		} else if (MashState == MASH_INFUSE) {
+		} else if (MashState == MASH_INFUSE || MashState == MASH_DECOCT) {
 		    switch (Buttons_Scan()) {
 			case 0:     Main_Screen = MAIN_AUTO_ABORT;
 				    break;
-			case 1:	    MashState = Sub_Screen = MASH_WAITTEMP;
-				    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"timer\":\"\"}", Main_Screen, Sub_Screen);
-                		    ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
+			case 1:
+#ifdef CONFIG_TEMP_SENSORS_SIMULATOR
+				    if (MashState == MASH_DECOCT) {
+					Fake_MLT = recipe.MashStep[runtime.MashStep].Step_temp - 0.72; // Fake the decoction amt.
+					if (xSemaphoreTake(xSemaphoreDS18B20, 10) == pdTRUE) {
+					    ds18b20_state->mlt_temperature = ((int)(Fake_MLT * 16)) / 16.0;
+					    xSemaphoreGive(xSemaphoreDS18B20);
+					}
+				    }
+#endif
 				    if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) {
 					// Start PID again.
 					driver_state->mlt_sp = stageTemp;
 					driver_state->mlt_mode = MLT_MODE_PID;
 					xSemaphoreGive(xSemaphoreDriver);
 				    }
+				    TFT_fillRect(0, 120, 320, 50, TFT_BLACK);
 				    Buttons_Clear();
 			    	    Buttons_Add(  5,  30, 60, 40, (char *)"+sp",   0);
 				    Buttons_Add(255,  30, 60, 40, (char *)"-sp",   1);
 				    Buttons_Show();
 				    TFT_fillRect(65, 120, 190, 40, TFT_BLACK);
-				    log_annotation(ANNOTATION_EVENT, (char *)"Eind infusie");
+				    if (MashState == MASH_INFUSE) {
+					log_msg(TAG, "Eind infusie");
+				    	log_annotation(ANNOTATION_EVENT, (char *)"Eind infusie");
+				    } else {
+					log_msg(TAG, "Eind decoctie");
+					log_annotation(ANNOTATION_EVENT, (char *)"Eind decoctie");
+				    }
+				    MashState = Sub_Screen = MASH_WAITTEMP;
+				    snprintf(msg, 63, "{\"main\":\"%d\",\"sub\":\"%d\",\"step\":\"%d\",\"timer\":\"\"}",
+							Main_Screen, Sub_Screen, runtime.MashStep);
+                                    ws_server_send_text_clients((char *)"/ws", msg, strlen(msg));
 				    break;
 			default:    break;
 		    }

mercurial