From 4ef6c8bd08b2baf42dea7ebe2ad505efe2c3418f36f5b34736aa3eea8476ac04 Mon Sep 17 00:00:00 2001 From: localhorst Date: Sat, 21 Dec 2024 22:02:16 +0100 Subject: [PATCH 1/2] add control status --- README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++- main/control.c | 11 ++++++++-- main/control.h | 13 +++++++++++- main/metrics.c | 17 +++++++++++----- main/safety.c | 16 +++++++-------- main/safety.h | 2 +- 6 files changed, 95 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e583a8f..af69041 100644 --- a/README.md +++ b/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 | + + diff --git a/main/control.c b/main/control.c index c10da7e..a833069 100644 --- a/main/control.c +++ b/main/control.c @@ -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); } -} \ No newline at end of file +} + +eControlState getControlState(void) +{ + return sControlState; +} diff --git a/main/control.h b/main/control.h index 67170a0..bd80ca4 100644 --- a/main/control.h +++ b/main/control.h @@ -1,3 +1,14 @@ #pragma once -void initControl(void); \ No newline at end of file +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); \ No newline at end of file diff --git a/main/metrics.c b/main/metrics.c index 0f24436..278d2c2 100644 --- a/main/metrics.c +++ b/main/metrics.c @@ -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++; diff --git a/main/safety.c b/main/safety.c index 4513822..db60a87 100644 --- a/main/safety.c +++ b/main/safety.c @@ -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); diff --git a/main/safety.h b/main/safety.h index f7dce1c..825e7cd 100644 --- a/main/safety.h +++ b/main/safety.h @@ -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; From 23e8f05df9d6d05efa9b49e90f3a974718b96dbceb2994f7fbcd06aaa67d5dcc Mon Sep 17 00:00:00 2001 From: localhorst Date: Sat, 21 Dec 2024 22:11:46 +0100 Subject: [PATCH 2/2] add status encoding --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index af69041..22859b8 100644 --- a/README.md +++ b/README.md @@ -111,24 +111,52 @@ wifi_rssi -63 - 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 | +| 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 | +##### Safety Loop + - safety_state +| Enum eSafetyState in [safety.h](main/safety.h) | Value | Description | +|------------------------------------------------|-------|----------------------------| +| SAFETY_NO_ERROR | 0 | | +| SAFETY_SENSOR_ERROR | 1 | At least one sensor failed | +| SAFETY_INTERNAL_ERROR | 2 | Internal error | + +##### Control Loop + - control_state + +| Enum eControlState in [control.h](main/control.h) | Value | Description | +|---------------------------------------------------|-------|-----------------------| +| CONTROL_STARTING | 0 | | +| CONTROL_HEATING | 1 | Burner running | +| CONTROL_OUTDOOR_TOO_WARM | 2 | Heating not needed | +| CONTROL_RETURN_FLOW_TOO_WARM | 3 | Heating not needed | +| CONTROL_BURNER_FAULT | 4 | Burner reported fault | +| CONTROL_FAULT | 5 | Unable to control | + +##### SNTP Client + - sntp_state + +| Enum eSntpState in [sntp.h](main/sntp.h) | Value | Description | +|------------------------------------------|-------|-------------| +| SYNC_SUCCESSFUL | 0 | | +| SYNC_NOT_STARTED | 1 | | +| SYNC_FAILED | 2 | | ## Hardware -| Function | ESP32 | PLC ES32C14 | -|---------------------------------------|-------|---------------------------| -| Output CirculationPump | IO27 | Relay 1 NC1 | -| Output Burner Fire Signal | IO14 | Relay 2 NC2 | -| Output Safety Contact (powers Burner) | IO12 | Relay 3 NC2 | -| Input Burner Fault | IO19 | Digital Input IN1 | -| Input Temperature DS10B20 | IO04 | 1-Wire | +| Function | ESP32 | PLC ES32C14 | +|---------------------------------------|-------|-------------------| +| Output CirculationPump | IO27 | Relay 1 NC1 | +| Output Burner Fire Signal | IO14 | Relay 2 NC2 | +| Output Safety Contact (powers Burner) | IO12 | Relay 3 NC2 | +| Input Burner Fault | IO19 | Digital Input IN1 | +| Input Temperature DS10B20 | IO04 | 1-Wire |