add is_system to analog sensor so internal sensors cannot be removed

This commit is contained in:
proddy
2025-11-08 16:30:40 +01:00
parent 3fd05c8eb7
commit dc838639b2
7 changed files with 62 additions and 43 deletions

View File

@@ -447,6 +447,7 @@ const SensorsAnalogDialog = ({
<Box flexGrow={1} sx={{ '& button': { mt: 0 } }}> <Box flexGrow={1} sx={{ '& button': { mt: 0 } }}>
<Button <Button
startIcon={<RemoveIcon />} startIcon={<RemoveIcon />}
disabled={editItem.s}
variant="outlined" variant="outlined"
color="warning" color="warning"
onClick={remove} onClick={remove}

View File

@@ -95,6 +95,7 @@ export interface AnalogSensor {
f: number; f: number;
t: number; t: number;
d: boolean; // deleted flag d: boolean; // deleted flag
s: boolean; // system customization flag
o_n?: string; o_n?: string;
} }

View File

@@ -52,18 +52,23 @@ void AnalogSensor::start(const bool factory_settings) {
// if (factory_settings && EMSESP::nvs_.getString("boot").equals("E32V2_2") && EMSESP::nvs_.getString("hwrevision").equals("3.0")) { // if (factory_settings && EMSESP::nvs_.getString("boot").equals("E32V2_2") && EMSESP::nvs_.getString("hwrevision").equals("3.0")) {
if (factory_settings && analogReadMilliVolts(39) > 700) { // core voltage > 2.6V if (factory_settings && analogReadMilliVolts(39) > 700) { // core voltage > 2.6V
EMSESP::webCustomizationService.update([&](WebCustomization & settings) { EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
auto newSensor = AnalogCustomization(); auto newSensor = AnalogCustomization();
newSensor.gpio = 39;
newSensor.name = "core_voltage"; newSensor.gpio = 39;
newSensor.offset = 0; newSensor.name = "core_voltage";
newSensor.factor = 0.00377136; // Divider 24k - 8,66k newSensor.offset = 0;
newSensor.uom = DeviceValueUOM::VOLTS; newSensor.factor = 0.00377136; // Divider 24k - 8,66k
newSensor.type = AnalogType::ADC; newSensor.uom = DeviceValueUOM::VOLTS;
newSensor.type = AnalogType::ADC;
newSensor.is_system = true;
settings.analogCustomizations.push_back(newSensor); settings.analogCustomizations.push_back(newSensor);
newSensor.gpio = 36;
newSensor.name = "supply_voltage"; newSensor.gpio = 36;
newSensor.factor = 0.017; // Divider 24k - 1,5k newSensor.name = "supply_voltage";
newSensor.factor = 0.017; // Divider 24k - 1,5k
newSensor.is_system = true;
settings.analogCustomizations.push_back(newSensor); settings.analogCustomizations.push_back(newSensor);
return StateUpdateResult::CHANGED; // persist the change return StateUpdateResult::CHANGED; // persist the change
}); });
} }
@@ -469,7 +474,7 @@ void AnalogSensor::loop() {
// update analog information name and offset // update analog information name and offset
// a type value of -1 is used to delete the sensor // a type value of -1 is used to delete the sensor
bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted) { bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted, bool is_system) {
// first see if we can find the sensor in our customization list // first see if we can find the sensor in our customization list
bool found_sensor = false; bool found_sensor = false;
EMSESP::webCustomizationService.update([&](WebCustomization & settings) { EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
@@ -496,11 +501,12 @@ bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, doubl
if (name != AnalogCustomization.name) { if (name != AnalogCustomization.name) {
EMSESP::nvs_.remove(AnalogCustomization.name.c_str()); EMSESP::nvs_.remove(AnalogCustomization.name.c_str());
} }
AnalogCustomization.name = name; AnalogCustomization.name = name;
AnalogCustomization.offset = offset; AnalogCustomization.offset = offset;
AnalogCustomization.factor = factor; AnalogCustomization.factor = factor;
AnalogCustomization.uom = uom; AnalogCustomization.uom = uom;
AnalogCustomization.type = type; AnalogCustomization.type = type;
AnalogCustomization.is_system = is_system;
LOG_DEBUG("Customizing existing analog GPIO %02d", gpio); LOG_DEBUG("Customizing existing analog GPIO %02d", gpio);
} }
return StateUpdateResult::CHANGED; // persist the change return StateUpdateResult::CHANGED; // persist the change
@@ -517,13 +523,14 @@ bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, doubl
// we didn't find it, it's new, so create and store it in the customization list // we didn't find it, it's new, so create and store it in the customization list
if (!found_sensor) { if (!found_sensor) {
EMSESP::webCustomizationService.update([&](WebCustomization & settings) { EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
auto newSensor = AnalogCustomization(); auto newSensor = AnalogCustomization();
newSensor.gpio = gpio; newSensor.gpio = gpio;
newSensor.name = name; newSensor.name = name;
newSensor.offset = offset; newSensor.offset = offset;
newSensor.factor = factor; newSensor.factor = factor;
newSensor.uom = uom; newSensor.uom = uom;
newSensor.type = type; newSensor.type = type;
newSensor.is_system = false;
settings.analogCustomizations.push_back(newSensor); settings.analogCustomizations.push_back(newSensor);
LOG_DEBUG("Adding new customization for analog sensor GPIO %02d", gpio); LOG_DEBUG("Adding new customization for analog sensor GPIO %02d", gpio);
return StateUpdateResult::CHANGED; // persist the change return StateUpdateResult::CHANGED; // persist the change
@@ -836,7 +843,8 @@ void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) {
output["readable"] = true; output["readable"] = true;
output["writeable"] = sensor.type() == AnalogType::COUNTER || sensor.type() == AnalogType::RGB || sensor.type() == AnalogType::PULSE output["writeable"] = sensor.type() == AnalogType::COUNTER || sensor.type() == AnalogType::RGB || sensor.type() == AnalogType::PULSE
|| (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2); || (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2);
output["visible"] = true; output["visible"] = true;
output["is_system"] = sensor.is_system();
if (sensor.type() == AnalogType::COUNTER) { if (sensor.type() == AnalogType::COUNTER) {
output["min"] = 0; output["min"] = 0;
output["max"] = 4000000; output["max"] = 4000000;

View File

@@ -61,6 +61,10 @@ class AnalogSensor {
value_ = value; value_ = value;
} }
bool is_system() const {
return is_system_;
}
double factor() const { double factor() const {
return factor_; return factor_;
} }
@@ -105,8 +109,9 @@ class AnalogSensor {
double offset_; double offset_;
double factor_; double factor_;
uint8_t uom_; uint8_t uom_;
double value_; // double because of the factor is a double double value_; // double because of the factor is a double
int8_t type_; // one of the AnalogType enum int8_t type_; // one of the AnalogType enum
bool is_system_; // if true, the sensor is a system sensor
}; };
AnalogSensor() = default; AnalogSensor() = default;
@@ -167,7 +172,7 @@ class AnalogSensor {
return sensors_.size(); return sensors_.size();
} }
bool update(uint8_t gpio, std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false); bool update(uint8_t gpio, std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false, bool is_system = false);
bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1); bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1);
void store_counters(); void store_counters();

View File

@@ -63,13 +63,14 @@ void WebCustomization::read(WebCustomization & customizations, JsonObject root)
// Analog Sensor customization // Analog Sensor customization
JsonArray analogJson = root["as"].to<JsonArray>(); JsonArray analogJson = root["as"].to<JsonArray>();
for (const AnalogCustomization & sensor : customizations.analogCustomizations) { for (const AnalogCustomization & sensor : customizations.analogCustomizations) {
JsonObject sensorJson = analogJson.add<JsonObject>(); JsonObject sensorJson = analogJson.add<JsonObject>();
sensorJson["gpio"] = sensor.gpio; // g sensorJson["gpio"] = sensor.gpio; // g
sensorJson["name"] = sensor.name; // n sensorJson["name"] = sensor.name; // n
sensorJson["offset"] = sensor.offset; // o sensorJson["offset"] = sensor.offset; // o
sensorJson["factor"] = sensor.factor; // f sensorJson["factor"] = sensor.factor; // f
sensorJson["uom"] = sensor.uom; // u sensorJson["uom"] = sensor.uom; // u
sensorJson["type"] = sensor.type; // t sensorJson["type"] = sensor.type; // t
sensorJson["is_system"] = sensor.is_system; // s
} }
// Masked entities customization and custom device name (optional) // Masked entities customization and custom device name (optional)
@@ -115,13 +116,14 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
auto analogJsons = root["as"].as<JsonArray>(); auto analogJsons = root["as"].as<JsonArray>();
for (const JsonObject analogJson : analogJsons) { for (const JsonObject analogJson : analogJsons) {
// create each of the sensor, overwriting any previous settings // create each of the sensor, overwriting any previous settings
auto analog = AnalogCustomization(); auto analog = AnalogCustomization();
analog.gpio = analogJson["gpio"]; analog.gpio = analogJson["gpio"];
analog.name = analogJson["name"].as<std::string>(); analog.name = analogJson["name"].as<std::string>();
analog.offset = analogJson["offset"]; analog.offset = analogJson["offset"];
analog.factor = analogJson["factor"]; analog.factor = analogJson["factor"];
analog.uom = analogJson["uom"]; analog.uom = analogJson["uom"];
analog.type = analogJson["type"]; analog.type = analogJson["type"];
analog.is_system = analogJson["is_system"];
if (_start && analog.type == EMSESP::analogsensor_.AnalogType::DIGITAL_OUT && analog.uom > DeviceValue::DeviceValueUOM::NONE) { if (_start && analog.type == EMSESP::analogsensor_.AnalogType::DIGITAL_OUT && analog.uom > DeviceValue::DeviceValueUOM::NONE) {
analog.offset = analog.uom - 1; analog.offset = analog.uom - 1;
} }

View File

@@ -45,8 +45,9 @@ class AnalogCustomization {
std::string name; std::string name;
double offset; double offset;
double factor; double factor;
uint8_t uom; // 0 is none uint8_t uom; // 0 is none
int8_t type; // -1 is for deletion int8_t type; // -1 is for deletion
bool is_system = false; // if true, the customization is a system customization
// used for removing from a list // used for removing from a list
bool operator==(const AnalogCustomization & a) const { bool operator==(const AnalogCustomization & a) const {

View File

@@ -143,6 +143,7 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
obj["o"] = sensor.offset(); obj["o"] = sensor.offset();
obj["f"] = sensor.factor(); obj["f"] = sensor.factor();
obj["t"] = sensor.type(); obj["t"] = sensor.type();
obj["s"] = sensor.is_system();
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) { if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
obj["v"] = Helpers::transformNumFloat(sensor.value()); // is optional and is a float obj["v"] = Helpers::transformNumFloat(sensor.value()); // is optional and is a float