mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 02:52:11 +01:00
Added garage door motor control #138
This commit is contained in:
parent
ff2d150ad8
commit
74ee9f6f25
9 changed files with 246 additions and 105 deletions
126
Somfy.cpp
126
Somfy.cpp
|
|
@ -51,6 +51,7 @@ somfy_commands translateSomfyCommand(const String& string) {
|
|||
else if (string.equalsIgnoreCase("StepDown")) return somfy_commands::StepDown;
|
||||
else if (string.equalsIgnoreCase("Flag")) return somfy_commands::Flag;
|
||||
else if (string.equalsIgnoreCase("Sensor")) return somfy_commands::Sensor;
|
||||
else if (string.equalsIgnoreCase("Toggle")) return somfy_commands::Toggle;
|
||||
else if (string.startsWith("mud") || string.startsWith("MUD")) return somfy_commands::MyUpDown;
|
||||
else if (string.startsWith("md") || string.startsWith("MD")) return somfy_commands::MyDown;
|
||||
else if (string.startsWith("ud") || string.startsWith("UD")) return somfy_commands::UpDown;
|
||||
|
|
@ -64,6 +65,7 @@ somfy_commands translateSomfyCommand(const String& string) {
|
|||
else if (string.startsWith("m") || string.startsWith("M")) return somfy_commands::My;
|
||||
else if (string.startsWith("f") || string.startsWith("F")) return somfy_commands::Flag;
|
||||
else if (string.startsWith("s") || string.startsWith("S")) return somfy_commands::SunFlag;
|
||||
else if (string.startsWith("t") || string.startsWith("T")) return somfy_commands::Toggle;
|
||||
else if (string.length() == 1) return static_cast<somfy_commands>(strtol(string.c_str(), nullptr, 16));
|
||||
else return somfy_commands::My;
|
||||
}
|
||||
|
|
@ -95,6 +97,8 @@ String translateSomfyCommand(const somfy_commands cmd) {
|
|||
return "Step Down";
|
||||
case somfy_commands::Sensor:
|
||||
return "Sensor";
|
||||
case somfy_commands::Toggle:
|
||||
return "Toggle";
|
||||
default:
|
||||
return "Unknown(" + String((uint8_t)cmd) + ")";
|
||||
}
|
||||
|
|
@ -119,57 +123,26 @@ void somfy_frame_t::decodeFrame(byte* frame) {
|
|||
|
||||
this->checksum = decoded[1] & 0b1111;
|
||||
this->encKey = decoded[0];
|
||||
// Pull in the 80-bit commands. The upper nibble will be 0 even on 80 bit packets.
|
||||
// Lets first determine the protocol.
|
||||
this->cmd = (somfy_commands)((decoded[1] >> 4));
|
||||
// Pull in the data for an 80-bit step command.
|
||||
if(this->cmd == somfy_commands::StepDown)
|
||||
this->cmd = (somfy_commands)((decoded[1] >> 4) | ((decoded[8] & 0x08) << 4));
|
||||
if(this->cmd == somfy_commands::RTWProto) {
|
||||
this->proto = this->encKey > 142 ? radio_proto::RTV : radio_proto::RTW;
|
||||
|
||||
switch(this->encKey) {
|
||||
case 149:
|
||||
case 133:
|
||||
this->cmd = somfy_commands::My;
|
||||
break;
|
||||
case 150:
|
||||
case 134:
|
||||
this->cmd = somfy_commands::Up;
|
||||
break;
|
||||
case 151:
|
||||
case 135:
|
||||
this->cmd = somfy_commands::MyUp;
|
||||
break;
|
||||
case 152:
|
||||
case 136:
|
||||
this->cmd = somfy_commands::Down;
|
||||
break;
|
||||
case 153:
|
||||
case 137:
|
||||
this->cmd = somfy_commands::MyDown;
|
||||
break;
|
||||
case 154:
|
||||
case 138:
|
||||
this->cmd = somfy_commands::UpDown;
|
||||
break;
|
||||
case 155:
|
||||
case 139:
|
||||
this->cmd = somfy_commands::MyUpDown;
|
||||
break;
|
||||
case 156:
|
||||
case 140:
|
||||
this->cmd = somfy_commands::Prog;
|
||||
break;
|
||||
case 157:
|
||||
case 141:
|
||||
this->cmd = somfy_commands::SunFlag;
|
||||
break;
|
||||
case 158:
|
||||
case 142:
|
||||
this->cmd = somfy_commands::Flag;
|
||||
break;
|
||||
if(this->encKey >= 160) {
|
||||
this->proto = radio_proto::RTS;
|
||||
if(this->encKey == 164) this->cmd = somfy_commands::Toggle;
|
||||
}
|
||||
else if(this->encKey > 148) {
|
||||
this->proto = radio_proto::RTV;
|
||||
this->cmd = (somfy_commands)(this->encKey - 148);
|
||||
}
|
||||
else if(this->encKey > 133) {
|
||||
this->proto = radio_proto::RTW;
|
||||
this->cmd = (somfy_commands)(this->encKey - 133);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Pull in the data for an 80-bit step command.
|
||||
if(this->cmd == somfy_commands::StepDown) this->cmd = (somfy_commands)((decoded[1] >> 4) | ((decoded[8] & 0x08) << 4));
|
||||
this->rollingCode = decoded[3] + (decoded[2] << 8);
|
||||
this->remoteAddress = (decoded[6] + (decoded[5] << 8) + (decoded[4] << 16));
|
||||
this->valid = this->checksum == checksum && this->remoteAddress > 0 && this->remoteAddress < 16777215;
|
||||
|
|
@ -191,13 +164,13 @@ void somfy_frame_t::decodeFrame(byte* frame) {
|
|||
case somfy_commands::SunFlag:
|
||||
case somfy_commands::Sensor:
|
||||
break;
|
||||
case somfy_commands::UnknownC:
|
||||
case somfy_commands::UnknownD:
|
||||
case somfy_commands::RTWProto:
|
||||
this->valid = false;
|
||||
break;
|
||||
case somfy_commands::StepUp:
|
||||
case somfy_commands::StepDown:
|
||||
case somfy_commands::Toggle:
|
||||
// These must be 80 bit commands
|
||||
break;
|
||||
default:
|
||||
|
|
@ -363,6 +336,8 @@ void somfy_frame_t::encodeFrame(byte *frame) {
|
|||
frame[8] = 48;
|
||||
frame[9] = 30;
|
||||
break;
|
||||
case somfy_commands::Toggle:
|
||||
frame[0] = 164;
|
||||
case somfy_commands::Prog:
|
||||
frame[7] = 196;
|
||||
frame[8] = 0;
|
||||
|
|
@ -834,7 +809,7 @@ void SomfyShade::checkMovement() {
|
|||
else if(this->direction != 0) this->tiltDirection = 0;
|
||||
uint8_t currPos = floor(this->currentPos);
|
||||
uint8_t currTiltPos = floor(this->currentTiltPos);
|
||||
|
||||
if(this->direction != 0) this->lastMovement = this->direction;
|
||||
if (sunFlag) {
|
||||
if (isSunny && !isWindy) { // It is sunny and there is no wind so we should be extended
|
||||
if (this->noWindDone
|
||||
|
|
@ -1256,22 +1231,23 @@ void SomfyShade::emitState(uint8_t num, const char *evt) {
|
|||
else sockEmit.sendToClient(num, evt, buf);
|
||||
if(mqtt.connected()) {
|
||||
char topic[32];
|
||||
snprintf(topic, sizeof(topic), "shades/%u/shadeType", this->shadeId);
|
||||
mqtt.publish(topic, static_cast<uint8_t>(this->shadeType));
|
||||
//snprintf(topic, sizeof(topic), "shades/%u/shadeType", this->shadeId);
|
||||
//mqtt.publish(topic, static_cast<uint8_t>(this->shadeType));
|
||||
//snprintf(topic, sizeof(topic), "shades/%u/remoteAddress", this->shadeId);
|
||||
//mqtt.publish(topic, this->getRemoteAddress());
|
||||
//snprintf(topic, sizeof(topic), "shades/%u/tiltType", this->shadeId);
|
||||
//mqtt.publish(topic, static_cast<uint8_t>(this->tiltType));
|
||||
//snprintf(topic, sizeof(topic), "shades/%u/lastRollingCode", this->shadeId);
|
||||
//mqtt.publish(topic, this->lastRollingCode);
|
||||
snprintf(topic, sizeof(topic), "shades/%u/position", this->shadeId);
|
||||
mqtt.publish(topic, this->transformPosition(this->currentPos));
|
||||
snprintf(topic, sizeof(topic), "shades/%u/direction", this->shadeId);
|
||||
mqtt.publish(topic, this->direction);
|
||||
snprintf(topic, sizeof(topic), "shades/%u/target", this->shadeId);
|
||||
mqtt.publish(topic, this->transformPosition(this->target));
|
||||
snprintf(topic, sizeof(topic), "shades/%u/remoteAddress", this->shadeId);
|
||||
mqtt.publish(topic, this->getRemoteAddress());
|
||||
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, this->transformPosition(this->myPos));
|
||||
snprintf(topic, sizeof(topic), "shades/%u/tiltType", this->shadeId);
|
||||
mqtt.publish(topic, static_cast<uint8_t>(this->tiltType));
|
||||
|
||||
snprintf(topic, sizeof(topic), "shades/%u/sunSensor", this->shadeId);
|
||||
mqtt.publish(topic, this->hasSunSensor());
|
||||
|
||||
|
|
@ -1283,14 +1259,15 @@ void SomfyShade::emitState(uint8_t num, const char *evt) {
|
|||
snprintf(topic, sizeof(topic), "shades/%u/tiltTarget", this->shadeId);
|
||||
mqtt.publish(topic, this->transformPosition(this->tiltTarget));
|
||||
}
|
||||
const uint8_t sunFlag = !!(this->flags & static_cast<uint8_t>(somfy_flags_t::SunFlag));
|
||||
const uint8_t isSunny = !!(this->flags & static_cast<uint8_t>(somfy_flags_t::Sunny));
|
||||
const uint8_t isWindy = !!(this->flags & static_cast<uint8_t>(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);
|
||||
if(this->hasSunSensor()) {
|
||||
const uint8_t sunFlag = !!(this->flags & static_cast<uint8_t>(somfy_flags_t::SunFlag));
|
||||
const uint8_t isSunny = !!(this->flags & static_cast<uint8_t>(somfy_flags_t::Sunny));
|
||||
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);
|
||||
}
|
||||
|
|
@ -1662,6 +1639,14 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
|||
}
|
||||
this->emitCommand(cmd, internal ? "internal" : "remote", frame.remoteAddress);
|
||||
break;
|
||||
case somfy_commands::Toggle:
|
||||
if(!this->isIdle()) {
|
||||
this->target = this->currentPos;
|
||||
}
|
||||
else if(this->currentPos == 100.0f) this->target = 0;
|
||||
else if(this->currentPos == 0.0f) this->target = 100;
|
||||
else this->target = this->lastMovement == -1 ? 100 : 0;
|
||||
break;
|
||||
default:
|
||||
dir = 0;
|
||||
break;
|
||||
|
|
@ -1980,6 +1965,9 @@ void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
|||
this->tiltTarget = this->currentTiltPos;
|
||||
}
|
||||
}
|
||||
else if(this->shadeType == shade_types::garage1 && cmd == somfy_commands::My) {
|
||||
SomfyRemote::sendCommand(somfy_commands::Toggle, repeat);
|
||||
}
|
||||
else {
|
||||
SomfyRemote::sendCommand(cmd, repeat);
|
||||
}
|
||||
|
|
@ -2054,6 +2042,12 @@ void SomfyShade::moveToTiltTarget(float target) {
|
|||
}
|
||||
void SomfyShade::moveToTarget(float pos, float tilt) {
|
||||
somfy_commands cmd = somfy_commands::My;
|
||||
if(this->shadeType == shade_types::garage1) {
|
||||
// Overload this as we cannot seek a position on a garage door.
|
||||
this->target = this->currentPos = pos;
|
||||
this->emitState();
|
||||
return;
|
||||
}
|
||||
if(this->tiltType == tilt_types::tiltonly) {
|
||||
this->currentPos = this->target = 100.0f;
|
||||
pos = 100;
|
||||
|
|
@ -2571,6 +2565,10 @@ void SomfyShadeController::sendFrame(somfy_frame_t &frame, uint8_t repeat) {
|
|||
frm[7] = 132;
|
||||
frm[9] = 63;
|
||||
break;
|
||||
case somfy_commands::Toggle:
|
||||
frm[7] = 136;
|
||||
frm[9] = 34;
|
||||
break;
|
||||
default:
|
||||
frm[9] = 46;
|
||||
break;
|
||||
|
|
|
|||
10
Somfy.h
10
Somfy.h
|
|
@ -39,12 +39,12 @@ enum class somfy_commands : byte {
|
|||
SunFlag = 0x9,
|
||||
Flag = 0xA,
|
||||
StepDown = 0xB,
|
||||
UnknownC = 0xC,
|
||||
Toggle = 0xC,
|
||||
UnknownD = 0xD,
|
||||
Sensor = 0xE,
|
||||
RTWProto = 0xF, // RTW Protocol
|
||||
// Command extensions for 80 bit frames
|
||||
StepUp = 0x8B
|
||||
StepUp = 0x8B,
|
||||
};
|
||||
enum class group_types : byte {
|
||||
channel = 0x00
|
||||
|
|
@ -54,7 +54,10 @@ enum class shade_types : byte {
|
|||
blind = 0x01,
|
||||
drapery = 0x02,
|
||||
awning = 0x03,
|
||||
shutter = 0x04
|
||||
shutter = 0x04,
|
||||
garage1 = 0x05,
|
||||
garage3 = 0x06
|
||||
|
||||
};
|
||||
enum class tilt_types : byte {
|
||||
none = 0x00,
|
||||
|
|
@ -228,6 +231,7 @@ class SomfyShade : public SomfyRemote {
|
|||
float currentPos = 0.0f;
|
||||
float currentTiltPos = 0.0f;
|
||||
//uint16_t movement = 0;
|
||||
int8_t lastMovement = 0;
|
||||
int8_t direction = 0; // 0 = stopped, 1=down, -1=up.
|
||||
int8_t tiltDirection = 0; // 0=stopped, 1=clockwise, -1=counter clockwise
|
||||
float target = 0.0f;
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -490,6 +490,40 @@ i.icss-somfy-up {
|
|||
left: 50%;
|
||||
transform: translate(-50%,-30%) rotate(-45deg);
|
||||
}
|
||||
i.icss-somfy-toggle {
|
||||
width: .15em;
|
||||
height: .55em;
|
||||
border-radius: .1em;
|
||||
margin: .2em .4em .25em .45em;
|
||||
}
|
||||
|
||||
i.icss-somfy-toggle:before {
|
||||
width: .45em;
|
||||
height: .5em;
|
||||
border-radius: .3em .12em 0 .2em;
|
||||
border: .1em solid transparent;
|
||||
border-width: 0 0 .35em 0;
|
||||
background-color: currentColor;
|
||||
box-shadow: -.1em 0, -.3em -.35em;
|
||||
transform: rotate(-45deg);
|
||||
clip: rect(-.5em .5em .15em -.5em);
|
||||
left: .15em;
|
||||
top: .35em;
|
||||
}
|
||||
|
||||
i.icss-somfy-toggle:after {
|
||||
width: .52em;
|
||||
height: .52em;
|
||||
border: .065em solid currentColor;
|
||||
border-bottom-color: transparent;
|
||||
border-radius: 50%;
|
||||
transform: translateX(-50%);
|
||||
top: -.22em;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
i.icss-home {
|
||||
width: .8em;
|
||||
height: .45em;
|
||||
|
|
@ -652,6 +686,34 @@ i.icss-window-tilt {
|
|||
font-weight:bold;
|
||||
font-size:.3em;
|
||||
}
|
||||
i.icss-garage {
|
||||
width: 1.1em;
|
||||
height: .7em;
|
||||
background-color: transparent;
|
||||
box-shadow: inset 0 0.01em 0 0.04em, inset 0.01em 0px 0em, inset 0.01em 0.01em 1px 0em;
|
||||
margin: .4em 0 0;
|
||||
}
|
||||
|
||||
i.icss-garage:after {
|
||||
border-width: 0 .8em .4em;
|
||||
border-style: solid;
|
||||
border-color: currentColor transparent;
|
||||
transform: translateX(-50%);
|
||||
top: -0.4em;
|
||||
left: 50%;
|
||||
clip-path: polygon(50% 0, 99% 50%, 50% 250%, 0 50%);
|
||||
}
|
||||
|
||||
i.icss-garage:before {
|
||||
width: calc(100% - .08em);
|
||||
height: calc(var(--shade-position, 0%) - 0em);
|
||||
left: 0.05em;
|
||||
border-bottom: outset 0.025em gray;
|
||||
background-image: repeating-linear-gradient(var(--shade-color, currentColor) 0% 50%, rgba(71, 212, 255, 0) 0% 75%);
|
||||
background-position: 0 0, 100% 100%;
|
||||
background-size: 0.01em 0.2em;
|
||||
background-color: rgba(71, 212, 255, 0);
|
||||
}
|
||||
|
||||
i.icss-upload {
|
||||
width: 1em;
|
||||
|
|
|
|||
|
|
@ -313,6 +313,8 @@
|
|||
<option value="1">Blind</option>
|
||||
<option value="2">Drapery</option>
|
||||
<option value="3">Awning</option>
|
||||
<option value="5">Garage (1-button)</option>
|
||||
<option value="6">Garage (3-button)</option>
|
||||
</select>
|
||||
<label for="selShadeType">Type</label>
|
||||
</div>
|
||||
|
|
@ -322,11 +324,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="divSomfyButtons" style="float:right;margin-top:10px;position:relative">
|
||||
<div id="divSomfyButtons" class="shadectl-buttons" 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 class="button-outline" data-cmd="up" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'up');"><i class="icss-somfy-up"></i></div>
|
||||
<div class="button-outline" data-cmd="my" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'my');" style="font-size: 2em; padding: 10px;"><span>my</span></div>
|
||||
<div class="button-outline" data-cmd="down" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'down');"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
||||
<div class="button-outline toggle-button" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="toggle" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'toggle');"><i class="icss-somfy-toggle" style="margin-top:-4px;"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-group" style="padding:0px;">
|
||||
|
|
@ -358,7 +361,7 @@
|
|||
<label for="fldTiltTime">Tilt Time (ms)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="divStepSettings" style="display:none;">
|
||||
<div id="divStepSettings">
|
||||
<div class="field-group">
|
||||
<input id="slidStepSize" name="stepSize" type="range" min="1" max="1000" step="1" data-bind="stepSize" data-datatype="int" style="width:100%;" oninput="somfy.stepSizeChanged(this);" />
|
||||
<label for="slidStepSize" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;">
|
||||
|
|
@ -369,7 +372,7 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:-10px;">
|
||||
<div id="divSunSensor" style="margin-top:-10px;">
|
||||
<div class="field-group">
|
||||
<input id="cbHasSunsensor" name="hasSunSensor" data-bind="sunSensor" type="checkbox" style="" />
|
||||
<label for="cbHasSunSensor" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Has Sun Sensor</label>
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ Number.prototype.fmt = function (format, empty) {
|
|||
if (rd.length === 0 && rw.length === 0) return '';
|
||||
return pfx + rw + rd + sfx;
|
||||
};
|
||||
var baseUrl = window.location.protocol === 'file:' ? 'http://ESPSomfyRTS' : '';
|
||||
var baseUrl = window.location.protocol === 'file:' ? 'http://ESPSomfyRTS.local' : '';
|
||||
//var baseUrl = '';
|
||||
function makeBool(val) {
|
||||
if (typeof val === 'boolean') return val;
|
||||
|
|
@ -1961,6 +1961,10 @@ class Somfy {
|
|||
case 4:
|
||||
divCtl += ' icss-shutter';
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
divCtl += ' icss-garage';
|
||||
break;
|
||||
default:
|
||||
divCtl += ' icss-window-shade';
|
||||
break;
|
||||
|
|
@ -1973,18 +1977,19 @@ class Somfy {
|
|||
divCtl += `<span class="shadectl-name">${shade.name}</span>`;
|
||||
if (shade.tiltType === 3)
|
||||
divCtl += `<span class="shadectl-mypos"><label>My Tilt: </label><span id="spanMyTiltPos">${shade.myTiltPos > 0 ? shade.myTiltPos + '%' : '---'}</span>`
|
||||
else {
|
||||
else if(shade.shadeType !== 5) {
|
||||
divCtl += `<span class="shadectl-mypos"><label>My: </label><span id="spanMyPos">${shade.myPos > 0 ? shade.myPos + '%' : '---'}</span>`;
|
||||
if (shade.myTiltPos > 0 && shade.tiltType !== 3) divCtl += `<label> Tilt: </label><span id="spanMyTiltPos">${shade.myTiltPos > 0 ? shade.myTiltPos + '%' : '---'}</span>`;
|
||||
}
|
||||
divCtl += '</div>';
|
||||
|
||||
divCtl += `<div class="shadectl-buttons">`;
|
||||
divCtl += `<div class="shadectl-buttons" data-shadeType="${shade.shadeType}">`;
|
||||
divCtl += `<div class="button-sunflag cmd-button" data-cmd="sunflag" data-shadeid="${shade.shadeId}" data-on="${shade.flags & 0x01 ? 'true' : 'false'}" style="${!shade.sunSensor ? 'display:none' : ''}"><i class="icss-sun-c"></i><i class="icss-sun-o"></i></div>`;
|
||||
divCtl += `<div class="button-outline cmd-button" data-cmd="up" data-shadeid="${shade.shadeId}"><i class="icss-somfy-up"></i></div>`;
|
||||
divCtl += `<div class="button-outline cmd-button my-button" data-cmd="my" data-shadeid="${shade.shadeId}" style="font-size:2em;padding:10px;"><span>my</span></div>`;
|
||||
divCtl += `<div class="button-outline cmd-button" data-cmd="down" data-shadeid="${shade.shadeId}"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>`;
|
||||
divCtl += `<div class="button-outline cmd-button toggle-button" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="toggle" data-shadeid="${shade.shadeId}"><i class="icss-somfy-toggle" style="margin-top:-4px;"></i></div>`;
|
||||
divCtl += '</div></div>';
|
||||
divCtl += '</div>';
|
||||
}
|
||||
document.getElementById('divShadeList').innerHTML = divCfg;
|
||||
let shadeControls = document.getElementById('divShadeControls');
|
||||
|
|
@ -2414,20 +2419,26 @@ class Somfy {
|
|||
onShadeTypeChanged(el) {
|
||||
let sel = document.getElementById('selShadeType');
|
||||
let tilt = parseInt(document.getElementById('selTiltType').value, 10);
|
||||
let sun = true;
|
||||
let ico = document.getElementById('icoShade');
|
||||
switch (parseInt(sel.value, 10)) {
|
||||
let type = parseInt(sel.value, 10);
|
||||
document.getElementById('somfyShade').setAttribute('data-shadetype', type);
|
||||
document.getElementById('divSomfyButtons').setAttribute('data-shadetype', type);
|
||||
switch (type) {
|
||||
case 1:
|
||||
document.getElementById('divTiltSettings').style.display = '';
|
||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
||||
if (ico.classList.contains('icss-awning')) ico.classList.remove('icss-awning');
|
||||
if (ico.classList.contains('icss-shutter')) ico.classList.remove('icss-shutter');
|
||||
if (!ico.classList.contains('icss-window-blind')) ico.classList.add('icss-window-blind');
|
||||
if (ico.classList.contains('icss-garage')) ico.classList.remove('icss-garage');
|
||||
break;
|
||||
case 3:
|
||||
document.getElementById('divTiltSettings').style.display = 'none';
|
||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
||||
if (ico.classList.contains('icss-window-blind')) ico.classList.remove('icss-window-blind');
|
||||
if (ico.classList.contains('icss-shutter')) ico.classList.remove('icss-shutter');
|
||||
if (ico.classList.contains('icss-garage')) ico.classList.remove('icss-garage');
|
||||
if (!ico.classList.contains('icss-awning')) ico.classList.add('icss-awning');
|
||||
tilt = false;
|
||||
break;
|
||||
|
|
@ -2436,14 +2447,26 @@ class Somfy {
|
|||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
||||
if (ico.classList.contains('icss-window-blind')) ico.classList.remove('icss-window-blind');
|
||||
if (ico.classList.contains('icss-awning')) ico.classList.remove('icss-awning');
|
||||
if (ico.classList.contains('icss-garage')) ico.classList.remove('icss-garage');
|
||||
if (!ico.classList.contains('icss-shutter')) ico.classList.add('icss-shutter');
|
||||
tilt = false;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 5:
|
||||
document.getElementById('divTiltSettings').style.display = 'none';
|
||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
||||
if (ico.classList.contains('icss-window-blind')) ico.classList.remove('icss-window-blind');
|
||||
if (ico.classList.contains('icss-awning')) ico.classList.remove('icss-awning');
|
||||
if (ico.classList.contains('icss-shutter')) ico.classList.remove('icss-shutter');
|
||||
if (!ico.classList.contains('icss-garage')) ico.classList.add('icss-garage');
|
||||
sun = false;
|
||||
tilt = false;
|
||||
break;
|
||||
default:
|
||||
if (ico.classList.contains('icss-window-blind')) ico.classList.remove('icss-window-blind');
|
||||
if (ico.classList.contains('icss-awning')) ico.classList.remove('icss-awning');
|
||||
if (!ico.classList.contains('icss-window-shade')) ico.classList.add('icss-window-shade');
|
||||
if (ico.classList.contains('icss-garage')) ico.classList.remove('icss-garage');
|
||||
if (ico.classList.contains('icss-shutter')) ico.classList.remove('icss-shutter');
|
||||
document.getElementById('divTiltSettings').style.display = 'none';
|
||||
tilt = false;
|
||||
|
|
@ -2452,9 +2475,11 @@ class Somfy {
|
|||
document.getElementById('fldTiltTime').parentElement.style.display = tilt ? 'inline-block' : 'none';
|
||||
document.getElementById('divLiftSettings').style.display = tilt === 3 ? 'none' : '';
|
||||
document.querySelector('#divSomfyButtons i.icss-window-tilt').style.display = tilt ? '' : 'none';
|
||||
document.getElementById('divSunSensor').style.display = sun ? '' : 'none';
|
||||
}
|
||||
onShadeBitLengthChanged(el) {
|
||||
document.getElementById('divStepSettings').style.display = parseInt(el.value, 10) === 80 ? '' : 'none';
|
||||
document.getElementById('somfyShade').setAttribute('data-bitlength', el.value);
|
||||
//document.getElementById('divStepSettings').style.display = parseInt(el.value, 10) === 80 ? '' : 'none';
|
||||
}
|
||||
openEditShade(shadeId) {
|
||||
if (typeof shadeId === 'undefined') {
|
||||
|
|
@ -2506,6 +2531,9 @@ class Somfy {
|
|||
this.onShadeTypeChanged(document.getElementById('selShadeType'));
|
||||
let ico = document.getElementById('icoShade');
|
||||
switch (shade.shadeType) {
|
||||
case 0:
|
||||
document.getElementById('divSunSensor').style.display = '';
|
||||
break;
|
||||
case 1:
|
||||
ico.classList.remove('icss-window-shade');
|
||||
ico.classList.add('icss-window-blind');
|
||||
|
|
@ -2513,11 +2541,19 @@ class Somfy {
|
|||
case 3:
|
||||
ico.classList.remove('icss-window-shade');
|
||||
ico.classList.add('icss-awning');
|
||||
document.getElementById('divSunSensor').style.display = '';
|
||||
break;
|
||||
case 4:
|
||||
ico.classList.remove('icss-window-shade');
|
||||
ico.classList.add('icss-shutter');
|
||||
document.getElementById('divSunSensor').style.display = '';
|
||||
break;
|
||||
case 5:
|
||||
ico.classList.remove('icss-window-shade');
|
||||
ico.classList.add('icss-garage');
|
||||
document.getElementById('divSunSensor').style.display = 'none';
|
||||
break;
|
||||
|
||||
}
|
||||
let tilt = ico.parentElement.querySelector('i.icss-window-tilt');
|
||||
tilt.style.display = shade.tiltType !== 0 ? '' : 'none';
|
||||
|
|
@ -2896,22 +2932,39 @@ class Somfy {
|
|||
});
|
||||
}
|
||||
pairShade(shadeId) {
|
||||
let shadeType = parseInt(document.getElementById('somfyShade').getAttribute('data-shadetype'), 10);
|
||||
let div = document.createElement('div');
|
||||
let html = `<div id="divPairing" class="instructions" data-type="link-remote" data-shadeid="${shadeId}">`;
|
||||
html += '<div>Follow the instructions below to pair this shade with a Somfy motor</div>';
|
||||
html += '<hr style="width:100%;margin:0px;"></hr>';
|
||||
html += '<ul style="width:100%;margin:0px;padding-left:20px;font-size:14px;">';
|
||||
html += '<li>Open the shade memory using an existing remote by pressing the prog button on the back until the shade jogs.</li>';
|
||||
html += '<li>After the shade jogs press the Prog button below</li>';
|
||||
html += '<li>The shade should jog again indicating that the shade is paired. NOTE: On some motors you may need to press and hold the Prog button.</li>';
|
||||
html += '<li>If the shade jogs, you can press the shade paired button.</li>';
|
||||
html += '<li>If the shade does not jog, try pressing the prog button again.</li>';
|
||||
html += '</ul>';
|
||||
html += `<div class="button-container">`;
|
||||
html += `<button id="btnSendPairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;">Prog</button>`;
|
||||
html += `<button id="btnMarkPaired" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;" onclick="somfy.setPaired(${shadeId}, true);">Shade Paired</button>`;
|
||||
html += `<button id="btnStopPairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block" >Close</button>`;
|
||||
html += `</div>`;
|
||||
if (shadeType === 5 || shadeType === 6) {
|
||||
html += '<div>Follow the instructions below to pair ESPSomfy RTS with an RTS Garage Door motor</div>';
|
||||
html += '<hr style="width:100%;margin:0px;"></hr>';
|
||||
html += '<ul style="width:100%;margin:0px;padding-left:20px;font-size:14px;">';
|
||||
html += '<li>Open the garage door motor memory per instructions for your motor.</li>';
|
||||
html += '<li>Once the memory is opened, press the prog button below</li>';
|
||||
html += '<li>For single button control ESPSomfy RTS will send a toggle command but for a 3 button control it will send a prog command.</li>';
|
||||
html += '</ul>';
|
||||
html += `<div class="button-container">`;
|
||||
html += `<button id="btnSendPairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;">Prog</button>`;
|
||||
html += `<button id="btnMarkPaired" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;" onclick="somfy.setPaired(${shadeId}, true);">Door Paired</button>`;
|
||||
html += `<button id="btnStopPairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block" >Close</button>`;
|
||||
html += `</div>`;
|
||||
}
|
||||
else {
|
||||
html += '<div>Follow the instructions below to pair this shade with a Somfy motor</div>';
|
||||
html += '<hr style="width:100%;margin:0px;"></hr>';
|
||||
html += '<ul style="width:100%;margin:0px;padding-left:20px;font-size:14px;">';
|
||||
html += '<li>Open the shade memory using an existing remote by pressing the prog button on the back until the shade jogs.</li>';
|
||||
html += '<li>After the shade jogs press the Prog button below</li>';
|
||||
html += '<li>The shade should jog again indicating that the shade is paired. NOTE: On some motors you may need to press and hold the Prog button.</li>';
|
||||
html += '<li>If the shade jogs, you can press the shade paired button.</li>';
|
||||
html += '<li>If the shade does not jog, try pressing the prog button again.</li>';
|
||||
html += '</ul>';
|
||||
html += `<div class="button-container">`;
|
||||
html += `<button id="btnSendPairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;">Prog</button>`;
|
||||
html += `<button id="btnMarkPaired" type="button" style="padding-left:20px;padding-right:20px;display:inline-block;" onclick="somfy.setPaired(${shadeId}, true);">Shade Paired</button>`;
|
||||
html += `<button id="btnStopPairing" type="button" style="padding-left:20px;padding-right:20px;display:inline-block" >Close</button>`;
|
||||
html += `</div>`;
|
||||
}
|
||||
let fnRepeatProg = (err, shade) => {
|
||||
if (this.btnTimer) {
|
||||
clearTimeout(this.btnTimer);
|
||||
|
|
|
|||
|
|
@ -664,16 +664,6 @@ div.wait-overlay > .lds-roller {
|
|||
padding: 7px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#divSomfyButtons div.button-outline {
|
||||
margin-top: -10px;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
margin-bottom: 0px;
|
||||
display: inline-block;
|
||||
padding: 7px;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.shade-positioner {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -109,4 +109,35 @@
|
|||
padding: 25px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#divSomfyButtons div.button-outline {
|
||||
margin-top: -10px;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
margin-bottom: 0px;
|
||||
padding: 7px;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.shadectl-buttons div.button-outline {
|
||||
display: inline-block;
|
||||
}
|
||||
.shadectl-buttons[data-shadetype="6"] > .cmd-button[data-cmd="sunflag"],
|
||||
.shadectl-buttons[data-shadetype="5"] > .cmd-button[data-cmd="sunflag"],
|
||||
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="my"],
|
||||
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="up"],
|
||||
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="down"] {
|
||||
display: none;
|
||||
}
|
||||
.shadectl-buttons[data-shadetype="0"] > .button-outline[data-cmd="toggle"],
|
||||
.shadectl-buttons[data-shadetype="1"] > .button-outline[data-cmd="toggle"],
|
||||
.shadectl-buttons[data-shadetype="2"] > .button-outline[data-cmd="toggle"],
|
||||
.shadectl-buttons[data-shadetype="3"] > .button-outline[data-cmd="toggle"],
|
||||
.shadectl-buttons[data-shadetype="4"] > .button-outline[data-cmd="toggle"],
|
||||
.shadectl-buttons[data-shadetype="6"] > .button-outline[data-cmd="toggle"] {
|
||||
display: none;
|
||||
}
|
||||
#somfyShade[data-bitlength="56"] #divStepSettings,
|
||||
#somfyShade[data-shadetype="5"] #divStepSettings,
|
||||
#somfyShade[data-shadetype="6"] #divStepSettings {
|
||||
display:none;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue