diff --git a/ConfigFile.cpp b/ConfigFile.cpp index ca09fe4..0fb4a3b 100644 --- a/ConfigFile.cpp +++ b/ConfigFile.cpp @@ -6,9 +6,9 @@ extern Preferences pref; -#define SHADE_HDR_VER 8 +#define SHADE_HDR_VER 9 #define SHADE_HDR_SIZE 16 -#define SHADE_REC_SIZE 236 +#define SHADE_REC_SIZE 242 bool ConfigFile::begin(const char* filename, bool readOnly) { this->file = LittleFS.open(filename, readOnly ? "r" : "w"); @@ -329,6 +329,9 @@ bool ShadeConfigFile::loadFile(SomfyShadeController *s, const char *filename) { } shade->target = floor(shade->currentPos); shade->tiltTarget = floor(shade->currentTiltPos); + if(this->header.version >= 9) { + shade->inverted = this->readBool(false); + } } pref.end(); if(opened) { @@ -365,7 +368,7 @@ bool ShadeConfigFile::writeShadeRecord(SomfyShade *shade) { this->writeFloat(shade->myPos, 5); this->writeFloat(shade->myTiltPos, 5); this->writeFloat(shade->currentPos, 5); - this->writeFloat(shade->currentTiltPos, 5, CFG_REC_END); + this->writeFloat(shade->currentTiltPos, 5); } else { // Make sure that we write cleared values when the shade is deleted. @@ -373,8 +376,9 @@ bool ShadeConfigFile::writeShadeRecord(SomfyShade *shade) { 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 + this->writeFloat(0.0f, 5); // currentTiltPos } + this->writeBool(shade->inverted, CFG_REC_END); return true; } bool ShadeConfigFile::exists() { return LittleFS.exists("/shades.cfg"); } diff --git a/Somfy.cpp b/Somfy.cpp index 99b75a4..6399ab9 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -1058,7 +1058,7 @@ void SomfyShade::processWaitingFrame() { } if(this->lastFrame.processed) return; if(this->lastFrame.await > 0 && (millis() > this->lastFrame.await)) { - switch(this->lastFrame.cmd) { + switch(this->transformCommand(this->lastFrame.cmd)) { case somfy_commands::StepUp: this->lastFrame.processed = true; // Simply move the shade up by 1%. @@ -1161,10 +1161,11 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) { this->startTiltPos = this->currentTiltPos; // If the command is coming from a remote then we are aborting all these positioning operations. if(!internal) this->settingMyPos = this->settingPos = this->settingTiltPos = false; - + + somfy_commands cmd = this->transformCommand(frame.cmd); // At this point we are not processing the combo buttons // will need to see what the shade does when you press both. - switch(frame.cmd) { + switch(cmd) { case somfy_commands::Sensor: { const uint8_t prevFlags = this->flags; @@ -1644,6 +1645,7 @@ bool SomfyShade::fromJSON(JsonObject &obj) { this->shadeType = static_cast(obj["shadeType"].as()); } } + if(obj.containsKey("inverted")) this->inverted = obj["inverted"].as(); if(obj.containsKey("tiltType")) { if(obj["tiltType"].is()) { if(strncmp(obj["tiltType"].as(), "none", 4) == 0) @@ -1703,6 +1705,7 @@ bool SomfyShade::toJSON(JsonObject &obj) { obj["bitLength"] = this->bitLength; obj["proto"] = static_cast(this->proto); obj["flags"] = this->flags; + obj["inverted"] = this->inverted; SomfyRemote::toJSON(obj); JsonArray arr = obj.createNestedArray("linkedRemotes"); for(uint8_t i = 0; i < SOMFY_MAX_LINKED_REMOTES; i++) { @@ -1859,11 +1862,32 @@ SomfyShade *SomfyShadeController::addShade() { } return shade; } +somfy_commands SomfyRemote::transformCommand(somfy_commands cmd) { + if(this->inverted) { + switch(cmd) { + case somfy_commands::Up: + return somfy_commands::Down; + case somfy_commands::MyUp: + return somfy_commands::MyDown; + case somfy_commands::Down: + return somfy_commands::Up; + case somfy_commands::MyDown: + return somfy_commands::MyUp; + case somfy_commands::StepUp: + return somfy_commands::StepDown; + case somfy_commands::StepDown: + return somfy_commands::StepUp; + default: + break; + } + } + return cmd; +} void SomfyRemote::sendCommand(somfy_commands cmd, uint8_t repeat) { somfy_frame_t frame; frame.rollingCode = this->getNextRollingCode(); frame.remoteAddress = this->getRemoteAddress(); - frame.cmd = cmd; + frame.cmd = this->transformCommand(cmd); frame.repeats = repeat; frame.bitLength = this->bitLength; // Match the encKey to the rolling code. These keys range from 160 to 175. diff --git a/Somfy.h b/Somfy.h index 7d17e8d..e142444 100644 --- a/Somfy.h +++ b/Somfy.h @@ -167,6 +167,8 @@ class SomfyRemote { uint32_t m_remoteAddress = 0; public: radio_proto proto = radio_proto::RTS; + bool inverted = false; + uint8_t flags = 0; uint8_t bitLength = 0; char *getRemotePrefId() {return m_remotePrefId;} virtual bool toJSON(JsonObject &obj); @@ -176,6 +178,7 @@ class SomfyRemote { virtual uint16_t setRollingCode(uint16_t code); uint16_t lastRollingCode = 0; virtual void sendCommand(somfy_commands cmd, uint8_t repeat = 1); + somfy_commands transformCommand(somfy_commands cmd); }; class SomfyLinkedRemote : public SomfyRemote { public: @@ -204,7 +207,6 @@ class SomfyShade : public SomfyRemote { public: shade_types shadeType = shade_types::roller; tilt_types tiltType = tilt_types::none; - uint8_t flags = 0; void load(); somfy_tx_queue_t txQueue; somfy_frame_t lastFrame; diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index dd0e4f1..12662fe 100644 Binary files a/SomfyController.ino.esp32.bin and b/SomfyController.ino.esp32.bin differ diff --git a/SomfyController.littlefs.bin b/SomfyController.littlefs.bin index c480456..672969e 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/data/index.html b/data/index.html index eed9f08..3e735e4 100644 --- a/data/index.html +++ b/data/index.html @@ -295,8 +295,14 @@ - +
+
+ + +
+
+