add control status
This commit is contained in:
		
							
								
								
									
										54
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								README.md
									
									
									
									
									
								
							| @ -40,6 +40,7 @@ Sntp <|-- Metrics | ||||
|     class Control{ | ||||
|         +taskControl() | ||||
|         -timetable | ||||
|         +getControlState() | ||||
|     } | ||||
|  | ||||
|     class Safety{ | ||||
| @ -71,7 +72,56 @@ Sntp <|-- Metrics | ||||
|     } | ||||
| ``` | ||||
|  | ||||
| ### Hardware | ||||
| ### Prometheus Metrics | ||||
| `curl http://X.X.X.X:9100/metrics` | ||||
| #### Example | ||||
| ``` | ||||
| burner_fault_pending 1 | ||||
| circulation_pump_enabled 0 | ||||
| burner_enabled 1 | ||||
| safety_contact_enabled 1 | ||||
| chamber_temperature 21.812500 | ||||
| chamber_temperature_avg10 21.837500 | ||||
| chamber_temperature_avg60 21.825521 | ||||
| inlet_flow_temperature 22.437500 | ||||
| inlet_flow_temperature_avg10 22.437500 | ||||
| inlet_flow_temperature_avg60 22.434896 | ||||
| outdoor_temperature 21.937500 | ||||
| outdoor_temperature_avg10 21.937500 | ||||
| outdoor_temperature_avg60 21.933594 | ||||
| return_flow_temperature 22.375000 | ||||
| return_flow_temperature_avg10 22.375000 | ||||
| return_flow_temperature_avg60 22.375000 | ||||
| chamber_temperature_state 0 | ||||
| outdoor_temperature_state 0 | ||||
| inlet_flow_temperature_state 0 | ||||
| return_flow_temperature_state 0 | ||||
| safety_state 0 | ||||
| control_state 5 | ||||
| sntp_state 0 | ||||
| system_unixtime 1734814285 | ||||
| uptime_seconds 90 | ||||
| wifi_rssi -63 | ||||
| ``` | ||||
|  | ||||
| #### Status Encoding | ||||
| ##### Digital Themperatur Sensor DS10B20 | ||||
|  - chamber_temperature_state | ||||
|  - outdoor_temperature_state | ||||
|  - inlet_flow_temperature_state | ||||
|  - return_flow_temperature_state | ||||
|  | ||||
| | Enum eSensorErrorState  in [safety.h](main/safety.h) | Value  | Description          | | ||||
| |------------------------------------------------------|--------|----------------------| | ||||
| | SENSOR_NO_ERROR                                      | 0      |                      | | ||||
| | SENSOR_TOO_HIGH                                      | 1      |  Sanity check failed | | ||||
| | SENSOR_TOO_LOW                                       | 2      |  Sanity check failed | | ||||
| | SENSOR_UNCHANGED                                     | 3      |  Sanity check failed | | ||||
| | SENSOR_NOT_FOUND                                     | 4      |  No Communication    | | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Hardware | ||||
|  | ||||
| | Function                              | ESP32 | PLC ES32C14               | | ||||
| |---------------------------------------|-------|---------------------------| | ||||
| @ -80,3 +130,5 @@ Sntp <|-- Metrics | ||||
| | Output Safety Contact (powers Burner) | IO12  | Relay 3 NC2               | | ||||
| | Input Burner Fault                    | IO19  | Digital Input IN1         | | ||||
| | Input Temperature DS10B20             | IO04  | 1-Wire                    | | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -10,7 +10,7 @@ | ||||
| #define PERIODIC_INTERVAL 1U // run safety checks every 1sec | ||||
|  | ||||
| static const char *TAG = "smart-oil-heater-control-system-control"; | ||||
|  | ||||
| static eControlState sControlState = CONTROL_STARTING; | ||||
| void taskControl(void *pvParameters); | ||||
|  | ||||
| void initControl(void) | ||||
| @ -44,12 +44,14 @@ void taskControl(void *pvParameters) | ||||
|         if (getSafetyState() != SAFETY_NO_ERROR) | ||||
|         { | ||||
|             ESP_LOGW(TAG, "Control not possible due to safety fault!"); | ||||
|             sControlState = CONTROL_FAULT; | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         if (getSntpState() != SYNC_SUCCESSFUL) | ||||
|         { | ||||
|             ESP_LOGW(TAG, "Control not possible due to sntp fault!"); | ||||
|             sControlState = CONTROL_FAULT; | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
| @ -58,4 +60,9 @@ void taskControl(void *pvParameters) | ||||
|         setBurnerState(ENABLED); | ||||
|         setSafetyControlState(ENABLED); | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | ||||
| eControlState getControlState(void) | ||||
| { | ||||
|     return sControlState; | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,14 @@ | ||||
| #pragma once | ||||
|  | ||||
| void initControl(void); | ||||
| typedef enum _ControlState | ||||
| { | ||||
|     CONTROL_STARTING, | ||||
|     CONTROL_HEATING, | ||||
|     CONTROL_OUTDOOR_TOO_WARM, | ||||
|     CONTROL_RETURN_FLOW_TOO_WARM, | ||||
|     CONTROL_BURNER_FAULT, | ||||
|     CONTROL_FAULT, | ||||
| } eControlState; | ||||
|  | ||||
| void initControl(void); | ||||
| eControlState getControlState(void); | ||||
| @ -12,6 +12,7 @@ | ||||
| #include "inputs.h" | ||||
| #include "safety.h" | ||||
| #include "sntp.h" | ||||
| #include "control.h" | ||||
|  | ||||
| static const char *TAG = "smart-oil-heater-control-system-metrics"; | ||||
|  | ||||
| @ -181,15 +182,15 @@ void taskMetrics(void *pvParameters) | ||||
|         aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature().average60s.fValue; | ||||
|         u16MetricCounter++; | ||||
|  | ||||
|         /*Sensor status*/ | ||||
|         /*Sensor State*/ | ||||
|         sSensorSanityCheck aChecks[NUMBER_OF_SENSOR_SANITY_CHECKS]; | ||||
|         getSensorSanityStates(aChecks); | ||||
|         for (size_t i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++) | ||||
|         { | ||||
|             strcpy(aMetrics[u16MetricCounter].caMetricName, aChecks[i].name); | ||||
|             strcat(aMetrics[u16MetricCounter].caMetricName, "_status"); | ||||
|             strcat(aMetrics[u16MetricCounter].caMetricName, "_state"); | ||||
|             aMetrics[u16MetricCounter].type = INTEGER_U8; | ||||
|             aMetrics[u16MetricCounter].u8MetricValue = aChecks[i].status; | ||||
|             aMetrics[u16MetricCounter].u8MetricValue = aChecks[i].state; | ||||
|             u16MetricCounter++; | ||||
|         } | ||||
|  | ||||
| @ -199,8 +200,14 @@ void taskMetrics(void *pvParameters) | ||||
|         aMetrics[u16MetricCounter].u8MetricValue = getSafetyState(); | ||||
|         u16MetricCounter++; | ||||
|  | ||||
|         /*SNTP Status*/ | ||||
|         strcpy(aMetrics[u16MetricCounter].caMetricName, "sntp_status"); | ||||
|         /*Control State*/ | ||||
|         strcpy(aMetrics[u16MetricCounter].caMetricName, "control_state"); | ||||
|         aMetrics[u16MetricCounter].type = INTEGER_U8; | ||||
|         aMetrics[u16MetricCounter].u8MetricValue = getControlState(); | ||||
|         u16MetricCounter++; | ||||
|  | ||||
|         /*SNTP State*/ | ||||
|         strcpy(aMetrics[u16MetricCounter].caMetricName, "sntp_state"); | ||||
|         aMetrics[u16MetricCounter].type = INTEGER_U8; | ||||
|         aMetrics[u16MetricCounter].u8MetricValue = getSntpState(); | ||||
|         u16MetricCounter++; | ||||
|  | ||||
| @ -77,7 +77,7 @@ void checkSensorSanity(void) | ||||
|     for (int i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++) | ||||
|     { | ||||
|         // printf("Check sanity of sensor %s:\n", sanityChecks[i].name); | ||||
|         // printf("  Status: %u\n", sanityChecks[i].status); | ||||
|         // printf("  state: %u\n", sanityChecks[i].state); | ||||
|         // printf("  Sensor Limits: Max = %.2f, Min = %.2f\n", sanityChecks[i].sSensorLimit.max, sanityChecks[i].sSensorLimit.min); | ||||
|         // printf("  Last Sensor Temperature: %.2f\n", sanityChecks[i].fSensorTemperatureLast); | ||||
|  | ||||
| @ -86,7 +86,7 @@ void checkSensorSanity(void) | ||||
|         if (sCurrentMeasurement.state == MEASUREMENT_FAULT) | ||||
|         { | ||||
|             ESP_LOGE(TAG, "%s Sensor not found!", sanityChecks[i].name); | ||||
|             sanityChecks[i].status = SENSOR_NOT_FOUND; | ||||
|             sanityChecks[i].state = SENSOR_NOT_FOUND; | ||||
|             sSafetyState = SAFETY_SENSOR_ERROR; | ||||
|         } | ||||
|         else | ||||
| @ -97,7 +97,7 @@ void checkSensorSanity(void) | ||||
|                 if (sanityChecks[i].uUnchangedCounter >= (SENSOR_GRACE_PERIOD / PERIODIC_INTERVAL)) | ||||
|                 { | ||||
|                     ESP_LOGE(TAG, "%s Sensor reported unchanged value! %lf == %lf", sanityChecks[i].name, sCurrentMeasurement.fCurrentValue, sanityChecks[i].fSensorTemperatureLast); | ||||
|                     sanityChecks[i].status = SENSOR_UNCHANGED; | ||||
|                     sanityChecks[i].state = SENSOR_UNCHANGED; | ||||
|                     sSafetyState = SAFETY_SENSOR_ERROR; | ||||
|                 } | ||||
|             } | ||||
| @ -108,23 +108,23 @@ void checkSensorSanity(void) | ||||
|                 if (sCurrentMeasurement.fCurrentValue > sanityChecks[i].sSensorLimit.max) | ||||
|                 { | ||||
|                     ESP_LOGE(TAG, "%s Sensor reported too high value! %lf > %lf", sanityChecks[i].name, sCurrentMeasurement.fCurrentValue, sanityChecks[i].sSensorLimit.max); | ||||
|                     sanityChecks[i].status = SENSOR_TOO_HIGH; | ||||
|                     sanityChecks[i].state = SENSOR_TOO_HIGH; | ||||
|                     sSafetyState = SAFETY_SENSOR_ERROR; | ||||
|                 } | ||||
|                 else if (sCurrentMeasurement.fCurrentValue < sanityChecks[i].sSensorLimit.min) | ||||
|                 { | ||||
|                     ESP_LOGE(TAG, "%s Sensor reported too low value! %lf < %lf", sanityChecks[i].name, sCurrentMeasurement.fCurrentValue, sanityChecks[i].sSensorLimit.min); | ||||
|                     sanityChecks[i].status = SENSOR_TOO_LOW; | ||||
|                     sanityChecks[i].state = SENSOR_TOO_LOW; | ||||
|                     sSafetyState = SAFETY_SENSOR_ERROR; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     sanityChecks[i].uUnchangedCounter = 0U; | ||||
|                     sanityChecks[i].status = SENSOR_NO_ERROR; | ||||
|                     sanityChecks[i].state = SENSOR_NO_ERROR; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         // printf("  Status: %u\n", sanityChecks[i].status); | ||||
|         // printf("  state: %u\n", sanityChecks[i].state); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -142,7 +142,7 @@ void getSensorSanityStates(sSensorSanityCheck *pSensorSanityChecks) | ||||
|         for (size_t i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++) | ||||
|         { | ||||
|             // Copy only the needed attributes | ||||
|             pSensorSanityChecks[i].status = sanityChecks[i].status; | ||||
|             pSensorSanityChecks[i].state = sanityChecks[i].state; | ||||
|             strcpy(pSensorSanityChecks[i].name, sanityChecks[i].name); | ||||
|         } | ||||
|         xSemaphoreGiveRecursive(xMutexAccessSafety); | ||||
|  | ||||
| @ -30,7 +30,7 @@ typedef struct _TemperatureSensorLimit | ||||
| } sTemperatureSensorLimit; | ||||
| typedef struct _SensorSanityCheck | ||||
| { | ||||
|     eSensorErrorState status; | ||||
|     eSensorErrorState state; | ||||
|     char name[MAX_ERROR_STRING_SIZE]; | ||||
|     sTemperatureSensorLimit sSensorLimit; | ||||
|     float fSensorTemperatureLast; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user