mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-12 18:42:10 +01:00
Added step size for tilt wheels
This commit is contained in:
parent
7425a46d1a
commit
fb677dc239
8 changed files with 60 additions and 26 deletions
|
|
@ -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());
|
||||
|
|
|
|||
14
Somfy.cpp
14
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<float>(this->tiltTime/100.0f))));
|
||||
if(this->tiltTime == 0 || this->stepSize == 0) return;
|
||||
this->tiltTarget = max(0.0f, this->currentTiltPos - (100.0f/(static_cast<float>(this->tiltTime/static_cast<float>(this->stepSize)))));
|
||||
}
|
||||
else if(this->currentPos > 0.0f) {
|
||||
this->target = max(0.0f, this->currentPos - (100.0f/(static_cast<float>(this->upTime/100.0f))));
|
||||
if(this->downTime == 0 || this->stepSize == 0) return;
|
||||
this->target = max(0.0f, this->currentPos - (100.0f/(static_cast<float>(this->upTime/static_cast<float>(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<float>(this->tiltTime/100.0f))));
|
||||
if(this->tiltTime == 0 || this->stepSize == 0) return;
|
||||
this->tiltTarget = min(100.0f, this->currentTiltPos + (100.0f/(static_cast<float>(this->tiltTime/static_cast<float>(this->stepSize)))));
|
||||
}
|
||||
else if(this->currentPos < 100.0f) {
|
||||
this->target = min(100.0f, this->currentPos + (100.0f/(static_cast<float>(this->downTime/100.0f))));
|
||||
if(this->downTime == 0 || this->stepSize == 0) return;
|
||||
this->target = min(100.0f, this->currentPos + (100.0f/(static_cast<float>(this->downTime/static_cast<float>(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<bool>(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<uint8_t>(floor(this->currentTiltPos));
|
||||
obj["tiltDirection"] = this->tiltDirection;
|
||||
obj["tiltTime"] = this->tiltTime;
|
||||
obj["stepSize"] = this->stepSize;
|
||||
obj["tiltTarget"] = static_cast<uint8_t>(floor(this->tiltTarget));
|
||||
obj["target"] = this->target;
|
||||
obj["myPos"] = static_cast<int8_t>(floor(this->myPos));
|
||||
|
|
|
|||
1
Somfy.h
1
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();
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
1.5.1
|
||||
1.5.2
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="main.css?v=1.5.1" type="text/css" />
|
||||
<link rel="stylesheet" href="icons.css?v=1.5.1" type="text/css" />
|
||||
<link rel="stylesheet" href="main.css?v=1.5.2b" type="text/css" />
|
||||
<link rel="stylesheet" href="icons.css?v=1.5.2b" type="text/css" />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<script type="text/javascript" src="index.js?v=1.5.1"></script>
|
||||
<script type="text/javascript" src="index.js?v=1.5.2b"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="divContainer" class="container" style="user-select:none;position:relative;border-radius:27px;">
|
||||
|
|
@ -220,13 +220,13 @@
|
|||
<div class="field-group" style="width:127px;display:inline-block;margin-top:-20px;float:left;">
|
||||
<div class="field-group">
|
||||
<div class="field-group">
|
||||
<select id="selShadeBitLength" name="bitLength" style="width:100%;">
|
||||
<select id="selShadeBitLength" name="bitLength" style="width:100%;" onchange="somfy.onShadeBitLengthChanged(this);">
|
||||
<option value="56">56-BIT</option>
|
||||
<option value="80">80-BIT</option>
|
||||
</select>
|
||||
<label for="selShadeBitLength">Bit Length</label>
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<div class="field-group" style="margin-top:-10px;">
|
||||
<select id="selShadeType" name="shadeType" style="width:100%;" onchange="somfy.onShadeTypeChanged(this);">
|
||||
<option value="0">Roller Shade</option>
|
||||
<option value="1">Blind</option>
|
||||
|
|
@ -234,25 +234,25 @@
|
|||
</select>
|
||||
<label for="selShadeType">Type</label>
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<div class="field-group" style="margin-top:-15px;">
|
||||
<input id="fldShadeAddress" name="shadeAddress" type="number" length=5 placeholder="Address" style="width:100%;text-align:right;">
|
||||
<label for="fldShadeAddress">Remote Address</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="divSomfyButtons" style="float:right;margin-top:27px;position:relative">
|
||||
<div id="divSomfyButtons" style="float:right;margin-top:10px;position:relative">
|
||||
<div style="display:inline-block;margin-right:7px;position:relative;font-size:48px;"><i id="icoShade" class="somfy-shade-icon icss-window-shade" data-shadeid="0" style="--shade-position:0%;vertical-align:middle;"></i><i class="icss-window-tilt" data-tiltposition="0" style="display:none;"></i></div>
|
||||
<div class="button-outline" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'up');"><i class="icss-somfy-up"></i></div>
|
||||
<div class="button-outline" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'my');" style="font-size: 2em; padding: 10px;"><span>my</span></div>
|
||||
<div class="button-outline" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'down');"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<div class="field-group" style="padding:0px;">
|
||||
<input id="fldShadeName" name="shadeName" type="text" length=20 placeholder="Name">
|
||||
<label for="fldShadeName">Name</label>
|
||||
</div>
|
||||
<div>
|
||||
<div class="field-group" style="display:inline-block;max-width:127px;margin-right:17px;">
|
||||
<div style="margin-top:-10px;">
|
||||
<div class="field-group" style="display:inline-block;max-width:127px;margin-right:17px;margin-top:-10px;">
|
||||
<input id="fldShadeUpTime" name="shadeUpTime" type="number" length=5 placeholder="milliseconds" style="width:100%;text-align:right;" />
|
||||
<label for="fldShadeUpTime">Up Time (ms)</label>
|
||||
</div>
|
||||
|
|
@ -261,7 +261,7 @@
|
|||
<label for="fldShadeDownTime">Down Time (ms)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="divTiltSettings" style="display:none;">
|
||||
<div id="divTiltSettings" style="display:none;margin-top:-10px;">
|
||||
<div class="field-group" style="display:inline-block; margin-right:17px;width:127px;vertical-align:middle;">
|
||||
<select id="selTiltType" name="tiltType" style="width:100%;" onchange="somfy.onShadeTypeChanged(this);">
|
||||
<option value="0">None</option>
|
||||
|
|
@ -275,6 +275,18 @@
|
|||
<label for="fldTiltTime">Tilt Time (ms)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="divStepSettings" style="display:none;">
|
||||
<div class="field-group">
|
||||
<input id="slidStepSize" name="stepSize" type="range" min="1" max="1000" step="1" style="width:100%;" oninput="somfy.stepSizeChanged(this);" />
|
||||
<label for="slidStepSize" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;">
|
||||
<span>Step Size (smaller)</span>
|
||||
<span style="float:right;display:inline-block;margin-right:7px;">
|
||||
<span id="spanStepSize" style="color:black;"></span><span>(larger)</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="button-container" style="text-align:center;">
|
||||
<button id="btnPairShade" type="button" onclick="somfy.pairShade(parseInt(document.getElementById('spanShadeId').innerText, 10));" style="display:inline-block;width:47%;">
|
||||
Pair Shade
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ document.oncontextmenu = (event) => {
|
|||
else {
|
||||
event.preventDefault(); event.stopPropagation(); return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
Date.prototype.toJSON = function () {
|
||||
let tz = this.getTimezoneOffset();
|
||||
let sign = tz > 0 ? '-' : '+';
|
||||
|
|
@ -378,7 +378,7 @@ async function reopenSocket() {
|
|||
await initSockets();
|
||||
}
|
||||
class General {
|
||||
appVersion = 'v1.5.1';
|
||||
appVersion = 'v1.5.2beta';
|
||||
reloadApp = false;
|
||||
async init() {
|
||||
this.setAppVersion();
|
||||
|
|
@ -1266,7 +1266,6 @@ class Somfy {
|
|||
case 37:
|
||||
case 38:
|
||||
continue;
|
||||
break;
|
||||
case 32: // We cannot use this pin with the mask for TX.
|
||||
case 33:
|
||||
case 34: // Input only
|
||||
|
|
@ -1309,7 +1308,6 @@ class Somfy {
|
|||
span = divs[i].querySelector('#spanMyTiltPos');
|
||||
if (span) span.innerHTML = typeof state.myTiltPos !== 'undefined' && state.myTiltPos >= 0 ? `${state.myTiltPos}%` : '---';
|
||||
}
|
||||
|
||||
};
|
||||
procRemoteFrame(frame) {
|
||||
console.log(frame);
|
||||
|
|
@ -1348,7 +1346,7 @@ class Somfy {
|
|||
if (i !== 0) html += ',';
|
||||
html += `${frame.pulses[i]}`;
|
||||
}
|
||||
html += '</div>'
|
||||
html += '</div>';
|
||||
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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue