diff --git a/ConfigFile.cpp b/ConfigFile.cpp index 2e6ffbc..4277658 100644 --- a/ConfigFile.cpp +++ b/ConfigFile.cpp @@ -7,9 +7,9 @@ extern Preferences pref; -#define SHADE_HDR_VER 16 +#define SHADE_HDR_VER 17 #define SHADE_HDR_SIZE 56 -#define SHADE_REC_SIZE 268 +#define SHADE_REC_SIZE 272 #define GROUP_REC_SIZE 184 #define TRANS_REC_SIZE 74 @@ -667,10 +667,10 @@ bool ShadeConfigFile::readShadeRecord(SomfyShade *shade) { shade->gpioUp = this->readUInt8(shade->gpioUp); shade->gpioDown = this->readUInt8(shade->gpioDown); } - if(this->header.version > 15) { + if(this->header.version > 15) shade->gpioMy = this->readUInt8(shade->gpioMy); - } - + if(this->header.version > 16) + shade->gpioFlags = this->readUInt8(shade->gpioFlags); if(shade->getShadeId() == 255) shade->clear(); else if(shade->tiltType == tilt_types::tiltonly) { shade->myPos = shade->currentPos = shade->target = 100.0f; @@ -785,7 +785,8 @@ bool ShadeConfigFile::writeShadeRecord(SomfyShade *shade) { this->writeUInt8(shade->sortOrder); this->writeUInt8(shade->gpioUp); this->writeUInt8(shade->gpioDown); - this->writeUInt8(shade->gpioMy, CFG_REC_END); + this->writeUInt8(shade->gpioMy); + this->writeUInt8(shade->gpioFlags, CFG_REC_END); return true; } bool ShadeConfigFile::writeSettingsRecord() { diff --git a/ConfigSettings.h b/ConfigSettings.h index 8d3f43e..b78b1cd 100644 --- a/ConfigSettings.h +++ b/ConfigSettings.h @@ -3,7 +3,7 @@ #ifndef configsettings_h #define configsettings_h -#define FW_VERSION "v2.2.2c" +#define FW_VERSION "v2.2.2d" enum DeviceStatus { DS_OK = 0, DS_ERROR = 1, diff --git a/Somfy.cpp b/Somfy.cpp index 64160ea..beb5ffa 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -811,43 +811,46 @@ bool SomfyShade::isInGroup() { void SomfyShade::setGPIOs() { if(this->proto == radio_proto::GP_Relay) { // Determine whether the direction needs to be set. + uint8_t p_on = this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger == 0x00 ? HIGH : LOW; + uint8_t p_off = this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger == 0x00 ? LOW : HIGH; + int8_t dir = this->direction; if(dir == 0 && this->tiltType == tilt_types::integrated) dir = this->tiltDirection; else if(this->tiltType == tilt_types::tiltonly) dir = this->tiltDirection; if(this->shadeType == shade_types::drycontact) { - digitalWrite(this->gpioDown, this->currentPos == 100 ? HIGH : LOW); + digitalWrite(this->gpioDown, this->currentPos == 100 ? p_on : p_off); this->gpioDir = this->currentPos == 100 ? 1 : -1; } else if(this->shadeType == shade_types::drycontact2) { if(this->currentPos == 100) { - digitalWrite(this->gpioDown, LOW); - digitalWrite(this->gpioUp, HIGH); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioUp, p_on); } else { - digitalWrite(this->gpioUp, LOW); - digitalWrite(this->gpioDown, HIGH); + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_on); } this->gpioDir = this->currentPos == 100 ? 1 : -1; } else { switch(dir) { case -1: - digitalWrite(this->gpioDown, LOW); - digitalWrite(this->gpioUp, HIGH); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioUp, p_on); if(dir != this->gpioDir) Serial.printf("UP: true, DOWN: false\n"); this->gpioDir = dir; break; case 1: - digitalWrite(this->gpioUp, LOW); - digitalWrite(this->gpioDown, HIGH); + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_on); if(dir != this->gpioDir) Serial.printf("UP: false, DOWN: true\n"); this->gpioDir = dir; break; default: - digitalWrite(this->gpioUp, LOW); - digitalWrite(this->gpioDown, LOW); + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_off); if(dir != this->gpioDir) Serial.printf("UP: false, DOWN: false\n"); this->gpioDir = dir; break; @@ -856,9 +859,11 @@ void SomfyShade::setGPIOs() { } else if(this->proto == radio_proto::GP_Remote) { if(millis() > this->gpioRelease) { - digitalWrite(this->gpioUp, LOW); - digitalWrite(this->gpioDown, LOW); - digitalWrite(this->gpioMy, LOW); + uint8_t p_on = this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger == 0x00 ? HIGH : LOW; + uint8_t p_off = this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger == 0x00 ? LOW : HIGH; + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioMy, p_off); this->gpioRelease = 0; } } @@ -866,22 +871,24 @@ void SomfyShade::setGPIOs() { void SomfyRemote::triggerGPIOs(somfy_frame_t &frame) { } void SomfyShade::triggerGPIOs(somfy_frame_t &frame) { if(this->proto == radio_proto::GP_Remote) { + uint8_t p_on = this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger == 0x00 ? HIGH : LOW; + uint8_t p_off = this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger == 0x00 ? LOW : HIGH; int8_t dir = 0; switch(frame.cmd) { case somfy_commands::My: if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1) { - digitalWrite(this->gpioUp, LOW); - digitalWrite(this->gpioDown, LOW); - digitalWrite(this->gpioMy, HIGH); + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioMy, p_on); dir = 0; if(dir != this->gpioDir) Serial.printf("UP: false, DOWN: false, MY: true\n"); } break; case somfy_commands::Up: if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioMy, LOW); - digitalWrite(this->gpioDown, LOW); - digitalWrite(this->gpioUp, HIGH); + digitalWrite(this->gpioMy, p_off); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioUp, p_on); dir = -1; Serial.printf("UP: true, DOWN: false, MY: false\n"); } @@ -889,34 +896,34 @@ void SomfyShade::triggerGPIOs(somfy_frame_t &frame) { case somfy_commands::Toggle: case somfy_commands::Down: if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioMy, LOW); - digitalWrite(this->gpioUp, LOW); + digitalWrite(this->gpioMy, p_off); + digitalWrite(this->gpioUp, p_off); } - digitalWrite(this->gpioDown, HIGH); + digitalWrite(this->gpioDown, p_on); dir = 1; Serial.printf("UP: false, DOWN: true, MY: false\n"); break; case somfy_commands::MyUp: if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioDown, LOW); - digitalWrite(this->gpioMy, HIGH); - digitalWrite(this->gpioUp, HIGH); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioMy, p_on); + digitalWrite(this->gpioUp, p_on); Serial.printf("UP: true, DOWN: false, MY: true\n"); } break; case somfy_commands::MyDown: if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioUp, LOW); - digitalWrite(this->gpioMy, HIGH); - digitalWrite(this->gpioDown, HIGH); + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioMy, p_on); + digitalWrite(this->gpioDown, p_on); Serial.printf("UP: false, DOWN: true, MY: true\n"); } break; case somfy_commands::MyUpDown: if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioUp, HIGH); - digitalWrite(this->gpioMy, HIGH); - digitalWrite(this->gpioDown, HIGH); + digitalWrite(this->gpioUp, p_on); + digitalWrite(this->gpioMy, p_on); + digitalWrite(this->gpioDown, p_on); Serial.printf("UP: true, DOWN: true, MY: true\n"); } break; @@ -2777,6 +2784,9 @@ int8_t SomfyShade::fromJSON(JsonObject &obj) { if(obj.containsKey("proto")) this->proto = static_cast(obj["proto"].as()); if(obj.containsKey("sunSensor")) this->setSunSensor(obj["sunSensor"]); if(obj.containsKey("light")) this->setLight(obj["light"]); + if(obj.containsKey("gpioFlags")) this->gpioFlags = obj["gpioFlags"]; + if(obj.containsKey("gpioLLTrigger")) this->gpioFlags = obj["gpioLLTrigger"].as() ? this->gpioFlags |= (uint8_t)gpio_flags_t::LowLevelTrigger : this->gpioFlags &= ~(uint8_t)gpio_flags_t::LowLevelTrigger; + if(obj.containsKey("shadeType")) { if(obj["shadeType"].is()) { if(strncmp(obj["shadeType"].as(), "roller", 7) == 0) @@ -2904,6 +2914,8 @@ bool SomfyShade::toJSON(JsonObject &obj) { obj["gpioUp"] = this->gpioUp; obj["gpioDown"] = this->gpioDown; obj["gpioMy"] = this->gpioMy; + obj["gpioLLTrigger"] = ((this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0) ? false : true; + Serial.println(this->gpioFlags); SomfyRemote::toJSON(obj); JsonArray arr = obj.createNestedArray("linkedRemotes"); for(uint8_t i = 0; i < SOMFY_MAX_LINKED_REMOTES; i++) { diff --git a/Somfy.h b/Somfy.h index c52cad0..9a7bc57 100644 --- a/Somfy.h +++ b/Somfy.h @@ -153,6 +153,9 @@ enum class somfy_flags_t : byte { Sunny = 0x20, Lighted = 0x40 }; +enum class gpio_flags_t : byte { + LowLevelTrigger = 0x01 +}; struct somfy_frame_t { bool valid = false; bool processed = false; @@ -186,6 +189,7 @@ class SomfyRemote { uint32_t m_remoteAddress = 0; public: radio_proto proto = radio_proto::RTS; + uint8_t gpioFlags = 0; int8_t gpioDir = 0; uint8_t gpioUp = 0; uint8_t gpioDown = 0; diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index d091757..4d258a8 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 b3b69ea..7e50f5f 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/data/index.html b/data/index.html index c945b09..547739f 100644 --- a/data/index.html +++ b/data/index.html @@ -3,11 +3,11 @@ - - - + + + - +
@@ -415,6 +415,12 @@
+
+
+ + +
+
diff --git a/data/index.js b/data/index.js index 7ed5b3c..f6f60f0 100644 --- a/data/index.js +++ b/data/index.js @@ -1252,7 +1252,7 @@ var security = new Security(); class General { initialized = false; - appVersion = 'v2.2.2c'; + appVersion = 'v2.2.2d'; reloadApp = false; init() { if (this.initialized) return; diff --git a/data/widgets.css b/data/widgets.css index 4b4fd59..1e9363f 100644 --- a/data/widgets.css +++ b/data/widgets.css @@ -211,6 +211,14 @@ width: 70px; display: inline-block; } +#somfyShade #divLLTrigger { + display:none; +} + +#somfyShade[data-proto="8"] #divLLTrigger, +#somfyShade[data-proto="9"] #divLLTrigger { + display: block; +} #somfyShade[data-proto="8"] #divStepSettings, #somfyShade[data-proto="9"] #divStepSettings, #somfyShade[data-proto="8"] #divGPIOMy,