refactor: optimizations & fixes

This commit is contained in:
Yurii
2024-11-11 15:45:36 +03:00
parent 24a46f4c16
commit c6df74f06e
9 changed files with 244 additions and 205 deletions

View File

@@ -77,10 +77,19 @@ public:
return; return;
} }
this->webServer->sendContent((const char*)this->buffer, this->bufferPos);
this->bufferPos = 0;
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif
auto& client = this->webServer->client();
if (client.connected()) {
this->webServer->sendContent((const char*)this->buffer, this->bufferPos);
}
this->bufferPos = 0;
#ifdef ARDUINO_ARCH_ESP8266
::optimistic_yield(1000);
#endif #endif
} }

View File

@@ -37,7 +37,7 @@ public:
case Sensors::Purpose::DHW_RETURN_TEMP: case Sensors::Purpose::DHW_RETURN_TEMP:
case Sensors::Purpose::EXHAUST_TEMP: case Sensors::Purpose::EXHAUST_TEMP:
case Sensors::Purpose::TEMPERATURE: case Sensors::Purpose::TEMPERATURE:
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -87,7 +87,7 @@ public:
break; break;
case Sensors::Purpose::HUMIDITY: case Sensors::Purpose::HUMIDITY:
doc[FPSTR(HA_DEVICE_CLASS)] = F("humidity"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_HUMIDITY);
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT);
break; break;
@@ -156,23 +156,25 @@ public:
String objId = Sensors::makeObjectId(sSensor.name); String objId = Sensors::makeObjectId(sSensor.name);
// state topic // state topic
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("sensors"), objId.c_str()); doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(
F("sensors"),
objId.c_str()
);
// set device class, name, value template for bluetooth sensors // set device class, name, value template for bluetooth sensors
// or name & value template for another sensors // or name & value template for another sensors
String sName = sSensor.name;
if (sSensor.type == Sensors::Type::BLUETOOTH) { if (sSensor.type == Sensors::Type::BLUETOOTH) {
// available state topic // available state topic
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)]; doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)];
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_SENSOR_CONN; doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_SENSOR_CONN;
String sName = sSensor.name;
switch (vType) { switch (vType) {
case Sensors::ValueType::TEMPERATURE: case Sensors::ValueType::TEMPERATURE:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("temp")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, F("temp"));
sName += F(" temperature"); sName += F(" temperature");
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -184,20 +186,20 @@ public:
break; break;
case Sensors::ValueType::HUMIDITY: case Sensors::ValueType::HUMIDITY:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("humidity")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_HUMIDITY));
sName += F(" humidity"); sName += F(" humidity");
doc[FPSTR(HA_DEVICE_CLASS)] = F("humidity"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_HUMIDITY);
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT);
doc[FPSTR(HA_NAME)] = sName; doc[FPSTR(HA_NAME)] = sName;
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.humidity|float(0)|round(2) }}"); doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.humidity|float(0)|round(2) }}");
break; break;
case Sensors::ValueType::BATTERY: case Sensors::ValueType::BATTERY:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("battery")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_BATTERY));
sName += F(" battery"); sName += F(" battery");
doc[FPSTR(HA_DEVICE_CLASS)] = F("battery"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_BATTERY);
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC);
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_PERCENT);
doc[FPSTR(HA_NAME)] = sName; doc[FPSTR(HA_NAME)] = sName;
@@ -205,7 +207,7 @@ public:
break; break;
case Sensors::ValueType::RSSI: case Sensors::ValueType::RSSI:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("rssi")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_RSSI));
sName += F(" RSSI"); sName += F(" RSSI");
doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength"); doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength");
@@ -223,10 +225,14 @@ public:
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX); doc[FPSTR(HA_MODE)] = FPSTR(HA_MODE_BOX);
doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(F("sensors"), objId.c_str(), F("set")); doc[FPSTR(HA_COMMAND_TOPIC)] = this->getDeviceTopic(
F("sensors"),
objId.c_str(),
F("set")
);
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"value\": {{ value }}}"); doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"value\": {{ value }}}");
doc[FPSTR(HA_NAME)] = sName; doc[FPSTR(HA_NAME)] = sSensor.name;
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}"); doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}");
} else { } else {
@@ -234,20 +240,15 @@ public:
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)]; doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = doc[FPSTR(HA_STATE_TOPIC)];
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_SENSOR_CONN; doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = AVAILABILITY_SENSOR_CONN;
doc[FPSTR(HA_NAME)] = sName; doc[FPSTR(HA_NAME)] = sSensor.name;
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}"); doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.value|float(0)|round(2) }}");
} }
sName.clear();
// object id's // object id's
{ doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(objId.c_str());
String objIdWithPrefix = this->getObjectIdWithPrefix(objId.c_str()); doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_UNIQUE_ID)] = objIdWithPrefix;
doc[FPSTR(HA_OBJECT_ID)] = objIdWithPrefix;
}
String configTopic = this->makeConfigTopic( const String& configTopic = this->makeConfigTopic(
sSensor.type == Sensors::Type::MANUAL ? FPSTR(HA_ENTITY_NUMBER) : FPSTR(HA_ENTITY_SENSOR), sSensor.type == Sensors::Type::MANUAL ? FPSTR(HA_ENTITY_NUMBER) : FPSTR(HA_ENTITY_SENSOR),
objId.c_str() objId.c_str()
); );
@@ -264,32 +265,35 @@ public:
} }
bool deleteDynamicSensor(Sensors::Settings& sSensor, Sensors::ValueType vType = Sensors::ValueType::PRIMARY) { bool deleteDynamicSensor(Sensors::Settings& sSensor, Sensors::ValueType vType = Sensors::ValueType::PRIMARY) {
String objId = Sensors::makeObjectId(sSensor.name); String objId;
if (sSensor.type == Sensors::Type::BLUETOOTH) { if (sSensor.type == Sensors::Type::BLUETOOTH) {
switch (vType) { switch (vType) {
case Sensors::ValueType::TEMPERATURE: case Sensors::ValueType::TEMPERATURE:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("temp")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, F("temp"));
break; break;
case Sensors::ValueType::HUMIDITY: case Sensors::ValueType::HUMIDITY:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("humidity")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_HUMIDITY));
break; break;
case Sensors::ValueType::BATTERY: case Sensors::ValueType::BATTERY:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("battery")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_BATTERY));
break; break;
case Sensors::ValueType::RSSI: case Sensors::ValueType::RSSI:
objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("rssi")); Sensors::makeObjectIdWithSuffix(objId, sSensor.name, FPSTR(S_RSSI));
break; break;
default: default:
return false; return false;
} }
} else {
Sensors::makeObjectId(objId, sSensor.name);
} }
String configTopic = this->makeConfigTopic( const String& configTopic = this->makeConfigTopic(
sSensor.type == Sensors::Type::MANUAL ? FPSTR(HA_ENTITY_NUMBER) : FPSTR(HA_ENTITY_SENSOR), sSensor.type == Sensors::Type::MANUAL ? FPSTR(HA_ENTITY_NUMBER) : FPSTR(HA_ENTITY_SENSOR),
objId.c_str() objId.c_str()
); );
@@ -303,18 +307,14 @@ public:
String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("connected")); String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("connected"));
// object id's // object id's
{ doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(objId.c_str());
String objIdWithPrefix = this->getObjectIdWithPrefix(objId.c_str()); doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_UNIQUE_ID)] = objIdWithPrefix;
doc[FPSTR(HA_OBJECT_ID)] = objIdWithPrefix;
}
// state topic // state topic
{ doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(
String parentObjId = Sensors::makeObjectId(sSensor.name); F("sensors"),
String stateTopic = this->getDeviceTopic(F("sensors"), parentObjId.c_str()); Sensors::makeObjectId(sSensor.name).c_str()
doc[FPSTR(HA_STATE_TOPIC)] = stateTopic; );
}
// sensor name // sensor name
{ {
@@ -325,7 +325,7 @@ public:
doc[FPSTR(HA_NAME)] = sName; doc[FPSTR(HA_NAME)] = sName;
} }
String configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), objId.c_str()); const String& configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), objId.c_str());
objId.clear(); objId.clear();
@@ -341,9 +341,10 @@ public:
} }
bool deleteConnectionDynamicSensor(Sensors::Settings& sSensor) { bool deleteConnectionDynamicSensor(Sensors::Settings& sSensor) {
String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("connected")); const String& configTopic = this->makeConfigTopic(
String configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), objId.c_str()); FPSTR(HA_ENTITY_BINARY_SENSOR),
objId.clear(); Sensors::makeObjectIdWithSuffix(sSensor.name, F("connected")).c_str()
);
return this->publish(configTopic.c_str()); return this->publish(configTopic.c_str());
} }
@@ -353,18 +354,14 @@ public:
String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("signal_quality")); String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("signal_quality"));
// object id's // object id's
{ doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(objId.c_str());
String objIdWithPrefix = this->getObjectIdWithPrefix(objId.c_str()); doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_UNIQUE_ID)] = objIdWithPrefix;
doc[FPSTR(HA_OBJECT_ID)] = objIdWithPrefix;
}
// state topic // state topic
{ doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(
String parentObjId = Sensors::makeObjectId(sSensor.name); F("sensors"),
String stateTopic = this->getDeviceTopic(F("sensors"), parentObjId.c_str()); Sensors::makeObjectId(sSensor.name).c_str()
doc[FPSTR(HA_STATE_TOPIC)] = stateTopic; );
}
// sensor name // sensor name
{ {
@@ -375,7 +372,7 @@ public:
doc[FPSTR(HA_NAME)] = sName; doc[FPSTR(HA_NAME)] = sName;
} }
String configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), objId.c_str()); const String& configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), objId.c_str());
objId.clear(); objId.clear();
@@ -395,9 +392,10 @@ public:
bool deleteSignalQualityDynamicSensor(Sensors::Settings& sSensor) { bool deleteSignalQualityDynamicSensor(Sensors::Settings& sSensor) {
JsonDocument doc; JsonDocument doc;
String objId = Sensors::makeObjectIdWithSuffix(sSensor.name, F("signal_quality")); const String& configTopic = this->makeConfigTopic(
String configTopic = this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), objId.c_str()); FPSTR(HA_ENTITY_SENSOR),
objId.clear(); Sensors::makeObjectIdWithSuffix(sSensor.name, F("signal_quality")).c_str()
);
return this->publish(configTopic.c_str()); return this->publish(configTopic.c_str());
} }
@@ -432,7 +430,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating_hysteresis")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating_hysteresis"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -488,7 +486,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating_min_temp")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating_min_temp"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -522,7 +520,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating_max_temp")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("heating_max_temp"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -557,7 +555,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("dhw_min_temp")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("dhw_min_temp"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -591,7 +589,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("dhw_max_temp")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("dhw_max_temp"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -742,7 +740,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("pid_min_temp")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("pid_min_temp"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -776,7 +774,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("pid_max_temp")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("pid_max_temp"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("temperature"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_TEMPERATURE);
if (unit == UnitSystem::METRIC) { if (unit == UnitSystem::METRIC) {
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C); doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = FPSTR(HA_UNIT_OF_MEASUREMENT_C);
@@ -1119,7 +1117,7 @@ public:
JsonDocument doc; JsonDocument doc;
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("rssi")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(FPSTR(S_RSSI));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_DIAGNOSTIC);
doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength"); doc[FPSTR(HA_DEVICE_CLASS)] = F("signal_strength");
@@ -1132,7 +1130,7 @@ public:
doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter;
doc.shrinkToFit(); doc.shrinkToFit();
return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), F("rssi")).c_str(), doc); return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_SENSOR), FPSTR(S_RSSI)).c_str(), doc);
} }
bool publishUptime(bool enabledByDefault = true) { bool publishUptime(bool enabledByDefault = true) {
@@ -1257,17 +1255,17 @@ public:
JsonDocument doc; JsonDocument doc;
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str(); doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("restart")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(FPSTR(S_RESTART));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("restart"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_RESTART);
doc[FPSTR(HA_NAME)] = F("Restart"); doc[FPSTR(HA_NAME)] = F("Restart");
doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str(); doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str();
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"restart\": true}}"); doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"restart\": true}}");
doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter; doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter;
doc.shrinkToFit(); doc.shrinkToFit();
return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BUTTON), F("restart")).c_str(), doc); return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_BUTTON), FPSTR(S_RESTART)).c_str(), doc);
} }
bool publishResetFaultButton(bool enabledByDefault = true) { bool publishResetFaultButton(bool enabledByDefault = true) {
@@ -1280,7 +1278,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("reset_fault")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("reset_fault"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("restart"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_RESTART);
doc[FPSTR(HA_NAME)] = F("Reset fault"); doc[FPSTR(HA_NAME)] = F("Reset fault");
doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str(); doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str();
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"resetFault\": true}}"); doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"resetFault\": true}}");
@@ -1300,7 +1298,7 @@ public:
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("reset_diagnostic")); doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectIdWithPrefix(F("reset_diagnostic"));
doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)]; doc[FPSTR(HA_OBJECT_ID)] = doc[FPSTR(HA_UNIQUE_ID)];
doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG); doc[FPSTR(HA_ENTITY_CATEGORY)] = FPSTR(HA_ENTITY_CATEGORY_CONFIG);
doc[FPSTR(HA_DEVICE_CLASS)] = F("restart"); doc[FPSTR(HA_DEVICE_CLASS)] = FPSTR(S_RESTART);
doc[FPSTR(HA_NAME)] = F("Reset diagnostic"); doc[FPSTR(HA_NAME)] = F("Reset diagnostic");
doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str(); doc[FPSTR(HA_COMMAND_TOPIC)] = this->setStateTopic.c_str();
doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"resetDiagnostic\": true}}"); doc[FPSTR(HA_COMMAND_TEMPLATE)] = F("{\"actions\": {\"resetDiagnostic\": true}}");

View File

@@ -76,17 +76,6 @@ protected:
vars.actions.restart = false; vars.actions.restart = false;
this->restartSignalTime = millis(); this->restartSignalTime = millis();
// save settings
fsSettings.updateNow();
// save sensors settings
fsSensorsSettings.updateNow();
// force save network settings
if (fsNetworkSettings.updateNow() == FD_FILE_ERR && LittleFS.begin()) {
fsNetworkSettings.write();
}
Log.sinfoln(FPSTR(L_MAIN), F("Restart signal received. Restart after 10 sec.")); Log.sinfoln(FPSTR(L_MAIN), F("Restart signal received. Restart after 10 sec."));
} }
@@ -147,8 +136,9 @@ protected:
for (Stream* stream : Log.getStreams()) { for (Stream* stream : Log.getStreams()) {
while (stream->available() > 0) { while (stream->available() > 0) {
stream->read(); stream->read();
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
} }
} }
@@ -159,7 +149,19 @@ protected:
// restart // restart
if (this->restartSignalTime > 0 && millis() - this->restartSignalTime > 10000) { if (this->restartSignalTime > 0 && millis() - this->restartSignalTime > 10000) {
// save settings
fsSettings.updateNow();
// save sensors settings
fsSensorsSettings.updateNow();
// force save network settings
if (fsNetworkSettings.updateNow() == FD_FILE_ERR && LittleFS.begin()) {
fsNetworkSettings.write();
}
this->restartSignalTime = 0; this->restartSignalTime = 0;
this->delay(500);
ESP.restart(); ESP.restart();
} }
} }

View File

@@ -129,7 +129,7 @@ protected:
#endif #endif
this->client->onMessage([this] (void*, size_t length) { this->client->onMessage([this] (void*, size_t length) {
String topic = this->client->messageTopic(); const String& topic = this->client->messageTopic();
if (!length || length > 2048 || !topic.length()) { if (!length || length > 2048 || !topic.length()) {
return; return;
} }
@@ -139,7 +139,7 @@ protected:
payload[i] = this->client->read(); payload[i] = this->client->read();
} }
this->onMessage(topic.c_str(), payload, length); this->onMessage(topic, payload, length);
}); });
// writer settings // writer settings
@@ -153,7 +153,7 @@ protected:
Log.straceln(FPSTR(L_MQTT), F("%s publish %u of %u bytes to topic: %s"), result ? F("Successfully") : F("Failed"), written, length, topic); Log.straceln(FPSTR(L_MQTT), F("%s publish %u of %u bytes to topic: %s"), result ? F("Successfully") : F("Failed"), written, length, topic);
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
//this->client->poll(); //this->client->poll();
@@ -162,13 +162,13 @@ protected:
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
this->writer->setFlushEventCallback([this] (size_t, size_t) { this->writer->setFlushEventCallback([this] (size_t, size_t) {
::delay(0); ::optimistic_yield(1000);
if (this->wifiClient->connected()) { if (this->wifiClient->connected()) {
this->wifiClient->flush(); this->wifiClient->flush();
} }
::delay(0); ::optimistic_yield(1000);
}); });
#endif #endif
@@ -222,7 +222,7 @@ protected:
} }
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
// publish variables and status // publish variables and status
@@ -295,14 +295,14 @@ protected:
this->haHelper->deleteDynamicSensor(prevSettings, Sensors::ValueType::TEMPERATURE); this->haHelper->deleteDynamicSensor(prevSettings, Sensors::ValueType::TEMPERATURE);
break; break;
case Sensors::Type::MANUAL: { case Sensors::Type::MANUAL:
String topic = this->haHelper->getDeviceTopic( this->client->unsubscribe(
F("sensors"), this->haHelper->getDeviceTopic(
Sensors::makeObjectId(prevSettings.name).c_str(), F("sensors"),
F("set") Sensors::makeObjectId(prevSettings.name).c_str(),
F("set")
).c_str()
); );
this->client->unsubscribe(topic.c_str());
}
default: default:
this->haHelper->deleteDynamicSensor(prevSettings, Sensors::ValueType::PRIMARY); this->haHelper->deleteDynamicSensor(prevSettings, Sensors::ValueType::PRIMARY);
@@ -331,14 +331,14 @@ protected:
this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::TEMPERATURE, settings.system.unitSystem); this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::TEMPERATURE, settings.system.unitSystem);
break; break;
case Sensors::Type::MANUAL: { case Sensors::Type::MANUAL:
String topic = this->haHelper->getDeviceTopic( this->client->subscribe(
F("sensors"), this->haHelper->getDeviceTopic(
Sensors::makeObjectId(prevSettings.name).c_str(), F("sensors"),
F("set") Sensors::makeObjectId(prevSettings.name).c_str(),
F("set")
).c_str()
); );
this->client->subscribe(topic.c_str());
}
default: default:
this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::PRIMARY, settings.system.unitSystem); this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::PRIMARY, settings.system.unitSystem);
@@ -372,13 +372,13 @@ protected:
Log.swarningln(FPSTR(L_MQTT), F("Disconnected (reason: %d uptime: %lu s.)"), this->client->connectError(), uptime); Log.swarningln(FPSTR(L_MQTT), F("Disconnected (reason: %d uptime: %lu s.)"), this->client->connectError(), uptime);
} }
void onMessage(const char* topic, uint8_t* payload, size_t length) { void onMessage(const String& topic, uint8_t* payload, size_t length) {
if (!length) { if (!length) {
return; return;
} }
if (settings.system.logLevel >= TinyLogger::Level::TRACE) { if (settings.system.logLevel >= TinyLogger::Level::TRACE) {
Log.strace(FPSTR(L_MQTT_MSG), F("Topic: %s\r\n> "), topic); Log.strace(FPSTR(L_MQTT_MSG), F("Topic: %s\r\n> "), topic.c_str());
if (Log.lock()) { if (Log.lock()) {
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++) {
if (payload[i] == 0) { if (payload[i] == 0) {
@@ -409,31 +409,27 @@ protected:
} }
doc.shrinkToFit(); doc.shrinkToFit();
// delete topic
this->writer->publish(topic.c_str(), nullptr, 0, true);
if (this->haHelper->getDeviceTopic(F("state/set")).equals(topic)) { if (this->haHelper->getDeviceTopic(F("state/set")).equals(topic)) {
this->writer->publish(topic, nullptr, 0, true);
if (jsonToVars(doc, vars)) { if (jsonToVars(doc, vars)) {
this->resetPublishedVarsTime(); this->resetPublishedVarsTime();
} }
} else if (this->haHelper->getDeviceTopic(F("settings/set")).equals(topic)) { } else if (this->haHelper->getDeviceTopic(F("settings/set")).equals(topic)) {
this->writer->publish(topic, nullptr, 0, true);
if (safeJsonToSettings(doc, settings)) { if (safeJsonToSettings(doc, settings)) {
this->resetPublishedSettingsTime(); this->resetPublishedSettingsTime();
fsSettings.update(); fsSettings.update();
} }
} else { } else {
this->writer->publish(topic, nullptr, 0, true); const String& sensorsTopic = this->haHelper->getDeviceTopic(F("sensors/"));
String _topic = topic;
String sensorsTopic = this->haHelper->getDeviceTopic(F("sensors/"));
auto stLength = sensorsTopic.length(); auto stLength = sensorsTopic.length();
if (_topic.startsWith(sensorsTopic) && _topic.endsWith(F("/set"))) { if (topic.startsWith(sensorsTopic) && topic.endsWith(F("/set"))) {
if (_topic.length() > stLength + 4) { if (topic.length() > stLength + 4) {
String name = _topic.substring(stLength, _topic.indexOf('/', stLength)); const String& name = topic.substring(stLength, topic.indexOf('/', stLength));
int16_t id = Sensors::getIdByObjectId(name.c_str()); int16_t id = Sensors::getIdByObjectId(name.c_str());
if (id == -1) { if (id == -1) {
@@ -515,14 +511,14 @@ protected:
this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::TEMPERATURE, settings.system.unitSystem); this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::TEMPERATURE, settings.system.unitSystem);
break; break;
case Sensors::Type::MANUAL: { case Sensors::Type::MANUAL:
String topic = this->haHelper->getDeviceTopic( this->client->subscribe(
F("sensors"), this->haHelper->getDeviceTopic(
Sensors::makeObjectId(sSettings.name).c_str(), F("sensors"),
F("set") Sensors::makeObjectId(sSettings.name).c_str(),
F("set")
).c_str()
); );
this->client->subscribe(topic.c_str());
}
default: default:
this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::PRIMARY, settings.system.unitSystem); this->haHelper->publishDynamicSensor(sSettings, Sensors::ValueType::PRIMARY, settings.system.unitSystem);
@@ -603,12 +599,14 @@ protected:
sensorResultToJson(sensorId, doc); sensorResultToJson(sensorId, doc);
doc.shrinkToFit(); doc.shrinkToFit();
String topic = this->haHelper->getDeviceTopic( return this->writer->publish(
F("sensors"), this->haHelper->getDeviceTopic(
Sensors::makeObjectId(sSettings.name).c_str() F("sensors"),
Sensors::makeObjectId(sSettings.name).c_str()
).c_str(),
doc,
true
); );
return this->writer->publish(topic.c_str(), doc, true);
} }
bool publishVariables(const char* topic) { bool publishVariables(const char* topic) {

View File

@@ -232,7 +232,7 @@ protected:
} }
} }
String plain = this->webServer->arg(0); const String& plain = this->webServer->arg(0);
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/backup/restore %d bytes: %s"), plain.length(), plain.c_str()); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/backup/restore %d bytes: %s"), plain.length(), plain.c_str());
if (plain.length() < 5) { if (plain.length() < 5) {
@@ -246,7 +246,6 @@ protected:
JsonDocument doc; JsonDocument doc;
DeserializationError dErr = deserializeJson(doc, plain); DeserializationError dErr = deserializeJson(doc, plain);
plain.clear();
if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) { if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) {
this->webServer->send(400); this->webServer->send(400);
@@ -254,12 +253,6 @@ protected:
} }
bool changed = false; bool changed = false;
if (!doc[FPSTR(S_SETTINGS)].isNull() && jsonToSettings(doc[FPSTR(S_SETTINGS)], settings)) {
vars.actions.restart = true;
fsSettings.update();
changed = true;
}
if (!doc[FPSTR(S_NETWORK)].isNull() && jsonToNetworkSettings(doc[FPSTR(S_NETWORK)], networkSettings)) { if (!doc[FPSTR(S_NETWORK)].isNull() && jsonToNetworkSettings(doc[FPSTR(S_NETWORK)], networkSettings)) {
fsNetworkSettings.update(); fsNetworkSettings.update();
network->setHostname(networkSettings.hostname) network->setHostname(networkSettings.hostname)
@@ -271,27 +264,40 @@ protected:
networkSettings.staticConfig.gateway, networkSettings.staticConfig.gateway,
networkSettings.staticConfig.subnet, networkSettings.staticConfig.subnet,
networkSettings.staticConfig.dns networkSettings.staticConfig.dns
) );
->reconnect(); changed = true;
}
if (!doc[FPSTR(S_SETTINGS)].isNull() && jsonToSettings(doc[FPSTR(S_SETTINGS)], settings)) {
fsSettings.update();
changed = true; changed = true;
} }
if (!doc[FPSTR(S_SENSORS)].isNull()) { if (!doc[FPSTR(S_SENSORS)].isNull()) {
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) { for (auto sensor : doc[FPSTR(S_SENSORS)].as<JsonObject>()) {
if (doc[FPSTR(S_SENSORS)][sensorId].isNull()) { if (!isDigit(sensor.key().c_str())) {
continue; continue;
} }
auto sensorSettingsDoc = doc[FPSTR(S_SENSORS)][sensorId].to<JsonObject>(); int sensorId = atoi(sensor.key().c_str());
if (jsonToSensorSettings(sensorId, sensorSettingsDoc, Sensors::settings[sensorId])){ if (sensorId < 0 || sensorId > 255 || !Sensors::isValidSensorId(sensorId)) {
continue;
}
if (jsonToSensorSettings(sensorId, sensor.value(), Sensors::settings[sensorId])) {
fsSensorsSettings.update();
changed = true; changed = true;
} }
} }
} }
doc.clear(); doc.clear();
doc.shrinkToFit(); doc.shrinkToFit();
if (changed) {
vars.actions.restart = true;
}
this->webServer->send(changed ? 201 : 200); this->webServer->send(changed ? 201 : 200);
}); });
@@ -317,7 +323,7 @@ protected:
} }
} }
String plain = this->webServer->arg(0); const String& plain = this->webServer->arg(0);
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/network/settings %d bytes: %s"), plain.length(), plain.c_str()); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/network/settings %d bytes: %s"), plain.length(), plain.c_str());
if (plain.length() < 5) { if (plain.length() < 5) {
@@ -331,7 +337,6 @@ protected:
JsonDocument doc; JsonDocument doc;
DeserializationError dErr = deserializeJson(doc, plain); DeserializationError dErr = deserializeJson(doc, plain);
plain.clear();
if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) { if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) {
this->webServer->send(400); this->webServer->send(400);
@@ -390,7 +395,7 @@ protected:
JsonDocument doc; JsonDocument doc;
for (short int i = 0; i < apCount; i++) { for (short int i = 0; i < apCount; i++) {
String ssid = WiFi.SSID(i); const String& ssid = WiFi.SSID(i);
doc[i][FPSTR(S_SSID)] = ssid; doc[i][FPSTR(S_SSID)] = ssid;
doc[i][FPSTR(S_BSSID)] = WiFi.BSSIDstr(i); doc[i][FPSTR(S_BSSID)] = WiFi.BSSIDstr(i);
doc[i][FPSTR(S_SIGNAL_QUALITY)] = NetworkMgr::rssiToSignalQuality(WiFi.RSSI(i)); doc[i][FPSTR(S_SIGNAL_QUALITY)] = NetworkMgr::rssiToSignalQuality(WiFi.RSSI(i));
@@ -433,7 +438,7 @@ protected:
} }
} }
String plain = this->webServer->arg(0); const String& plain = this->webServer->arg(0);
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/settings %d bytes: %s"), plain.length(), plain.c_str()); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/settings %d bytes: %s"), plain.length(), plain.c_str());
if (plain.length() < 5) { if (plain.length() < 5) {
@@ -447,7 +452,6 @@ protected:
JsonDocument doc; JsonDocument doc;
DeserializationError dErr = deserializeJson(doc, plain); DeserializationError dErr = deserializeJson(doc, plain);
plain.clear();
if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) { if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) {
this->webServer->send(400); this->webServer->send(400);
@@ -618,7 +622,7 @@ protected:
} }
} }
String plain = this->webServer->arg(0); const String& plain = this->webServer->arg(0);
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/vars %d bytes: %s"), plain.length(), plain.c_str()); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Request /api/vars %d bytes: %s"), plain.length(), plain.c_str());
if (plain.length() < 5) { if (plain.length() < 5) {
@@ -632,7 +636,6 @@ protected:
JsonDocument doc; JsonDocument doc;
DeserializationError dErr = deserializeJson(doc, plain); DeserializationError dErr = deserializeJson(doc, plain);
plain.clear();
if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) { if (dErr != DeserializationError::Ok || doc.isNull() || !doc.size()) {
this->webServer->send(400); this->webServer->send(400);
@@ -829,7 +832,7 @@ protected:
this->webServer->onNotFound([this]() { this->webServer->onNotFound([this]() {
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Page not found, uri: %s"), this->webServer->uri().c_str()); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Page not found, uri: %s"), this->webServer->uri().c_str());
const String uri = this->webServer->uri(); const String& uri = this->webServer->uri();
if (uri.equals(F("/"))) { if (uri.equals(F("/"))) {
this->webServer->send(200, F("text/plain"), F("The file system is not flashed!")); this->webServer->send(200, F("text/plain"), F("The file system is not flashed!"));
@@ -856,7 +859,7 @@ protected:
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Started: AP up or STA connected")); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Started: AP up or STA connected"));
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
} else if (this->stateWebServer() && !network->isApEnabled() && !network->isStaEnabled()) { } else if (this->stateWebServer() && !network->isApEnabled() && !network->isStaEnabled()) {
@@ -864,7 +867,7 @@ protected:
Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Stopped: AP and STA down")); Log.straceln(FPSTR(L_PORTAL_WEBSERVER), F("Stopped: AP and STA down"));
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
} }
@@ -874,7 +877,7 @@ protected:
Log.straceln(FPSTR(L_PORTAL_DNSSERVER), F("Started: AP up")); Log.straceln(FPSTR(L_PORTAL_DNSSERVER), F("Started: AP up"));
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
} else if (this->stateDnsServer() && (!network->isApEnabled() || !this->stateWebServer())) { } else if (this->stateDnsServer() && (!network->isApEnabled() || !this->stateWebServer())) {
@@ -882,14 +885,15 @@ protected:
Log.straceln(FPSTR(L_PORTAL_DNSSERVER), F("Stopped: AP down")); Log.straceln(FPSTR(L_PORTAL_DNSSERVER), F("Stopped: AP down"));
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
} }
if (this->stateDnsServer()) { if (this->stateDnsServer()) {
this->dnsServer->processNextRequest(); this->dnsServer->processNextRequest();
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
::delay(0); ::optimistic_yield(1000);
#endif #endif
} }
@@ -907,7 +911,7 @@ protected:
} }
void onCaptivePortal() { void onCaptivePortal() {
const String uri = this->webServer->uri(); const String& uri = this->webServer->uri();
if (uri.equals(F("/connecttest.txt"))) { if (uri.equals(F("/connecttest.txt"))) {
this->webServer->sendHeader(F("Location"), F("http://logout.net")); this->webServer->sendHeader(F("Location"), F("http://logout.net"));
@@ -927,10 +931,10 @@ protected:
} else { } else {
String portalUrl = F("http://"); String portalUrl = F("http://");
portalUrl += network->getApIp().toString(); portalUrl += network->getApIp().toString().c_str();
portalUrl += '/'; portalUrl += '/';
this->webServer->sendHeader(F("Location"), portalUrl.c_str()); this->webServer->sendHeader(F("Location"), portalUrl);
this->webServer->send(302); this->webServer->send(302);
Log.straceln(FPSTR(L_PORTAL_CAPTIVE), F("Redirect to portal page with 302 code")); Log.straceln(FPSTR(L_PORTAL_CAPTIVE), F("Redirect to portal page with 302 code"));

View File

@@ -146,9 +146,10 @@ public:
return 0; return 0;
} }
String refObjectId;
for (uint8_t id = 0; id < getMaxSensorId(); id++) { for (uint8_t id = 0; id < getMaxSensorId(); id++) {
String _objectId = Sensors::makeObjectId(settings[id].name); Sensors::makeObjectId(refObjectId, settings[id].name);
if (strcmp(_objectId.c_str(), objectId) == 0) { if (refObjectId.equals(objectId)) {
return id; return id;
} }
} }
@@ -351,13 +352,10 @@ public:
return false; return false;
} }
template <class T> static String& cleanName(String& value, char space = ' ') {
static String cleanName(T value, char space = ' ') {
String clean = value;
// only valid symbols // only valid symbols
for (uint8_t pos = 0; pos < clean.length(); pos++) { for (uint8_t pos = 0; pos < value.length(); pos++) {
char symbol = clean.charAt(pos); char symbol = value.charAt(pos);
// 0..9 // 0..9
if (symbol >= 48 && symbol <= 57) { if (symbol >= 48 && symbol <= 57) {
@@ -379,39 +377,68 @@ public:
continue; continue;
} }
clean.setCharAt(pos, space); value.setCharAt(pos, space);
} }
clean.trim(); value.trim();
return clean; return value;
}
template <class T>
static String cleanName(T value, char space = ' ') {
String res = value;
return cleanName(res, space);
}
template <class T>
static String& makeObjectId(String& res, T value, char separator = '_') {
res = value;
cleanName(res);
res.toLowerCase();
res.replace(' ', separator);
return res;
} }
template <class T> template <class T>
static String makeObjectId(T value, char separator = '_') { static String makeObjectId(T value, char separator = '_') {
auto objId = cleanName(value); String res;
objId.toLowerCase(); makeObjectId(res, value, separator);
objId.replace(' ', separator);
return objId; return res;
} }
template <class TV, class TS> template <class TV, class TS>
static auto makeObjectIdWithSuffix(TV value, TS suffix, char separator = '_') { static String& makeObjectIdWithSuffix(String& res, TV value, TS suffix, char separator = '_') {
auto objId = makeObjectId(value, separator); res.clear();
objId += separator; makeObjectId(res, value, separator);
objId += suffix; res += separator;
res += suffix;
return objId; return res;
}
template <class TV, class TS>
static String makeObjectIdWithSuffix(TV value, TS suffix, char separator = '_') {
String res;
makeObjectIdWithSuffix(res, value, suffix, separator);
return res;
} }
template <class TV, class TP> template <class TV, class TP>
static auto makeObjectIdWithPrefix(TV value, TP prefix, char separator = '_') { static String& makeObjectIdWithPrefix(String& res, TV value, TP prefix, char separator = '_') {
String objId = prefix; res = prefix;
objId += separator; res += separator;
objId += makeObjectId(value, separator); res += makeObjectId(value, separator).c_str();
return objId; return res;
}
template <class TV, class TP>
static String makeObjectIdWithPrefix(TV value, TP prefix, char separator = '_') {
String res;
return makeObjectIdWithPrefix(res, value, prefix, separator);
} }
static uint8_t bluetoothRssiToQuality(int rssi) { static uint8_t bluetoothRssiToQuality(int rssi) {

View File

@@ -154,7 +154,7 @@ Sensors::Settings sensorsSettings[SENSORS_AMOUNT] = {
false, false,
"Outdoor temp", "Outdoor temp",
Sensors::Purpose::OUTDOOR_TEMP, Sensors::Purpose::OUTDOOR_TEMP,
Sensors::Type::DALLAS_TEMP, Sensors::Type::OT_OUTDOOR_TEMP,
DEFAULT_SENSOR_OUTDOOR_GPIO DEFAULT_SENSOR_OUTDOOR_GPIO
}, },
{ {

View File

@@ -1461,7 +1461,8 @@ bool jsonToSensorSettings(const uint8_t sensorId, const JsonVariantConst src, Se
// name // name
if (!src[FPSTR(S_NAME)].isNull()) { if (!src[FPSTR(S_NAME)].isNull()) {
String value = Sensors::cleanName(src[FPSTR(S_NAME)].as<String>()); auto value = src[FPSTR(S_NAME)].as<String>();
Sensors::cleanName(value);
if (value.length() < sizeof(dst.name) && !value.equals(dst.name)) { if (value.length() < sizeof(dst.name) && !value.equals(dst.name)) {
strcpy(dst.name, value.c_str()); strcpy(dst.name, value.c_str());

View File

@@ -306,22 +306,6 @@ const setupRestoreBackupForm = (formSelector) => {
try { try {
const data = JSON.parse(event.target.result); const data = JSON.parse(event.target.result);
console.log("Backup: ", data); console.log("Backup: ", data);
if (data.network != undefined) {
let response = await fetch(url, {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({"network": data.network})
});
if (!response.ok) {
onFailed();
return;
}
}
if (data.settings != undefined) { if (data.settings != undefined) {
let response = await fetch(url, { let response = await fetch(url, {
@@ -362,6 +346,22 @@ const setupRestoreBackupForm = (formSelector) => {
} }
} }
if (data.network != undefined) {
let response = await fetch(url, {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({"network": data.network})
});
if (!response.ok) {
onFailed();
return;
}
}
onSuccess(); onSuccess();
} catch (err) { } catch (err) {