diff --git a/ConfigFile.cpp b/ConfigFile.cpp index 7dbfb60..4b33b98 100644 --- a/ConfigFile.cpp +++ b/ConfigFile.cpp @@ -6,9 +6,9 @@ extern Preferences pref; -#define SHADE_HDR_VER 5 +#define SHADE_HDR_VER 6 #define SHADE_HDR_SIZE 16 -#define SHADE_REC_SIZE 222 +#define SHADE_REC_SIZE 228 bool ConfigFile::begin(const char* filename, bool readOnly) { this->file = LittleFS.open(filename, readOnly ? "r" : "w"); @@ -292,6 +292,9 @@ bool ShadeConfigFile::loadFile(SomfyShadeController *s, const char *filename) { shade->upTime = this->readUInt32(shade->upTime); shade->downTime = this->readUInt32(shade->downTime); shade->tiltTime = this->readUInt32(shade->tiltTime); + if(this->header.version > 5) { + shade->stepSize = this->readUInt16(100); + } for(uint8_t j = 0; j < SOMFY_MAX_LINKED_REMOTES; j++) { SomfyLinkedRemote *rem = &shade->linkedRemotes[j]; rem->setRemoteAddress(this->readUInt32(0)); @@ -346,6 +349,7 @@ bool ShadeConfigFile::writeShadeRecord(SomfyShade *shade) { this->writeUInt32(shade->upTime); this->writeUInt32(shade->downTime); this->writeUInt32(shade->tiltTime); + this->writeUInt16(shade->stepSize); for(uint8_t j = 0; j < SOMFY_MAX_LINKED_REMOTES; j++) { SomfyLinkedRemote *rem = &shade->linkedRemotes[j]; this->writeUInt32(rem->getRemoteAddress()); diff --git a/Somfy.cpp b/Somfy.cpp index a1fb054..7329676 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -1030,10 +1030,12 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) { // the motor must tilt in the direction first then move // so we have to calculate the target with this in mind. if(this->tiltType == tilt_types::integrated && this->currentTiltPos > 0.0f) { - this->tiltTarget = max(0.0f, this->currentTiltPos - (100.0f/(static_cast(this->tiltTime/100.0f)))); + if(this->tiltTime == 0 || this->stepSize == 0) return; + this->tiltTarget = max(0.0f, this->currentTiltPos - (100.0f/(static_cast(this->tiltTime/static_cast(this->stepSize))))); } else if(this->currentPos > 0.0f) { - this->target = max(0.0f, this->currentPos - (100.0f/(static_cast(this->upTime/100.0f)))); + if(this->downTime == 0 || this->stepSize == 0) return; + this->target = max(0.0f, this->currentPos - (100.0f/(static_cast(this->upTime/static_cast(this->stepSize))))); } break; case somfy_commands::MyDown: @@ -1045,10 +1047,12 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) { // the motor must tilt in the direction first then move // so we have to calculate the target with this in mind. if(this->tiltType == tilt_types::integrated && this->currentTiltPos < 100.0f) { - this->tiltTarget = min(100.0f, this->currentTiltPos + (100.0f/(static_cast(this->tiltTime/100.0f)))); + if(this->tiltTime == 0 || this->stepSize == 0) return; + this->tiltTarget = min(100.0f, this->currentTiltPos + (100.0f/(static_cast(this->tiltTime/static_cast(this->stepSize))))); } else if(this->currentPos < 100.0f) { - this->target = min(100.0f, this->currentPos + (100.0f/(static_cast(this->downTime/100.0f)))); + if(this->downTime == 0 || this->stepSize == 0) return; + this->target = min(100.0f, this->currentPos + (100.0f/(static_cast(this->downTime/static_cast(this->stepSize))))); } break; default: @@ -1297,6 +1301,7 @@ bool SomfyShade::fromJSON(JsonObject &obj) { if(obj.containsKey("downTime")) this->downTime = obj["downTime"]; if(obj.containsKey("remoteAddress")) this->setRemoteAddress(obj["remoteAddress"]); if(obj.containsKey("tiltTime")) this->tiltTime = obj["tiltTime"]; + if(obj.containsKey("stepSize")) this->stepSize = obj["stepSize"]; if(obj.containsKey("hasTilt")) this->tiltType = static_cast(obj["hasTilt"]) ? tilt_types::none : tilt_types::tiltmotor; if(obj.containsKey("bitLength")) this->bitLength = obj["bitLength"]; if(obj.containsKey("shadeType")) { @@ -1358,6 +1363,7 @@ bool SomfyShade::toJSON(JsonObject &obj) { obj["tiltPosition"] = static_cast(floor(this->currentTiltPos)); obj["tiltDirection"] = this->tiltDirection; obj["tiltTime"] = this->tiltTime; + obj["stepSize"] = this->stepSize; obj["tiltTarget"] = static_cast(floor(this->tiltTarget)); obj["target"] = this->target; obj["myPos"] = static_cast(floor(this->myPos)); diff --git a/Somfy.h b/Somfy.h index 122384b..32dbf14 100644 --- a/Somfy.h +++ b/Somfy.h @@ -154,6 +154,7 @@ class SomfyShade : public SomfyRemote { uint32_t upTime = 10000; uint32_t downTime = 10000; uint32_t tiltTime = 7000; + uint16_t stepSize = 100; bool save(); bool isIdle(); void checkMovement(); diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index 5a55340..6c5151b 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 f8918ec..0c33cfb 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/data/appversion b/data/appversion index 8e03717..a73b432 100644 --- a/data/appversion +++ b/data/appversion @@ -1 +1 @@ -1.5.1 \ No newline at end of file +1.5.2 \ No newline at end of file diff --git a/data/index.html b/data/index.html index 426d3a8..eeac99c 100644 --- a/data/index.html +++ b/data/index.html @@ -3,10 +3,10 @@ - - + + - +
@@ -220,13 +220,13 @@
-
-
+
-
+
-
+
my
-
+
-
-
+
+
@@ -261,7 +261,7 @@
- '; row.innerHTML = html; frames.prepend(row); this.frames.push(frame); @@ -1357,7 +1355,7 @@ class Somfy { if (Array.isArray(obj)) { let output = '['; for (let i = 0; i < obj.length; i++) { - if (i != 0) output += ',\n'; + if (i !== 0) output += ',\n'; output += this.JSONPretty(obj[i], indent); } output += ']' @@ -1417,6 +1415,9 @@ class Somfy { document.getElementById('fldTiltTime').parentElement.style.display = tilt ? 'inline-block' : 'none'; document.querySelector('#divSomfyButtons i.icss-window-tilt').style.display = tilt ? '' : 'none'; }; + onShadeBitLengthChanged(el) { + document.getElementById('divStepSettings').style.display = parseInt(el.value, 10) === 80 ? '' : 'none'; + } openEditShade(shadeId) { console.log('Opening Edit Shade'); if (typeof shadeId === 'undefined') { @@ -1443,6 +1444,8 @@ class Somfy { document.getElementById('divLinkedRemoteList').innerHTML = ''; document.getElementById('btnSetRollingCode').style.display = 'none'; document.getElementById('selShadeBitLength').value = shade.bitLength || 56; + document.getElementById('slidStepSize').value = shade.stepSize || 100; + document.getElementById('spanStepSize').innerHTML = shade.stepSize.fmt('#,##0'); } }); } @@ -1471,6 +1474,8 @@ class Somfy { document.getElementsByName('shadeName')[0].value = shade.name; document.getElementsByName('shadeUpTime')[0].value = shade.upTime; document.getElementsByName('shadeDownTime')[0].value = shade.downTime; + document.getElementById('slidStepSize').value = shade.stepSize; + document.getElementById('spanStepSize').innerHTML = shade.stepSize.fmt('#,##0'); document.getElementById('fldTiltTime').value = shade.tiltTime; document.getElementById('selTiltType').value = shade.tiltType; this.onShadeTypeChanged(document.getElementById('selShadeType')); @@ -1488,6 +1493,7 @@ class Somfy { ico.style.setProperty('--shade-position', `${shade.position}%`); ico.style.setProperty('--tilt-position', `${shade.tiltPosition}%`); ico.setAttribute('data-shadeid', shade.shadeId); + somfy.onShadeBitLengthChanged(document.getElementById('selShadeBitLength')); document.getElementById('btnSetRollingCode').style.display = 'inline-block'; if (shade.paired) { document.getElementById('btnUnpairShade').style.display = 'inline-block'; @@ -1523,9 +1529,10 @@ class Somfy { downTime: parseInt(document.getElementsByName('shadeDownTime')[0].value, 10), shadeType: parseInt(document.getElementById('selShadeType').value, 10), tiltTime: parseInt(document.getElementById('fldTiltTime').value, 10), - bitLength: parseInt(document.getElementById('selShadeBitLength').value, 10) || 56 + bitLength: parseInt(document.getElementById('selShadeBitLength').value, 10) || 56, + stepSize: parseInt(document.getElementById('slidStepSize').value, 10) || 100 }; - if (obj.shadeType == 1) { + if (obj.shadeType === 1) { obj.tiltType = parseInt(document.getElementById('selTiltType').value, 10); } else obj.tiltType = 0; @@ -1857,6 +1864,10 @@ class Somfy { let lvls = [-30, -20, -15, -10, -6, 0, 5, 7, 10, 11, 12]; document.getElementById('spanTxPower').innerText = lvls[el.value]; }; + stepSizeChanged(el) { + document.getElementById('spanStepSize').innerText = parseInt(el.value, 10).fmt('#,##0'); + }; + processShadeTarget(el, shadeId) { let positioner = document.querySelector(`.shade-positioner[data-shadeid="${shadeId}"]`); if (positioner) {