Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			bugfix/con
		
	
	| Author | SHA256 | Date | |
|---|---|---|---|
| b6150ad452 | |||
| d992218a7d | |||
| 55b62d7438 | |||
| aeb9e04413 | 
							
								
								
									
										56
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								README.md
									
									
									
									
									
								
							@ -19,7 +19,11 @@ Sntp <|-- Metrics
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    class Inputs{
 | 
					    class Inputs{
 | 
				
			||||||
        +initInputs()
 | 
					        +initInputs()
 | 
				
			||||||
 | 
					        -initMeasurement()
 | 
				
			||||||
 | 
					        -updateAverage()
 | 
				
			||||||
 | 
					        -updatePrediction()
 | 
				
			||||||
        -taskInput()
 | 
					        -taskInput()
 | 
				
			||||||
 | 
					        -linearRegressionPredict()
 | 
				
			||||||
        +getChamberTemperature()
 | 
					        +getChamberTemperature()
 | 
				
			||||||
        +getOutdoorTemperature()
 | 
					        +getOutdoorTemperature()
 | 
				
			||||||
        +getInletFlowTemperature()
 | 
					        +getInletFlowTemperature()
 | 
				
			||||||
@ -38,7 +42,11 @@ Sntp <|-- Metrics
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Control{
 | 
					    class Control{
 | 
				
			||||||
 | 
					        initControl()
 | 
				
			||||||
        +taskControl()
 | 
					        +taskControl()
 | 
				
			||||||
 | 
					        +getControlCurrentWeekday()
 | 
				
			||||||
 | 
					        -findControlCurrentTemperatureEntry()
 | 
				
			||||||
 | 
					        +getControlCurrentTemperatureEntry()
 | 
				
			||||||
        -controlTable
 | 
					        -controlTable
 | 
				
			||||||
        +getControlState()
 | 
					        +getControlState()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -79,33 +87,41 @@ Sntp <|-- Metrics
 | 
				
			|||||||
burner_fault_pending 1
 | 
					burner_fault_pending 1
 | 
				
			||||||
circulation_pump_enabled 1
 | 
					circulation_pump_enabled 1
 | 
				
			||||||
burner_enabled 0
 | 
					burner_enabled 0
 | 
				
			||||||
safety_contact_enabled 0
 | 
					safety_contact_enabled 1
 | 
				
			||||||
chamber_temperature 58.750000
 | 
					chamber_temperature 37.250000
 | 
				
			||||||
chamber_temperature_avg10 58.931252
 | 
					chamber_temperature_avg10 37.237499
 | 
				
			||||||
chamber_temperature_avg60 59.190475
 | 
					chamber_temperature_avg60 37.438541
 | 
				
			||||||
chamber_temperature_pred60 55.870998
 | 
					chamber_temperature_damped 42.185040
 | 
				
			||||||
inlet_flow_temperature 53.875000
 | 
					chamber_temperature_pred60 36.638443
 | 
				
			||||||
inlet_flow_temperature_avg10 53.900002
 | 
					inlet_flow_temperature 35.625000
 | 
				
			||||||
inlet_flow_temperature_avg60 53.994320
 | 
					inlet_flow_temperature_avg10 35.618752
 | 
				
			||||||
inlet_flow_temperature_pred60 52.848743
 | 
					inlet_flow_temperature_avg60 35.415627
 | 
				
			||||||
outdoor_temperature 18.000000
 | 
					inlet_flow_temperature_damped 39.431259
 | 
				
			||||||
outdoor_temperature_avg10 18.006250
 | 
					inlet_flow_temperature_pred60 36.078678
 | 
				
			||||||
outdoor_temperature_avg60 18.002840
 | 
					outdoor_temperature 14.687500
 | 
				
			||||||
outdoor_temperature_pred60 18.050785
 | 
					outdoor_temperature_avg10 14.662500
 | 
				
			||||||
return_flow_temperature 48.625000
 | 
					outdoor_temperature_avg60 14.646875
 | 
				
			||||||
return_flow_temperature_avg10 48.718750
 | 
					outdoor_temperature_damped 9.169084
 | 
				
			||||||
return_flow_temperature_avg60 48.846592
 | 
					outdoor_temperature_pred60 14.660233
 | 
				
			||||||
return_flow_temperature_pred60 47.383083
 | 
					return_flow_temperature 39.937500
 | 
				
			||||||
 | 
					return_flow_temperature_avg10 40.087502
 | 
				
			||||||
 | 
					return_flow_temperature_avg60 41.146873
 | 
				
			||||||
 | 
					return_flow_temperature_damped 32.385151
 | 
				
			||||||
 | 
					return_flow_temperature_pred60 37.311958
 | 
				
			||||||
chamber_temperature_state 0
 | 
					chamber_temperature_state 0
 | 
				
			||||||
outdoor_temperature_state 0
 | 
					outdoor_temperature_state 0
 | 
				
			||||||
inlet_flow_temperature_state 0
 | 
					inlet_flow_temperature_state 0
 | 
				
			||||||
return_flow_temperature_state 0
 | 
					return_flow_temperature_state 0
 | 
				
			||||||
safety_state 0
 | 
					safety_state 0
 | 
				
			||||||
control_state 3
 | 
					control_state 3
 | 
				
			||||||
 | 
					control_current_weekday 5
 | 
				
			||||||
 | 
					control_current_entry_time 17100
 | 
				
			||||||
 | 
					control_current_entry_chamber_temperature 80.000000
 | 
				
			||||||
 | 
					control_current_entry_return_flow_temperature 30.000000
 | 
				
			||||||
sntp_state 0
 | 
					sntp_state 0
 | 
				
			||||||
system_unixtime 1735242392
 | 
					system_unixtime 1762012743
 | 
				
			||||||
uptime_seconds 40
 | 
					uptime_seconds 465229
 | 
				
			||||||
wifi_rssi -74
 | 
					wifi_rssi -72
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### Status Encoding
 | 
					#### Status Encoding
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										209
									
								
								main/control.c
									
									
									
									
									
								
							
							
						
						
									
										209
									
								
								main/control.c
									
									
									
									
									
								
							@ -1,10 +1,10 @@
 | 
				
			|||||||
 | 
					#include "control.h"
 | 
				
			||||||
 | 
					#include "esp_log.h"
 | 
				
			||||||
 | 
					#include "esp_timer.h"
 | 
				
			||||||
#include "freertos/FreeRTOS.h"
 | 
					#include "freertos/FreeRTOS.h"
 | 
				
			||||||
#include "freertos/task.h"
 | 
					#include "freertos/task.h"
 | 
				
			||||||
#include "esp_timer.h"
 | 
					 | 
				
			||||||
#include "esp_log.h"
 | 
					 | 
				
			||||||
#include "control.h"
 | 
					 | 
				
			||||||
#include "outputs.h"
 | 
					 | 
				
			||||||
#include "inputs.h"
 | 
					#include "inputs.h"
 | 
				
			||||||
 | 
					#include "outputs.h"
 | 
				
			||||||
#include "safety.h"
 | 
					#include "safety.h"
 | 
				
			||||||
#include "sntp.h"
 | 
					#include "sntp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,24 +15,78 @@
 | 
				
			|||||||
#define RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT 25.0f
 | 
					#define RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT 25.0f
 | 
				
			||||||
#define CHAMBER_TEMPERATURE_TARGET 80.0f    // Max cutoff temperature
 | 
					#define CHAMBER_TEMPERATURE_TARGET 80.0f    // Max cutoff temperature
 | 
				
			||||||
#define CHAMBER_TEMPERATURE_THRESHOLD 45.0f // Min threshold for burner enable
 | 
					#define CHAMBER_TEMPERATURE_THRESHOLD 45.0f // Min threshold for burner enable
 | 
				
			||||||
#define SUMMER_MODE_TEMPERATURE_THRESHOLD_HIGH 20.0f // Summer mode will be activated
 | 
					#define SUMMER_MODE_TEMPERATURE_THRESHOLD_HIGH \
 | 
				
			||||||
#define SUMMER_MODE_TEMPERATURE_THRESHOLD_LOW 15.0f  // Summer mode will be deactivated --> Heating starts
 | 
					    20.0f // Summer mode will be activated
 | 
				
			||||||
#define CIRCULATION_PUMP_TEMPERATURE_THRESHOLD 30.0f // Min threshold of chamber for circulation pump enable
 | 
					#define SUMMER_MODE_TEMPERATURE_THRESHOLD_LOW \
 | 
				
			||||||
#define BURNER_FAULT_DETECTION_THRESHOLD (60U * 4U)  // Burner fault detection after 4 minutes
 | 
					    15.0f // Summer mode will be deactivated --> Heating starts
 | 
				
			||||||
 | 
					#define CIRCULATION_PUMP_TEMPERATURE_THRESHOLD \
 | 
				
			||||||
 | 
					    30.0f // Min threshold of chamber for circulation pump enable
 | 
				
			||||||
 | 
					#define BURNER_FAULT_DETECTION_THRESHOLD \
 | 
				
			||||||
 | 
					    (60U * 4U) // Burner fault detection after 4 minutes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *TAG = "smart-oil-heater-control-system-control";
 | 
					static const char *TAG = "smart-oil-heater-control-system-control";
 | 
				
			||||||
static eControlState sControlState = CONTROL_STARTING;
 | 
					static eControlState sControlState = CONTROL_STARTING;
 | 
				
			||||||
// Control table for daily schedules
 | 
					// Control table for daily schedules
 | 
				
			||||||
static const sControlDay aControlTable[] = {
 | 
					static const sControlDay aControlTable[] = {
 | 
				
			||||||
    {MONDAY, 2U, {{{4, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{22, 0}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					    {MONDAY,
 | 
				
			||||||
    {TUESDAY, 2U, {{{4, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{22, 0}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					     2U,
 | 
				
			||||||
    {WEDNESDAY, 2U, {{{4, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{22, 0}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					     {{{4, 45},
 | 
				
			||||||
    {THURSDAY, 2U, {{{4, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{22, 0}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
    {FRIDAY, 2U, {{{4, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{23, 0}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
    {SATURDAY, 2U, {{{6, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{23, 30}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					      {{22, 0},
 | 
				
			||||||
    {SUNDAY, 2U, {{{6, 45}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY, CHAMBER_TEMPERATURE_TARGET}, {{22, 30}, RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT, CHAMBER_TEMPERATURE_TARGET}}},
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
 | 
					    {TUESDAY,
 | 
				
			||||||
 | 
					     2U,
 | 
				
			||||||
 | 
					     {{{4, 45},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
 | 
					      {{22, 0},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
 | 
					    {WEDNESDAY,
 | 
				
			||||||
 | 
					     2U,
 | 
				
			||||||
 | 
					     {{{4, 45},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
 | 
					      {{22, 0},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
 | 
					    {THURSDAY,
 | 
				
			||||||
 | 
					     2U,
 | 
				
			||||||
 | 
					     {{{4, 45},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
 | 
					      {{22, 0},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
 | 
					    {FRIDAY,
 | 
				
			||||||
 | 
					     2U,
 | 
				
			||||||
 | 
					     {{{4, 45},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
 | 
					      {{23, 0},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
 | 
					    {SATURDAY,
 | 
				
			||||||
 | 
					     2U,
 | 
				
			||||||
 | 
					     {{{6, 45},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
 | 
					      {{23, 30},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
 | 
					    {SUNDAY,
 | 
				
			||||||
 | 
					     2U,
 | 
				
			||||||
 | 
					     {{{6, 45},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET},
 | 
				
			||||||
 | 
					      {{22, 30},
 | 
				
			||||||
 | 
					       RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT,
 | 
				
			||||||
 | 
					       CHAMBER_TEMPERATURE_TARGET}}},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static sControlTemperatureEntry currentControlEntry = aControlTable[0].aTemperatureEntries[0];
 | 
					static sControlTemperatureEntry currentControlEntry =
 | 
				
			||||||
 | 
					    aControlTable[0].aTemperatureEntries[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Function prototypes
 | 
					// Function prototypes
 | 
				
			||||||
void taskControl(void *pvParameters);
 | 
					void taskControl(void *pvParameters);
 | 
				
			||||||
@ -40,8 +94,8 @@ void findControlCurrentTemperatureEntry(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void initControl(void)
 | 
					void initControl(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    BaseType_t taskCreated = xTaskCreate(
 | 
					    BaseType_t taskCreated =
 | 
				
			||||||
        taskControl,   // Function to implement the task
 | 
					        xTaskCreate(taskControl,   // Function to implement the task
 | 
				
			||||||
                    "taskControl", // Task name
 | 
					                    "taskControl", // Task name
 | 
				
			||||||
                    8192,          // Stack size (in words, not bytes)
 | 
					                    8192,          // Stack size (in words, not bytes)
 | 
				
			||||||
                    NULL,          // Parameters to the task function (none in this case)
 | 
					                    NULL,          // Parameters to the task function (none in this case)
 | 
				
			||||||
@ -100,18 +154,23 @@ void taskControl(void *pvParameters)
 | 
				
			|||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sControlTemperatureEntry currentControlEntry = getControlCurrentTemperatureEntry();
 | 
					        findControlCurrentTemperatureEntry();
 | 
				
			||||||
 | 
					        sControlTemperatureEntry currentControlEntry =
 | 
				
			||||||
 | 
					            getControlCurrentTemperatureEntry();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (getOutdoorTemperature().fDampedValue >= SUMMER_MODE_TEMPERATURE_THRESHOLD_HIGH)
 | 
					        if (getOutdoorTemperature().fDampedValue >=
 | 
				
			||||||
 | 
					            SUMMER_MODE_TEMPERATURE_THRESHOLD_HIGH)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            bSummerMode = true;
 | 
					            bSummerMode = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (getOutdoorTemperature().fDampedValue <= SUMMER_MODE_TEMPERATURE_THRESHOLD_LOW)
 | 
					        else if (getOutdoorTemperature().fDampedValue <=
 | 
				
			||||||
 | 
					                 SUMMER_MODE_TEMPERATURE_THRESHOLD_LOW)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            bSummerMode = false;
 | 
					            bSummerMode = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Enable burner if outdoor temperature is low and return flow temperature is cooled down
 | 
					        // Enable burner if outdoor temperature is low and return flow temperature
 | 
				
			||||||
 | 
					        // is cooled down
 | 
				
			||||||
        if (!bHeatingInAction && (eBurnerState != BURNER_FAULT))
 | 
					        if (!bHeatingInAction && (eBurnerState != BURNER_FAULT))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (bSummerMode)
 | 
					            if (bSummerMode)
 | 
				
			||||||
@ -121,10 +180,13 @@ void taskControl(void *pvParameters)
 | 
				
			|||||||
                setSafetyControlState(DISABLED);
 | 
					                setSafetyControlState(DISABLED);
 | 
				
			||||||
                sControlState = CONTROL_OUTDOOR_TOO_WARM;
 | 
					                sControlState = CONTROL_OUTDOOR_TOO_WARM;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if ((getReturnFlowTemperature().average60s.fValue <= currentControlEntry.fReturnFlowTemperature) &&
 | 
					            else if ((getReturnFlowTemperature().average60s.fValue <=
 | 
				
			||||||
                     (getChamberTemperature().fCurrentValue <= CHAMBER_TEMPERATURE_THRESHOLD))
 | 
					                      currentControlEntry.fReturnFlowTemperature) &&
 | 
				
			||||||
 | 
					                     (getChamberTemperature().fCurrentValue <=
 | 
				
			||||||
 | 
					                      CHAMBER_TEMPERATURE_THRESHOLD))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ESP_LOGI(TAG, "Enabling burner: Return flow temperature target reached");
 | 
					                ESP_LOGI(TAG,
 | 
				
			||||||
 | 
					                         "Enabling burner: Return flow temperature target reached");
 | 
				
			||||||
                eBurnerState = BURNER_UNKNOWN;
 | 
					                eBurnerState = BURNER_UNKNOWN;
 | 
				
			||||||
                bHeatingInAction = true;
 | 
					                bHeatingInAction = true;
 | 
				
			||||||
                setBurnerState(ENABLED);
 | 
					                setBurnerState(ENABLED);
 | 
				
			||||||
@ -142,15 +204,18 @@ void taskControl(void *pvParameters)
 | 
				
			|||||||
        // Disable burner if target temperature is reached or a fault occurred
 | 
					        // Disable burner if target temperature is reached or a fault occurred
 | 
				
			||||||
        if (bHeatingInAction)
 | 
					        if (bHeatingInAction)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if ((getChamberTemperature().fCurrentValue >= currentControlEntry.fChamberTemperature) ||
 | 
					            if ((getChamberTemperature().fCurrentValue >=
 | 
				
			||||||
                (getChamberTemperature().predict60s.fValue >= currentControlEntry.fChamberTemperature))
 | 
					                 currentControlEntry.fChamberTemperature) ||
 | 
				
			||||||
 | 
					                (getChamberTemperature().predict60s.fValue >=
 | 
				
			||||||
 | 
					                 currentControlEntry.fChamberTemperature))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ESP_LOGI(TAG, "Chamber target temperature reached: Disabling burner");
 | 
					                ESP_LOGI(TAG, "Chamber target temperature reached: Disabling burner");
 | 
				
			||||||
                bHeatingInAction = false;
 | 
					                bHeatingInAction = false;
 | 
				
			||||||
                setBurnerState(DISABLED);
 | 
					                setBurnerState(DISABLED);
 | 
				
			||||||
                setSafetyControlState(ENABLED);
 | 
					                setSafetyControlState(ENABLED);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (esp_timer_get_time() - i64BurnerEnableTimestamp >= BURNER_FAULT_DETECTION_THRESHOLD * 1000000U)
 | 
					            else if (esp_timer_get_time() - i64BurnerEnableTimestamp >=
 | 
				
			||||||
 | 
					                     BURNER_FAULT_DETECTION_THRESHOLD * 1000000U)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (eBurnerState == BURNER_UNKNOWN)
 | 
					                if (eBurnerState == BURNER_UNKNOWN)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -165,7 +230,8 @@ void taskControl(void *pvParameters)
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        // ESP_LOGI(TAG, "No burner fault detected: Marking burner as fired");
 | 
					                        // ESP_LOGI(TAG, "No burner fault detected: Marking burner as
 | 
				
			||||||
 | 
					                        // fired");
 | 
				
			||||||
                        eBurnerState = BURNER_FIRED;
 | 
					                        eBurnerState = BURNER_FIRED;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -173,7 +239,8 @@ void taskControl(void *pvParameters)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Manage circulation pump
 | 
					        // Manage circulation pump
 | 
				
			||||||
        if (getChamberTemperature().fCurrentValue <= CIRCULATION_PUMP_TEMPERATURE_THRESHOLD)
 | 
					        if (getChamberTemperature().fCurrentValue <=
 | 
				
			||||||
 | 
					            CIRCULATION_PUMP_TEMPERATURE_THRESHOLD)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // ESP_LOGI(TAG, "Burner cooled down: Disabling circulation pump");
 | 
					            // ESP_LOGI(TAG, "Burner cooled down: Disabling circulation pump");
 | 
				
			||||||
            setCirculationPumpState(DISABLED);
 | 
					            setCirculationPumpState(DISABLED);
 | 
				
			||||||
@ -186,10 +253,7 @@ void taskControl(void *pvParameters)
 | 
				
			|||||||
    } // End of while(1)
 | 
					    } // End of while(1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
eControlState getControlState(void)
 | 
					eControlState getControlState(void) { return sControlState; }
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return sControlState;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
eControlWeekday getControlCurrentWeekday(void)
 | 
					eControlWeekday getControlCurrentWeekday(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -203,31 +267,90 @@ eControlWeekday getControlCurrentWeekday(void)
 | 
				
			|||||||
    return (eControlWeekday)((day == 0) ? 6 : day - 1);
 | 
					    return (eControlWeekday)((day == 0) ? 6 : day - 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Finds the active temperature control entry for the current time.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Searches through the weekly schedule to find the most recent entry
 | 
				
			||||||
 | 
					 * that should be active at the current date/time. Falls back to the
 | 
				
			||||||
 | 
					 * last entry in the week if no suitable entry is found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Finds the active temperature control entry for the current time.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Searches through the weekly schedule to find the most recent entry
 | 
				
			||||||
 | 
					 * that should be active at the current date/time. Falls back to the
 | 
				
			||||||
 | 
					 * last entry in the week if no suitable entry is found.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void findControlCurrentTemperatureEntry(void)
 | 
					void findControlCurrentTemperatureEntry(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    eControlWeekday currentDay = getControlCurrentWeekday();
 | 
					    eControlWeekday currentDay = getControlCurrentWeekday();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get current time
 | 
				
			||||||
    time_t now;
 | 
					    time_t now;
 | 
				
			||||||
    struct tm timeinfo;
 | 
					    struct tm timeinfo;
 | 
				
			||||||
    time(&now);
 | 
					    time(&now);
 | 
				
			||||||
    localtime_r(&now, &timeinfo);
 | 
					    localtime_r(&now, &timeinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int hour = timeinfo.tm_hour;
 | 
					    int currentHour = timeinfo.tm_hour;
 | 
				
			||||||
    int minute = timeinfo.tm_min;
 | 
					    int currentMinute = timeinfo.tm_min;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < sizeof(aControlTable) / sizeof(aControlTable[0]); i++)
 | 
					    // ESP_LOGI(TAG, "Searching for control entry - Day: %d, Time: %02d:%02d", currentDay, currentHour, currentMinute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Search through all days and entries
 | 
				
			||||||
 | 
					    for (int dayIndex = 0; dayIndex < 7; dayIndex++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (int j = 0; j < aControlTable[i].entryCount; j++)
 | 
					        const sControlDay *day = &aControlTable[dayIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int entryIndex = 0; entryIndex < day->entryCount; entryIndex++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if ((aControlTable[i].day > currentDay) ||
 | 
					            const sControlTemperatureEntry *entry = &day->aTemperatureEntries[entryIndex];
 | 
				
			||||||
                (aControlTable[i].day == currentDay && aControlTable[i].aTemperatureEntries[j].timestamp.hour > hour) ||
 | 
					
 | 
				
			||||||
                (aControlTable[i].day == currentDay && aControlTable[i].aTemperatureEntries[j].timestamp.hour == hour && aControlTable[i].aTemperatureEntries[j].timestamp.minute >= minute))
 | 
					            // Check if this entry is in the future (next active entry)
 | 
				
			||||||
 | 
					            bool isFutureDay = (day->day > currentDay);
 | 
				
			||||||
 | 
					            bool isTodayFutureTime = (day->day == currentDay) &&
 | 
				
			||||||
 | 
					                                     ((entry->timestamp.hour > currentHour) ||
 | 
				
			||||||
 | 
					                                      (entry->timestamp.hour == currentHour &&
 | 
				
			||||||
 | 
					                                       entry->timestamp.minute > currentMinute));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (isFutureDay || isTodayFutureTime)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                currentControlEntry = aControlTable[i].aTemperatureEntries[j];
 | 
					                // Found next scheduled entry, so determine the previous (active) one
 | 
				
			||||||
 | 
					                if (entryIndex > 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // Use previous entry from same day
 | 
				
			||||||
 | 
					                    currentControlEntry = day->aTemperatureEntries[entryIndex - 1];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            currentControlEntry = aControlTable[i].aTemperatureEntries[j];
 | 
					                else if (dayIndex > 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // Use last entry from previous day
 | 
				
			||||||
 | 
					                    const sControlDay *previousDay = &aControlTable[dayIndex - 1];
 | 
				
			||||||
 | 
					                    currentControlEntry = previousDay->aTemperatureEntries[previousDay->entryCount - 1];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // First entry of the week - wrap to last entry of Sunday
 | 
				
			||||||
 | 
					                    const sControlDay *sunday = &aControlTable[6];
 | 
				
			||||||
 | 
					                    currentControlEntry = sunday->aTemperatureEntries[sunday->entryCount - 1];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                /*
 | 
				
			||||||
 | 
					                ESP_LOGI(TAG, "Active entry found - Time: %02d:%02d, "
 | 
				
			||||||
 | 
					                         "Return Temp: %lf, Chamber Temp: %lf",
 | 
				
			||||||
 | 
					                         currentControlEntry.timestamp.hour,
 | 
				
			||||||
 | 
					                         currentControlEntry.timestamp.minute,
 | 
				
			||||||
 | 
					                         currentControlEntry.fReturnFlowTemperature,
 | 
				
			||||||
 | 
					                         currentControlEntry.fChamberTemperature);
 | 
				
			||||||
 | 
					                         */
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If we reached here, current time is after all entries this week
 | 
				
			||||||
 | 
					    // Use the last entry (Sunday evening)
 | 
				
			||||||
 | 
					    const sControlDay *sunday = &aControlTable[6];
 | 
				
			||||||
 | 
					    currentControlEntry = sunday->aTemperatureEntries[sunday->entryCount - 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ESP_LOGI(TAG, "Using last entry of week - Time: %02d:%02d", currentControlEntry.timestamp.hour, currentControlEntry.timestamp.minute);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sControlTemperatureEntry getControlCurrentTemperatureEntry(void)
 | 
					sControlTemperatureEntry getControlCurrentTemperatureEntry(void)
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user