diff --git a/ConfigFile.cpp b/ConfigFile.cpp index f2567cf..ca09fe4 100644 --- a/ConfigFile.cpp +++ b/ConfigFile.cpp @@ -360,11 +360,21 @@ bool ShadeConfigFile::writeShadeRecord(SomfyShade *shade) { this->writeUInt32(rem->getRemoteAddress()); } this->writeUInt16(shade->lastRollingCode); - this->writeUInt8(shade->flags & static_cast(somfy_flags_t::SunFlag)); - this->writeFloat(shade->myPos, 5); - this->writeFloat(shade->myTiltPos, 5); - this->writeFloat(shade->currentPos, 5); - this->writeFloat(shade->currentTiltPos, 5, CFG_REC_END); + if(shade->getShadeId() != 255) { + this->writeUInt8(shade->flags & static_cast(somfy_flags_t::SunFlag)); + this->writeFloat(shade->myPos, 5); + this->writeFloat(shade->myTiltPos, 5); + this->writeFloat(shade->currentPos, 5); + this->writeFloat(shade->currentTiltPos, 5, CFG_REC_END); + } + else { + // Make sure that we write cleared values when the shade is deleted. + this->writeUInt8(0); + this->writeFloat(-1.0f, 5); // MyPos + this->writeFloat(-1.0f, 5); // MyTiltPos + this->writeFloat(0.0f, 5); // currentPos + this->writeFloat(0.0f, 5, CFG_REC_END); // currentTiltPos + } return true; } bool ShadeConfigFile::exists() { return LittleFS.exists("/shades.cfg"); } diff --git a/MQTT.cpp b/MQTT.cpp index d1adb27..ae41771 100644 --- a/MQTT.cpp +++ b/MQTT.cpp @@ -18,8 +18,13 @@ bool MQTTClass::begin() { } bool MQTTClass::end() { this->disconnect(); + this->lastConnect = 0; + this->connect(); return true; } +void MQTTClass::reset() { + this->disconnect(); +} bool MQTTClass::loop() { if(settings.MQTT.enabled && !mqttClient.connected()) this->connect(); @@ -121,6 +126,7 @@ bool MQTTClass::connect() { this->subscribe("shades/+/tiltTarget/set"); this->subscribe("shades/+/direction/set"); this->subscribe("shades/+/mypos/set"); + this->subscribe("shades/+/myTiltPos/set"); this->subscribe("shades/+/sunFlag/set"); mqttClient.setCallback(MQTTClass::receive); this->lastConnect = millis(); @@ -144,6 +150,7 @@ bool MQTTClass::disconnect() { this->unsubscribe("shades/+/direction/set"); this->unsubscribe("shades/+/tiltTarget/set"); this->unsubscribe("shades/+/mypos/set"); + this->unsubscribe("shades/+/myTiltPos/set"); this->unsubscribe("shades/+/sunFlag/set"); mqttClient.disconnect(); } @@ -156,6 +163,8 @@ bool MQTTClass::unsubscribe(const char *topic) { snprintf(top, sizeof(top), "%s/%s", settings.MQTT.rootTopic, topic); else strlcpy(top, topic, sizeof(top)); + Serial.print("MQTT Unsubscribed from:"); + Serial.println(top); return mqttClient.unsubscribe(top); } return true; diff --git a/MQTT.h b/MQTT.h index cf7ea31..338c3da 100644 --- a/MQTT.h +++ b/MQTT.h @@ -13,6 +13,7 @@ class MQTTClass { bool connect(); bool disconnect(); bool connected(); + void reset(); bool publish(const char *topic, const char *payload); bool publish(const char *topic, JsonDocument &doc); bool publish(const char *topic, JsonArray &arr); diff --git a/Somfy.cpp b/Somfy.cpp index 7475976..99b75a4 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -971,7 +971,9 @@ void SomfyShade::publish() { snprintf(topic, sizeof(topic), "shades/%u/lastRollingCode", this->shadeId); mqtt.publish(topic, this->lastRollingCode); snprintf(topic, sizeof(topic), "shades/%u/mypos", this->shadeId); - mqtt.publish(topic, static_cast(floor(this->myPos))); + mqtt.publish(topic, static_cast(floor(this->myPos))); + snprintf(topic, sizeof(topic), "shades/%u/myTiltPos", this->shadeId); + mqtt.publish(topic, static_cast(floor(this->myTiltPos))); snprintf(topic, sizeof(topic), "shades/%u/shadeType", this->shadeId); mqtt.publish(topic, static_cast(this->shadeType)); snprintf(topic, sizeof(topic), "shades/%u/tiltType", this->shadeId); @@ -987,6 +989,18 @@ void SomfyShade::publish() { snprintf(topic, sizeof(topic), "shades/%u/tiltTarget", this->shadeId); mqtt.publish(topic, static_cast(floor(this->tiltTarget))); } + else if (this->shadeType == shade_types::awning) { + const uint8_t sunFlag = !!(this->flags & static_cast(somfy_flags_t::SunFlag)); + const uint8_t isSunny = !!(this->flags & static_cast(somfy_flags_t::Sunny)); + const uint8_t isWindy = !!(this->flags & static_cast(somfy_flags_t::Windy)); + + snprintf(topic, sizeof(topic), "shades/%u/sunFlag", this->shadeId); + mqtt.publish(topic, sunFlag); + snprintf(topic, sizeof(topic), "shades/%u/sunny", this->shadeId); + mqtt.publish(topic, isSunny); + snprintf(topic, sizeof(topic), "shades/%u/windy", this->shadeId); + mqtt.publish(topic, isWindy); + } } } void SomfyShade::emitState(const char *evt) { this->emitState(255, evt); } @@ -1898,6 +1912,13 @@ bool SomfyShadeController::deleteShade(uint8_t shadeId) { if(this->shades[i].getShadeId() == shadeId) { shades[i].emitState("shadeRemoved"); this->shades[i].setShadeId(255); + this->shades[i].currentPos = 0; + this->shades[i].currentTiltPos = 0; + this->shades[i].myPos = -1.0f; + this->shades[i].myTiltPos = -1.0f; + this->shades[i].shadeType = shade_types::roller; + this->shades[i].tiltType = tilt_types::none; + this->shades[i].flags = 0; } } if(this->useNVS()) { diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index cb1695e..e4a6876 100644 Binary files a/SomfyController.ino.esp32.bin and b/SomfyController.ino.esp32.bin differ diff --git a/Web.cpp b/Web.cpp index 9dd15ba..5ffe9db 100644 --- a/Web.cpp +++ b/Web.cpp @@ -7,13 +7,14 @@ #include "Utils.h" #include "SSDP.h" #include "Somfy.h" +#include "MQTT.h" extern ConfigSettings settings; extern SSDPClass SSDP; extern rebootDelay_t rebootDelay; extern SomfyShadeController somfy; extern Web webServer; - +extern MQTTClass mqtt; #define WEB_MAX_RESPONSE 16384 static char g_content[WEB_MAX_RESPONSE]; @@ -1477,11 +1478,14 @@ void Web::begin() { else { JsonObject obj = doc.as(); HTTPMethod method = server.method(); + Serial.print("Saving MQTT "); Serial.print(F("HTTP Method: ")); Serial.println(server.method()); if (method == HTTP_POST || method == HTTP_PUT) { + mqtt.disconnect(); settings.MQTT.fromJSON(obj); settings.MQTT.save(); + StaticJsonDocument<512> sdoc; JsonObject sobj = sdoc.to(); settings.MQTT.toJSON(sobj);