mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 11:02:12 +01:00
parent
d97f150439
commit
0c36c8e746
9 changed files with 398 additions and 257 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
#ifndef configsettings_h
|
#ifndef configsettings_h
|
||||||
#define configsettings_h
|
#define configsettings_h
|
||||||
|
|
||||||
#define FW_VERSION "v2.2.2b"
|
#define FW_VERSION "v2.2.2c"
|
||||||
enum DeviceStatus {
|
enum DeviceStatus {
|
||||||
DS_OK = 0,
|
DS_OK = 0,
|
||||||
DS_ERROR = 1,
|
DS_ERROR = 1,
|
||||||
|
|
|
||||||
64
Somfy.cpp
64
Somfy.cpp
|
|
@ -820,6 +820,17 @@ void SomfyShade::setGPIOs() {
|
||||||
digitalWrite(this->gpioDown, this->currentPos == 100 ? HIGH : LOW);
|
digitalWrite(this->gpioDown, this->currentPos == 100 ? HIGH : LOW);
|
||||||
this->gpioDir = this->currentPos == 100 ? 1 : -1;
|
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);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
digitalWrite(this->gpioUp, LOW);
|
||||||
|
digitalWrite(this->gpioDown, HIGH);
|
||||||
|
}
|
||||||
|
this->gpioDir = this->currentPos == 100 ? 1 : -1;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
switch(dir) {
|
switch(dir) {
|
||||||
case -1:
|
case -1:
|
||||||
|
|
@ -867,7 +878,7 @@ void SomfyShade::triggerGPIOs(somfy_frame_t &frame) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case somfy_commands::Up:
|
case somfy_commands::Up:
|
||||||
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1) {
|
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) {
|
||||||
digitalWrite(this->gpioMy, LOW);
|
digitalWrite(this->gpioMy, LOW);
|
||||||
digitalWrite(this->gpioDown, LOW);
|
digitalWrite(this->gpioDown, LOW);
|
||||||
digitalWrite(this->gpioUp, HIGH);
|
digitalWrite(this->gpioUp, HIGH);
|
||||||
|
|
@ -877,7 +888,7 @@ void SomfyShade::triggerGPIOs(somfy_frame_t &frame) {
|
||||||
break;
|
break;
|
||||||
case somfy_commands::Toggle:
|
case somfy_commands::Toggle:
|
||||||
case somfy_commands::Down:
|
case somfy_commands::Down:
|
||||||
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1) {
|
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) {
|
||||||
digitalWrite(this->gpioMy, LOW);
|
digitalWrite(this->gpioMy, LOW);
|
||||||
digitalWrite(this->gpioUp, LOW);
|
digitalWrite(this->gpioUp, LOW);
|
||||||
}
|
}
|
||||||
|
|
@ -886,7 +897,7 @@ void SomfyShade::triggerGPIOs(somfy_frame_t &frame) {
|
||||||
Serial.printf("UP: false, DOWN: true, MY: false\n");
|
Serial.printf("UP: false, DOWN: true, MY: false\n");
|
||||||
break;
|
break;
|
||||||
case somfy_commands::MyUp:
|
case somfy_commands::MyUp:
|
||||||
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1) {
|
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) {
|
||||||
digitalWrite(this->gpioDown, LOW);
|
digitalWrite(this->gpioDown, LOW);
|
||||||
digitalWrite(this->gpioMy, HIGH);
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
digitalWrite(this->gpioUp, HIGH);
|
digitalWrite(this->gpioUp, HIGH);
|
||||||
|
|
@ -894,7 +905,7 @@ void SomfyShade::triggerGPIOs(somfy_frame_t &frame) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case somfy_commands::MyDown:
|
case somfy_commands::MyDown:
|
||||||
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1) {
|
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) {
|
||||||
digitalWrite(this->gpioUp, LOW);
|
digitalWrite(this->gpioUp, LOW);
|
||||||
digitalWrite(this->gpioMy, HIGH);
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
digitalWrite(this->gpioDown, HIGH);
|
digitalWrite(this->gpioDown, HIGH);
|
||||||
|
|
@ -902,7 +913,7 @@ void SomfyShade::triggerGPIOs(somfy_frame_t &frame) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case somfy_commands::MyUpDown:
|
case somfy_commands::MyUpDown:
|
||||||
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1) {
|
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::garage1 && this->shadeType != shade_types::drycontact2) {
|
||||||
digitalWrite(this->gpioUp, HIGH);
|
digitalWrite(this->gpioUp, HIGH);
|
||||||
digitalWrite(this->gpioMy, HIGH);
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
digitalWrite(this->gpioDown, HIGH);
|
digitalWrite(this->gpioDown, HIGH);
|
||||||
|
|
@ -924,7 +935,7 @@ void SomfyShade::checkMovement() {
|
||||||
int32_t downTime = (int32_t)this->downTime;
|
int32_t downTime = (int32_t)this->downTime;
|
||||||
int32_t upTime = (int32_t)this->upTime;
|
int32_t upTime = (int32_t)this->upTime;
|
||||||
int32_t tiltTime = (int32_t)this->tiltTime;
|
int32_t tiltTime = (int32_t)this->tiltTime;
|
||||||
if(this->shadeType == shade_types::drycontact) downTime = upTime = tiltTime = 1;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) downTime = upTime = tiltTime = 1;
|
||||||
|
|
||||||
|
|
||||||
// We are checking movement for essentially 3 types of motors.
|
// We are checking movement for essentially 3 types of motors.
|
||||||
|
|
@ -1334,6 +1345,9 @@ void SomfyShade::publishDisco() {
|
||||||
obj["state_closing"] = this->flipPosition ? "-1" : "1";
|
obj["state_closing"] = this->flipPosition ? "-1" : "1";
|
||||||
obj["state_opening"] = this->flipPosition ? "1" : "-1";
|
obj["state_opening"] = this->flipPosition ? "1" : "-1";
|
||||||
break;
|
break;
|
||||||
|
case shade_types::lgate:
|
||||||
|
case shade_types::cgate:
|
||||||
|
case shade_types::rgate:
|
||||||
case shade_types::ldrapery:
|
case shade_types::ldrapery:
|
||||||
case shade_types::rdrapery:
|
case shade_types::rdrapery:
|
||||||
case shade_types::cdrapery:
|
case shade_types::cdrapery:
|
||||||
|
|
@ -1373,6 +1387,7 @@ void SomfyShade::publishDisco() {
|
||||||
obj["state_closing"] = this->flipPosition ? "-1" : "1";
|
obj["state_closing"] = this->flipPosition ? "-1" : "1";
|
||||||
obj["state_opening"] = this->flipPosition ? "1" : "-1";
|
obj["state_opening"] = this->flipPosition ? "1" : "-1";
|
||||||
break;
|
break;
|
||||||
|
case shade_types::drycontact2:
|
||||||
case shade_types::drycontact:
|
case shade_types::drycontact:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -1385,7 +1400,7 @@ void SomfyShade::publishDisco() {
|
||||||
obj["state_opening"] = this->flipPosition ? "1" : "-1";
|
obj["state_opening"] = this->flipPosition ? "1" : "-1";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(this->shadeType != shade_types::drycontact) {
|
if(this->shadeType != shade_types::drycontact && this->shadeType != shade_types::drycontact2) {
|
||||||
if(this->tiltType != tilt_types::tiltonly) {
|
if(this->tiltType != tilt_types::tiltonly) {
|
||||||
obj["command_topic"] = "~/direction/set";
|
obj["command_topic"] = "~/direction/set";
|
||||||
obj["position_topic"] = "~/position";
|
obj["position_topic"] = "~/position";
|
||||||
|
|
@ -1881,7 +1896,7 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
case somfy_commands::Sensor:
|
case somfy_commands::Sensor:
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
if(this->shadeType == shade_types::drycontact) return;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) return;
|
||||||
{
|
{
|
||||||
const uint8_t prevFlags = this->flags;
|
const uint8_t prevFlags = this->flags;
|
||||||
const bool wasSunny = prevFlags & static_cast<uint8_t>(somfy_flags_t::Sunny);
|
const bool wasSunny = prevFlags & static_cast<uint8_t>(somfy_flags_t::Sunny);
|
||||||
|
|
@ -1960,13 +1975,13 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
case somfy_commands::MyUpDown:
|
case somfy_commands::MyUpDown:
|
||||||
case somfy_commands::UpDown:
|
case somfy_commands::UpDown:
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
if(this->shadeType == shade_types::drycontact) return;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) return;
|
||||||
this->emitCommand(cmd, internal ? "internal" : "remote", frame.remoteAddress);
|
this->emitCommand(cmd, internal ? "internal" : "remote", frame.remoteAddress);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case somfy_commands::Flag:
|
case somfy_commands::Flag:
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
if(this->shadeType == shade_types::drycontact) return;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) return;
|
||||||
if(this->lastFrame.rollingCode & 0x8000) return; // Some sensors send bogus frames with a rollingCode >= 32768 that cause them to change the state.
|
if(this->lastFrame.rollingCode & 0x8000) return; // Some sensors send bogus frames with a rollingCode >= 32768 that cause them to change the state.
|
||||||
this->p_sunFlag(false);
|
this->p_sunFlag(false);
|
||||||
//this->flags &= ~(static_cast<uint8_t>(somfy_flags_t::SunFlag));
|
//this->flags &= ~(static_cast<uint8_t>(somfy_flags_t::SunFlag));
|
||||||
|
|
@ -1976,7 +1991,7 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
somfy.updateGroupFlags();
|
somfy.updateGroupFlags();
|
||||||
break;
|
break;
|
||||||
case somfy_commands::SunFlag:
|
case somfy_commands::SunFlag:
|
||||||
if(this->shadeType == shade_types::drycontact) return;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) return;
|
||||||
if(this->lastFrame.rollingCode & 0x8000) return; // Some sensors send bogus frames with a rollingCode >= 32768 that cause them to change the state.
|
if(this->lastFrame.rollingCode & 0x8000) return; // Some sensors send bogus frames with a rollingCode >= 32768 that cause them to change the state.
|
||||||
{
|
{
|
||||||
const bool isWindy = this->flags & static_cast<uint8_t>(somfy_flags_t::Windy);
|
const bool isWindy = this->flags & static_cast<uint8_t>(somfy_flags_t::Windy);
|
||||||
|
|
@ -2009,6 +2024,13 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(this->shadeType == shade_types::drycontact2) {
|
||||||
|
if(this->lastFrame.processed) return;
|
||||||
|
this->lastFrame.processed = true;
|
||||||
|
if(this->currentPos != 0.0f) this->p_target(0);
|
||||||
|
this->emitCommand(cmd, internal ? "internal" : "remote", frame.remoteAddress);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(this->tiltType == tilt_types::tiltmotor || this->tiltType == tilt_types::euromode) {
|
if(this->tiltType == tilt_types::tiltmotor || this->tiltType == tilt_types::euromode) {
|
||||||
// Wait another half second just in case we are potentially processing a tilt.
|
// Wait another half second just in case we are potentially processing a tilt.
|
||||||
if(!internal) this->lastFrame.await = curTime + 500;
|
if(!internal) this->lastFrame.await = curTime + 500;
|
||||||
|
|
@ -2030,6 +2052,13 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(this->shadeType == shade_types::drycontact2) {
|
||||||
|
if(this->lastFrame.processed) return;
|
||||||
|
this->lastFrame.processed = true;
|
||||||
|
if(this->currentPos != 100.0f) this->p_target(100);
|
||||||
|
this->emitCommand(cmd, internal ? "internal" : "remote", frame.remoteAddress);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!this->windLast || (curTime - this->windLast) >= SOMFY_NO_WIND_REMOTE_TIMEOUT) {
|
if (!this->windLast || (curTime - this->windLast) >= SOMFY_NO_WIND_REMOTE_TIMEOUT) {
|
||||||
if(this->tiltType == tilt_types::tiltmotor || this->tiltType == tilt_types::euromode) {
|
if(this->tiltType == tilt_types::tiltmotor || this->tiltType == tilt_types::euromode) {
|
||||||
// Wait another half seccond just in case we are potentially processing a tilt.
|
// Wait another half seccond just in case we are potentially processing a tilt.
|
||||||
|
|
@ -2047,6 +2076,7 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case somfy_commands::My:
|
case somfy_commands::My:
|
||||||
|
if(this->shadeType == shade_types::drycontact2) return;
|
||||||
if(this->shadeType == shade_types::garage1) {
|
if(this->shadeType == shade_types::garage1) {
|
||||||
if(this->lastFrame.processed) return;
|
if(this->lastFrame.processed) return;
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
|
|
@ -2093,7 +2123,7 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
case somfy_commands::StepUp:
|
case somfy_commands::StepUp:
|
||||||
if(this->lastFrame.processed) return;
|
if(this->lastFrame.processed) return;
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
if(this->shadeType == shade_types::drycontact) return;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) return;
|
||||||
dir = 0;
|
dir = 0;
|
||||||
// With the step commands and integrated shades
|
// With the step commands and integrated shades
|
||||||
// the motor must tilt in the direction first then move
|
// the motor must tilt in the direction first then move
|
||||||
|
|
@ -2115,7 +2145,7 @@ void SomfyShade::processFrame(somfy_frame_t &frame, bool internal) {
|
||||||
case somfy_commands::StepDown:
|
case somfy_commands::StepDown:
|
||||||
if(this->lastFrame.processed) return;
|
if(this->lastFrame.processed) return;
|
||||||
this->lastFrame.processed = true;
|
this->lastFrame.processed = true;
|
||||||
if(this->shadeType == shade_types::drycontact) return;
|
if(this->shadeType == shade_types::drycontact || this->shadeType == shade_types::drycontact2) return;
|
||||||
dir = 1;
|
dir = 1;
|
||||||
// With the step commands and integrated shades
|
// With the step commands and integrated shades
|
||||||
// the motor must tilt in the direction first then move
|
// the motor must tilt in the direction first then move
|
||||||
|
|
@ -2474,6 +2504,7 @@ void SomfyShade::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
||||||
else if(cmd == somfy_commands::My) {
|
else if(cmd == somfy_commands::My) {
|
||||||
if(this->shadeType == shade_types::garage1 || this->shadeType == shade_types::drycontact)
|
if(this->shadeType == shade_types::garage1 || this->shadeType == shade_types::drycontact)
|
||||||
SomfyRemote::sendCommand(cmd, repeat);
|
SomfyRemote::sendCommand(cmd, repeat);
|
||||||
|
else if(this->shadeType == shade_types::drycontact2) return;
|
||||||
else if(this->isIdle()) {
|
else if(this->isIdle()) {
|
||||||
this->moveToMyPosition();
|
this->moveToMyPosition();
|
||||||
return;
|
return;
|
||||||
|
|
@ -2653,6 +2684,8 @@ bool SomfyShade::usesPin(uint8_t pin) {
|
||||||
else if(this->shadeType == shade_types::garage1) {
|
else if(this->shadeType == shade_types::garage1) {
|
||||||
if(this->proto == radio_proto::GP_Relay && this->gpioUp == pin) return true;
|
if(this->proto == radio_proto::GP_Relay && this->gpioUp == pin) return true;
|
||||||
}
|
}
|
||||||
|
else if(this->shadeType == shade_types::drycontact2)
|
||||||
|
if(this->proto == radio_proto::GP_Relay && (this->gpioUp == pin || this->gpioDown == pin)) return true;
|
||||||
else {
|
else {
|
||||||
if(this->gpioUp == pin) return true;
|
if(this->gpioUp == pin) return true;
|
||||||
else if(this->proto == radio_proto::GP_Remote && this->gpioMy == pin) return true;
|
else if(this->proto == radio_proto::GP_Remote && this->gpioMy == pin) return true;
|
||||||
|
|
@ -2682,6 +2715,8 @@ int8_t SomfyShade::validateJSON(JsonObject &obj) {
|
||||||
type = shade_types::awning;
|
type = shade_types::awning;
|
||||||
else if(strncmp(obj["shadeType"].as<const char *>(), "shutter", 8) == 0)
|
else if(strncmp(obj["shadeType"].as<const char *>(), "shutter", 8) == 0)
|
||||||
type = shade_types::shutter;
|
type = shade_types::shutter;
|
||||||
|
else if(strncmp(obj["shadeType"].as<const char *>(), "drycontact2", 12) == 0)
|
||||||
|
type = shade_types::drycontact2;
|
||||||
else if(strncmp(obj["shadeType"].as<const char *>(), "drycontact", 11) == 0)
|
else if(strncmp(obj["shadeType"].as<const char *>(), "drycontact", 11) == 0)
|
||||||
type = shade_types::drycontact;
|
type = shade_types::drycontact;
|
||||||
}
|
}
|
||||||
|
|
@ -2698,6 +2733,7 @@ int8_t SomfyShade::validateJSON(JsonObject &obj) {
|
||||||
uint8_t downPin = obj.containsKey("gpioDown") ? obj["gpioDown"].as<uint8_t>() : this->gpioDown;
|
uint8_t downPin = obj.containsKey("gpioDown") ? obj["gpioDown"].as<uint8_t>() : this->gpioDown;
|
||||||
uint8_t myPin = obj.containsKey("gpioMy") ? obj["gpioMy"].as<uint8_t>() : this->gpioMy;
|
uint8_t myPin = obj.containsKey("gpioMy") ? obj["gpioMy"].as<uint8_t>() : this->gpioMy;
|
||||||
if(type == shade_types::drycontact || (type == shade_types::garage1 && proto == radio_proto::GP_Remote)) upPin = myPin = 255;
|
if(type == shade_types::drycontact || (type == shade_types::garage1 && proto == radio_proto::GP_Remote)) upPin = myPin = 255;
|
||||||
|
else if(type == shade_types::drycontact2) myPin = 255;
|
||||||
if(proto == radio_proto::GP_Relay) myPin = 255;
|
if(proto == radio_proto::GP_Relay) myPin = 255;
|
||||||
if(somfy.transceiver.config.enabled) {
|
if(somfy.transceiver.config.enabled) {
|
||||||
if((upPin != 255 && somfy.transceiver.usesPin(upPin)) ||
|
if((upPin != 255 && somfy.transceiver.usesPin(upPin)) ||
|
||||||
|
|
@ -2761,6 +2797,8 @@ int8_t SomfyShade::fromJSON(JsonObject &obj) {
|
||||||
this->shadeType = shade_types::awning;
|
this->shadeType = shade_types::awning;
|
||||||
else if(strncmp(obj["shadeType"].as<const char *>(), "shutter", 8) == 0)
|
else if(strncmp(obj["shadeType"].as<const char *>(), "shutter", 8) == 0)
|
||||||
this->shadeType = shade_types::shutter;
|
this->shadeType = shade_types::shutter;
|
||||||
|
else if(strncmp(obj["shadeType"].as<const char *>(), "drycontact2", 12) == 0)
|
||||||
|
this->shadeType = shade_types::drycontact2;
|
||||||
else if(strncmp(obj["shadeType"].as<const char *>(), "drycontact", 11) == 0)
|
else if(strncmp(obj["shadeType"].as<const char *>(), "drycontact", 11) == 0)
|
||||||
this->shadeType = shade_types::drycontact;
|
this->shadeType = shade_types::drycontact;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
Somfy.h
4
Somfy.h
|
|
@ -59,6 +59,10 @@ enum class shade_types : byte {
|
||||||
rdrapery = 0x07,
|
rdrapery = 0x07,
|
||||||
cdrapery = 0x08,
|
cdrapery = 0x08,
|
||||||
drycontact = 0x09,
|
drycontact = 0x09,
|
||||||
|
drycontact2 = 0x0A,
|
||||||
|
lgate = 0x0B,
|
||||||
|
cgate = 0x0C,
|
||||||
|
rgate = 0x0D
|
||||||
};
|
};
|
||||||
enum class tilt_types : byte {
|
enum class tilt_types : byte {
|
||||||
none = 0x00,
|
none = 0x00,
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
224
data/icons.css
224
data/icons.css
|
|
@ -1248,3 +1248,227 @@ i.icss-github-o {
|
||||||
top: .2em;
|
top: .2em;
|
||||||
transform: rotate(65deg);
|
transform: rotate(65deg);
|
||||||
}
|
}
|
||||||
|
i.icss-lgate {
|
||||||
|
width: 1.1em;
|
||||||
|
height: .9em;
|
||||||
|
background-color: transparent;
|
||||||
|
border: .05em solid transparent;
|
||||||
|
border-width: 0 .1em;
|
||||||
|
margin: .1em 0 .07em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-lgate:before {
|
||||||
|
width: 1.1em;
|
||||||
|
height: 1em;
|
||||||
|
border-bottom: solid 1px;
|
||||||
|
top: -.05em;
|
||||||
|
left: -.09em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-lgate > span.icss-panel-right {
|
||||||
|
display:inline-block;
|
||||||
|
width: var(--shade-position, 0%);
|
||||||
|
height: calc(100% - .005em);
|
||||||
|
right: calc(100% - var(--shade-position, 0%));
|
||||||
|
left: 0em;
|
||||||
|
top: 0.025em;
|
||||||
|
border-bottom: solid 0.025em gray;
|
||||||
|
border-right: solid 0.025em gray;
|
||||||
|
background-image: repeating-linear-gradient(to left, rgba(255,255,255,0) 0% 75%, var(--shade-color, currentColor) 75% 100%, rgba(255,255,255,0) 75% 0%);
|
||||||
|
background-position: 0 0, 100% 100%;
|
||||||
|
background-size: .1em 1em;
|
||||||
|
background-color: rgba(71, 212, 255, 0);
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-lgate > span.icss-panel-right:after {
|
||||||
|
position: absolute;
|
||||||
|
content:"";
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 1px var(--shade-color, currentColor);
|
||||||
|
width: .02em;
|
||||||
|
height: .9em;
|
||||||
|
left: -.05em;
|
||||||
|
background: var(--shade-color, currentColor);
|
||||||
|
}
|
||||||
|
i.icss-lgate > span.icss-panel-left {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
i.icss-lgate > span.icss-panel-left:before {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
content:"";
|
||||||
|
left: -.15em;
|
||||||
|
top: -.1em;
|
||||||
|
height: 1em;
|
||||||
|
width: .1em;
|
||||||
|
border: solid 1px;
|
||||||
|
border-top-left-radius: .05em;
|
||||||
|
border-top-right-radius: .05em;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
i.icss-rgate {
|
||||||
|
width: 1.1em;
|
||||||
|
height: .9em;
|
||||||
|
background-color: transparent;
|
||||||
|
border: .05em solid transparent;
|
||||||
|
border-width: 0 .1em;
|
||||||
|
margin: .1em 0 .07em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-rgate:before {
|
||||||
|
width: 1.1em;
|
||||||
|
height: 1em;
|
||||||
|
border-bottom: solid 1px;
|
||||||
|
top: -.05em;
|
||||||
|
left: -.09em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-rgate > span.icss-panel-left {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
width: var(--shade-position, 0%);
|
||||||
|
height: calc(100% - .005em);
|
||||||
|
left: calc(100% - var(--shade-position, 0%));
|
||||||
|
top: 0.025em;
|
||||||
|
border-top: solid 0.025em gray;
|
||||||
|
border-right: solid 0.025em gray;
|
||||||
|
background-image: repeating-linear-gradient(to left, rgba(255,255,255,0) 0% 75%, var(--shade-color, currentColor) 75% 100%, rgba(255,255,255,0) 75% 0%);
|
||||||
|
background-position: 0 0, 100% 100%;
|
||||||
|
background-size: .1em 1em;
|
||||||
|
background-color: rgba(71, 212, 255, 0);
|
||||||
|
margin-left:-.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-rgate > span.icss-panel-left:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 1px var(--shade-color, currentColor);
|
||||||
|
top:-0.07em;
|
||||||
|
width: .02em;
|
||||||
|
height: .9em;
|
||||||
|
left: -.05em;
|
||||||
|
background: var(--shade-color, currentColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-rgate > span.icss-panel-right {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
left:calc(100% - .05em);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-rgate > span.icss-panel-right:before {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
content: "";
|
||||||
|
right: -.15em;
|
||||||
|
top: -.1em;
|
||||||
|
height: 1em;
|
||||||
|
width: .1em;
|
||||||
|
border: solid 1px;
|
||||||
|
border-top-left-radius: .05em;
|
||||||
|
border-top-right-radius: .05em;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-cgate {
|
||||||
|
width: 1.1em;
|
||||||
|
height: .9em;
|
||||||
|
background-color: transparent;
|
||||||
|
border: .05em solid transparent;
|
||||||
|
border-width: 0 .1em;
|
||||||
|
margin: .1em 0 .07em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-cgate:before {
|
||||||
|
width: 1.1em;
|
||||||
|
height: 1em;
|
||||||
|
border-bottom: solid 1px;
|
||||||
|
top: -.05em;
|
||||||
|
left: -.09em;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-cgate > span.icss-panel-left {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(var(--shade-position, 0%) / 2);
|
||||||
|
height: calc(100% - .005em);
|
||||||
|
left: 0%;
|
||||||
|
top: 0.025em;
|
||||||
|
border-bottom: solid 0.025em gray;
|
||||||
|
border-right: solid 0.025em gray;
|
||||||
|
background-image: repeating-linear-gradient(to left, rgba(255,255,255,0) 0% 75%, var(--shade-color, currentColor) 75% 100%, rgba(255,255,255,0) 75% 0%);
|
||||||
|
background-position: 0 0, 100% 100%;
|
||||||
|
background-size: .1em 1em;
|
||||||
|
background-color: rgba(71, 212, 255, 0);
|
||||||
|
margin-left: -.025em;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icss-cgate > span.icss-panel-left:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 1px var(--shade-color, currentColor);
|
||||||
|
top: 0em;
|
||||||
|
width: .02em;
|
||||||
|
height: .9em;
|
||||||
|
left: -.05em;
|
||||||
|
background: var(--shade-color, currentColor);
|
||||||
|
}
|
||||||
|
i.icss-cgate > span.icss-panel-left:before {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
content: "";
|
||||||
|
right: -.15em;
|
||||||
|
top: -.025em;
|
||||||
|
height: 1em;
|
||||||
|
width: .1em;
|
||||||
|
border: solid 1px;
|
||||||
|
border-bottom-left-radius: .05em;
|
||||||
|
border-bottom-right-radius: .05em;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
i.icss-cgate > span.icss-panel-right {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(var(--shade-position, 0%) / 2);
|
||||||
|
height: calc(100% - .005em);
|
||||||
|
left: calc(100% - calc(var(--shade-position, 0%) / 2));
|
||||||
|
top: .025em;
|
||||||
|
border-top: solid 0.025em gray;
|
||||||
|
border-right: solid 0.025em gray;
|
||||||
|
background-image: repeating-linear-gradient(to left, rgba(255,255,255,0) 0% 75%, var(--shade-color, currentColor) 75% 100%, rgba(255,255,255,0) 75% 0%);
|
||||||
|
background-position: 0 0, 100% 100%;
|
||||||
|
background-size: .1em 1em;
|
||||||
|
background-color: rgba(71, 212, 255, 0);
|
||||||
|
margin-left: -.025em;
|
||||||
|
}
|
||||||
|
i.icss-cgate > span.icss-panel-right:after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 1px var(--shade-color, currentColor);
|
||||||
|
top: -.072em;
|
||||||
|
width: .02em;
|
||||||
|
height: .9em;
|
||||||
|
left: -.05em;
|
||||||
|
background: var(--shade-color, currentColor);
|
||||||
|
}
|
||||||
|
i.icss-cgate > span.icss-panel-right:before {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
content: "";
|
||||||
|
right: -.15em;
|
||||||
|
top: -.15em;
|
||||||
|
height: 1em;
|
||||||
|
width: .1em;
|
||||||
|
border: solid 1px;
|
||||||
|
border-top-left-radius: .05em;
|
||||||
|
border-top-right-radius: .05em;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="main.css?v=2.2.2b" type="text/css" />
|
<link rel="stylesheet" href="main.css?v=2.2.2c" type="text/css" />
|
||||||
<link rel="stylesheet" href="widgets.css?v=2.2.2b" type="text/css" />
|
<link rel="stylesheet" href="widgets.css?v=2.2.2c" type="text/css" />
|
||||||
<link rel="stylesheet" href="icons.css?v=2.2.2b" type="text/css" />
|
<link rel="stylesheet" href="icons.css?v=2.2.2c" type="text/css" />
|
||||||
<link rel="icon" type="image/png" href="favicon.png" />
|
<link rel="icon" type="image/png" href="favicon.png" />
|
||||||
<script type="text/javascript" src="index.js?v=2.2.2b"></script>
|
<script type="text/javascript" src="index.js?v=2.2.2c"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="divContainer" class="container main" data-auth="false">
|
<div id="divContainer" class="container main" data-auth="false">
|
||||||
|
|
@ -353,6 +353,10 @@
|
||||||
<option value="5">Garage (1-button)</option>
|
<option value="5">Garage (1-button)</option>
|
||||||
<option value="6">Garage (3-button)</option>
|
<option value="6">Garage (3-button)</option>
|
||||||
<option value="9">Dry Contact</option>
|
<option value="9">Dry Contact</option>
|
||||||
|
<option value="10">Dry Contact (2-button)</option>
|
||||||
|
<option value="11">Gate (left)</option>
|
||||||
|
<option value="12">Gate (center)</option>
|
||||||
|
<option value="13">Gate (right)</option>
|
||||||
</select>
|
</select>
|
||||||
<label for="selShadeType">Type</label>
|
<label for="selShadeType">Type</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
325
data/index.js
325
data/index.js
|
|
@ -169,7 +169,7 @@ Number.prototype.fmt = function (format, empty) {
|
||||||
if (rd.length === 0 && rw.length === 0) return '';
|
if (rd.length === 0 && rw.length === 0) return '';
|
||||||
return pfx + rw + rd + sfx;
|
return pfx + rw + rd + sfx;
|
||||||
};
|
};
|
||||||
var baseUrl = window.location.protocol === 'file:' ? 'http://ESPSomfyRTS' : '';
|
var baseUrl = window.location.protocol === 'file:' ? 'http://192.168.1.152' : '';
|
||||||
//var baseUrl = '';
|
//var baseUrl = '';
|
||||||
function makeBool(val) {
|
function makeBool(val) {
|
||||||
if (typeof val === 'boolean') return val;
|
if (typeof val === 'boolean') return val;
|
||||||
|
|
@ -1252,7 +1252,7 @@ var security = new Security();
|
||||||
|
|
||||||
class General {
|
class General {
|
||||||
initialized = false;
|
initialized = false;
|
||||||
appVersion = 'v2.2.2b';
|
appVersion = 'v2.2.2c';
|
||||||
reloadApp = false;
|
reloadApp = false;
|
||||||
init() {
|
init() {
|
||||||
if (this.initialized) return;
|
if (this.initialized) return;
|
||||||
|
|
@ -1885,6 +1885,22 @@ var wifi = new Wifi();
|
||||||
class Somfy {
|
class Somfy {
|
||||||
initialized = false;
|
initialized = false;
|
||||||
frames = [];
|
frames = [];
|
||||||
|
shadeTypes = [
|
||||||
|
{ type: 0, name: 'Roller Shade', ico: 'icss-window-shade', lift: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 1, name: 'Blind', ico: 'icss-window-blind', lift: true, tilt: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 2, name: 'Drapery (left)', ico: 'icss-ldrapery', lift: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 3, name: 'Awning', ico: 'icss-awning', lift: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 4, name: 'Shutter', ico: 'icss-shutter', lift: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 5, name: 'Garage (1-button)', ico: 'icss-garage', lift: true, light: true, fpos: true },
|
||||||
|
{ type: 6, name: 'Garage (3-button)', ico: 'icss-garage', lift: true, light: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 7, name: 'Drapery (right)', ico: 'icss-rdrapery', lift: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 8, name: 'Drapery (center)', ico: 'icss-cdrapery', lift: true, sun: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 9, name: 'Dry Contact (1-button)', ico: 'icss-lightbulb', fpos: true },
|
||||||
|
{ type: 10, name: 'Dry Contact (2-button)', ico: 'icss-lightbulb', fcmd: true, fpos: true },
|
||||||
|
{ type: 11, name: 'Gate (left)', ico: 'icss-lgate', lift: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 12, name: 'Gate (center)', ico: 'icss-cgate', lift: true, fcmd: true, fpos: true },
|
||||||
|
{ type: 13, name: 'Gate (right)', ico: 'icss-rgate', lift: true, fcmd: true, fpos: true },
|
||||||
|
];
|
||||||
init() {
|
init() {
|
||||||
if (this.initialized) return;
|
if (this.initialized) return;
|
||||||
this.loadPins('inout', document.getElementById('selTransSCKPin'));
|
this.loadPins('inout', document.getElementById('selTransSCKPin'));
|
||||||
|
|
@ -2098,6 +2114,8 @@ class Somfy {
|
||||||
}
|
}
|
||||||
for (let i = 0; i < shades.length; i++) {
|
for (let i = 0; i < shades.length; i++) {
|
||||||
let shade = shades[i];
|
let shade = shades[i];
|
||||||
|
let st = this.shadeTypes.find(x => x.type === shade.shadeType) || { type: shade.shadeType, ico: 'icss-window-shade' };
|
||||||
|
|
||||||
divCfg += `<div class="somfyShade shade-draggable" draggable="true" data-mypos="${shade.myPos}" data-shadeid="${shade.shadeId}" data-remoteaddress="${shade.remoteAddress}" data-tilt="${shade.tiltType}" data-shadetype="${shade.shadeType}">`;
|
divCfg += `<div class="somfyShade shade-draggable" draggable="true" data-mypos="${shade.myPos}" data-shadeid="${shade.shadeId}" data-remoteaddress="${shade.remoteAddress}" data-tilt="${shade.tiltType}" data-shadetype="${shade.shadeType}">`;
|
||||||
divCfg += `<div class="button-outline" onclick="somfy.openEditShade(${shade.shadeId});"><i class="icss-edit"></i></div>`;
|
divCfg += `<div class="button-outline" onclick="somfy.openEditShade(${shade.shadeId});"><i class="icss-edit"></i></div>`;
|
||||||
//divCfg += `<i class="shade-icon" data-position="${shade.position || 0}%"></i>`;
|
//divCfg += `<i class="shade-icon" data-position="${shade.position || 0}%"></i>`;
|
||||||
|
|
@ -2112,38 +2130,10 @@ class Somfy {
|
||||||
divCtl += ` data-tiltposition="${shade.tiltPosition}" data-tiltdirection="${shade.tiltDirection}" data-tilttarget="${shade.tiltTarget}"`;
|
divCtl += ` data-tiltposition="${shade.tiltPosition}" data-tiltdirection="${shade.tiltDirection}" data-tilttarget="${shade.tiltTarget}"`;
|
||||||
}
|
}
|
||||||
divCtl += `><div class="shade-icon" data-shadeid="${shade.shadeId}" onclick="event.stopPropagation(); console.log(event); somfy.openSetPosition(${shade.shadeId});">`;
|
divCtl += `><div class="shade-icon" data-shadeid="${shade.shadeId}" onclick="event.stopPropagation(); console.log(event); somfy.openSetPosition(${shade.shadeId});">`;
|
||||||
divCtl += `<i class="somfy-shade-icon`;
|
divCtl += `<i class="somfy-shade-icon ${st.ico}`;
|
||||||
switch (shade.shadeType) {
|
//divCtl += `" data-shadeid="${shade.shadeId}" style="--shade-position:${shade.flipPosition ? 100 - shade.position : shade.position}%;vertical-align: top;"><span class="icss-panel-left"></span><span class="icss-panel-right"></span></i>`;
|
||||||
case 1:
|
divCtl += `" data-shadeid="${shade.shadeId}" style="--shade-position:${shade.position}%;vertical-align: top;"><span class="icss-panel-left"></span><span class="icss-panel-right"></span></i>`;
|
||||||
divCtl += ' icss-window-blind';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
divCtl += ' icss-ldrapery';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
divCtl += ' icss-awning';
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
divCtl += ' icss-shutter';
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
divCtl += ' icss-garage';
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
divCtl += ' icss-rdrapery';
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
divCtl += ' icss-cdrapery';
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
divCtl += ' icss-lightbulb';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
divCtl += ' icss-window-shade';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
divCtl += `" data-shadeid="${shade.shadeId}" style="--shade-position:${shade.flipPosition ? 100 - shade.position : shade.position}%;vertical-align: top;"><span class="icss-panel-left"></span><span class="icss-panel-right"></span></i>`;
|
|
||||||
divCtl += shade.tiltType !== 0 ? `<i class="icss-window-tilt" data-shadeid="${shade.shadeId}" data-tiltposition="${shade.tiltPosition}"></i></div>` : '</div>';
|
divCtl += shade.tiltType !== 0 ? `<i class="icss-window-tilt" data-shadeid="${shade.shadeId}" data-tiltposition="${shade.tiltPosition}"></i></div>` : '</div>';
|
||||||
divCtl += `<div class="indicator indicator-wind"><i class="icss-warning"></i></div><div class="indicator indicator-sun"><i class="icss-sun"></i></div>`;
|
divCtl += `<div class="indicator indicator-wind"><i class="icss-warning"></i></div><div class="indicator indicator-sun"><i class="icss-sun"></i></div>`;
|
||||||
divCtl += `<div class="shade-name">`;
|
divCtl += `<div class="shade-name">`;
|
||||||
|
|
@ -2667,7 +2657,9 @@ class Somfy {
|
||||||
console.log(state);
|
console.log(state);
|
||||||
let icons = document.querySelectorAll(`.somfy-shade-icon[data-shadeid="${state.shadeId}"]`);
|
let icons = document.querySelectorAll(`.somfy-shade-icon[data-shadeid="${state.shadeId}"]`);
|
||||||
for (let i = 0; i < icons.length; i++) {
|
for (let i = 0; i < icons.length; i++) {
|
||||||
icons[i].style.setProperty('--shade-position', `${state.flipPosition ? 100 - state.position : state.position}%`);
|
//icons[i].style.setProperty('--shade-position', `${state.flipPosition ? 100 - state.position : state.position}%`);
|
||||||
|
icons[i].style.setProperty('--shade-position', `${state.position}%`);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (state.tiltType !== 0) {
|
if (state.tiltType !== 0) {
|
||||||
let tilts = document.querySelectorAll(`.icss-window-tilt[data-shadeid="${state.shadeId}"]`);
|
let tilts = document.querySelectorAll(`.icss-window-tilt[data-shadeid="${state.shadeId}"]`);
|
||||||
|
|
@ -2792,153 +2784,35 @@ class Somfy {
|
||||||
onShadeTypeChanged(el) {
|
onShadeTypeChanged(el) {
|
||||||
let sel = document.getElementById('selShadeType');
|
let sel = document.getElementById('selShadeType');
|
||||||
let tilt = parseInt(document.getElementById('selTiltType').value, 10);
|
let tilt = parseInt(document.getElementById('selTiltType').value, 10);
|
||||||
let sun = true;
|
|
||||||
let light = false;
|
|
||||||
let lift = true;
|
|
||||||
let flipCommands = true;
|
|
||||||
let flipPosition = true;
|
|
||||||
let ico = document.getElementById('icoShade');
|
let ico = document.getElementById('icoShade');
|
||||||
let type = parseInt(sel.value, 10);
|
let type = parseInt(sel.value, 10);
|
||||||
document.getElementById('somfyShade').setAttribute('data-shadetype', type);
|
document.getElementById('somfyShade').setAttribute('data-shadetype', type);
|
||||||
document.getElementById('divSomfyButtons').setAttribute('data-shadetype', type);
|
document.getElementById('divSomfyButtons').setAttribute('data-shadetype', type);
|
||||||
switch (type) {
|
|
||||||
case 1:
|
let st = this.shadeTypes.find(x => x.type === type) || { type: type };
|
||||||
document.getElementById('divTiltSettings').style.display = '';
|
for (let i = 0; i < this.shadeTypes.length; i++) {
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
let t = this.shadeTypes[i];
|
||||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
if (t.type !== type) {
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
if (ico.classList.contains(t.ico) && t.ico !== st.ico) ico.classList.remove(t.ico);
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
}
|
||||||
if (ico.classList.contains('icss-awning')) ico.classList.remove('icss-awning');
|
else {
|
||||||
if (ico.classList.contains('icss-shutter')) ico.classList.remove('icss-shutter');
|
if (!ico.classList.contains(st.ico)) ico.classList.add(st.ico);
|
||||||
if (!ico.classList.contains('icss-window-blind')) ico.classList.add('icss-window-blind');
|
document.getElementById('divTiltSettings').style.display = st.tilt !== false ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-garage')) ico.classList.remove('icss-garage');
|
let lift = st.lift || false;
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
if (lift && tilt == 3) lift = false;
|
||||||
break;
|
if (!st.tilt) tilt = 0;
|
||||||
case 2:
|
document.getElementById('fldTiltTime').parentElement.style.display = tilt ? 'inline-block' : 'none';
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
document.getElementById('divLiftSettings').style.display = lift ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
document.getElementById('divTiltSettings').style.display = st.tilt ? '' : 'none';
|
||||||
if (!ico.classList.contains('icss-ldrapery')) ico.classList.add('icss-ldrapery');
|
document.querySelector('#divSomfyButtons i.icss-window-tilt').style.display = tilt ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
document.getElementById('divSunSensor').style.display = st.sun ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
document.getElementById('divLightSwitch').style.display = st.light ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-window-blind')) ico.classList.remove('icss-window-blind');
|
document.getElementById('divFlipPosition').style.display = st.fpos ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-shutter')) ico.classList.remove('icss-shutter');
|
document.getElementById('divFlipCommands').style.display = st.fcmd ? '' : 'none';
|
||||||
if (ico.classList.contains('icss-garage')) ico.classList.remove('icss-garage');
|
if (!st.light) document.getElementById('cbHasLight').checked = false;
|
||||||
if (ico.classList.contains('icss-awning')) ico.classList.remove('icss-awning');
|
if (!st.sun) document.getElementById('cbHasSunsensor').checked = false;
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
}
|
||||||
tilt = false;
|
|
||||||
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-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
|
||||||
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');
|
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
|
||||||
tilt = false;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
|
||||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
|
||||||
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');
|
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
|
||||||
tilt = false;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
flipCommands = false;
|
|
||||||
case 6:
|
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
|
||||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
|
||||||
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');
|
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
|
||||||
light = true;
|
|
||||||
sun = false;
|
|
||||||
tilt = false;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
|
||||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (!ico.classList.contains('icss-rdrapery')) ico.classList.add('icss-rdrapery');
|
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
|
||||||
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.remove('icss-awning');
|
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
|
||||||
tilt = false;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
|
||||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
|
||||||
if (!ico.classList.contains('icss-cdrapery')) ico.classList.add('icss-cdrapery');
|
|
||||||
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.remove('icss-awning');
|
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
|
||||||
tilt = false;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
|
||||||
if (ico.classList.contains('icss-window-shade')) ico.classList.remove('icss-window-shade');
|
|
||||||
if (ico.classList.contains('icss-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
|
||||||
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.remove('icss-awning');
|
|
||||||
if (!ico.classList.contains('icss-lightbulb')) ico.classList.add('icss-lightbulb');
|
|
||||||
lift = false;
|
|
||||||
tilt = false;
|
|
||||||
light = false;
|
|
||||||
sun = false;
|
|
||||||
flipPosition = false;
|
|
||||||
flipCommands = 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-ldrapery')) ico.classList.remove('icss-ldrapery');
|
|
||||||
if (ico.classList.contains('icss-rdrapery')) ico.classList.remove('icss-rdrapery');
|
|
||||||
if (ico.classList.contains('icss-cdrapery')) ico.classList.remove('icss-cdrapery');
|
|
||||||
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');
|
|
||||||
if (ico.classList.contains('icss-lightbulb')) ico.classList.remove('icss-lightbulb');
|
|
||||||
document.getElementById('divTiltSettings').style.display = 'none';
|
|
||||||
tilt = false;
|
|
||||||
light = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
document.getElementById('fldTiltTime').parentElement.style.display = tilt ? 'inline-block' : 'none';
|
|
||||||
if (lift && tilt == 3) lift = false;
|
|
||||||
document.getElementById('divLiftSettings').style.display = lift ? '' : 'none';
|
|
||||||
document.querySelector('#divSomfyButtons i.icss-window-tilt').style.display = tilt ? '' : 'none';
|
|
||||||
document.getElementById('divSunSensor').style.display = sun ? '' : 'none';
|
|
||||||
document.getElementById('divLightSwitch').style.display = light ? '' : 'none';
|
|
||||||
document.getElementById('divFlipPosition').style.display = flipPosition ? '' : 'none';
|
|
||||||
document.getElementById('divFlipCommands').style.display = flipCommands ? '' : 'none';
|
|
||||||
if (!light) document.getElementById('cbHasLight').checked = false;
|
|
||||||
if (!sun) document.getElementById('cbHasSunsensor').checked = false;
|
|
||||||
}
|
}
|
||||||
onShadeBitLengthChanged(el) {
|
onShadeBitLengthChanged(el) {
|
||||||
document.getElementById('somfyShade').setAttribute('data-bitlength', el.value);
|
document.getElementById('somfyShade').setAttribute('data-bitlength', el.value);
|
||||||
|
|
@ -2997,54 +2871,15 @@ class Somfy {
|
||||||
document.getElementById('btnLinkRemote').style.display = '';
|
document.getElementById('btnLinkRemote').style.display = '';
|
||||||
this.onShadeTypeChanged(document.getElementById('selShadeType'));
|
this.onShadeTypeChanged(document.getElementById('selShadeType'));
|
||||||
let ico = document.getElementById('icoShade');
|
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');
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ico.classList.remove('icss-window-shade');
|
|
||||||
ico.classList.add('icss-ldrapery');
|
|
||||||
document.getElementById('divSunSensor').style.display = '';
|
|
||||||
break;
|
|
||||||
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:
|
|
||||||
case 6:
|
|
||||||
ico.classList.remove('icss-window-shade');
|
|
||||||
ico.classList.add('icss-garage');
|
|
||||||
document.getElementById('divSunSensor').style.display = 'none';
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
ico.classList.remove('icss-window-shade');
|
|
||||||
ico.classList.add('icss-rdrapery');
|
|
||||||
document.getElementById('divSunSensor').style.display = '';
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
ico.classList.remove('icss-window-shade');
|
|
||||||
ico.classList.add('icss-cdrapery');
|
|
||||||
document.getElementById('divSunSensor').style.display = '';
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
let tilt = ico.parentElement.querySelector('i.icss-window-tilt');
|
let tilt = ico.parentElement.querySelector('i.icss-window-tilt');
|
||||||
tilt.style.display = shade.tiltType !== 0 ? '' : 'none';
|
tilt.style.display = shade.tiltType !== 0 ? '' : 'none';
|
||||||
tilt.setAttribute('data-tiltposition', shade.tiltPosition);
|
tilt.setAttribute('data-tiltposition', shade.tiltPosition);
|
||||||
tilt.setAttribute('data-shadeid', shade.shadeId);
|
tilt.setAttribute('data-shadeid', shade.shadeId);
|
||||||
ico.style.setProperty('--shade-position', `${shade.flipPosition ? 100 - shade.position : shade.position}%`);
|
//ico.style.setProperty('--shade-position', `${shade.flipPosition ? 100 - shade.position : shade.position}%`);
|
||||||
ico.style.setProperty('--tilt-position', `${shade.flipPosition ? 100 - shade.tiltPosition : shade.tiltPosition}%`);
|
//ico.style.setProperty('--tilt-position', `${shade.flipPosition ? 100 - shade.tiltPosition : shade.tiltPosition}%`);
|
||||||
|
ico.style.setProperty('--shade-position', `${shade.position}%`);
|
||||||
|
ico.style.setProperty('--tilt-position', `${shade.tiltPosition}%`);
|
||||||
|
|
||||||
ico.setAttribute('data-shadeid', shade.shadeId);
|
ico.setAttribute('data-shadeid', shade.shadeId);
|
||||||
somfy.onShadeBitLengthChanged(document.getElementById('selShadeBitLength'));
|
somfy.onShadeBitLengthChanged(document.getElementById('selShadeBitLength'));
|
||||||
somfy.onShadeProtoChanged(document.getElementById('selShadeProto'));
|
somfy.onShadeProtoChanged(document.getElementById('selShadeProto'));
|
||||||
|
|
@ -3147,6 +2982,7 @@ class Somfy {
|
||||||
if (obj.proto === 8 || obj.proto === 9) {
|
if (obj.proto === 8 || obj.proto === 9) {
|
||||||
switch (obj.shadeType) {
|
switch (obj.shadeType) {
|
||||||
case 5: // Garage 1-button
|
case 5: // Garage 1-button
|
||||||
|
case 10: // Two button dry contact
|
||||||
if (obj.proto !== 9 && obj.gpioUp === obj.gpioDown) {
|
if (obj.proto !== 9 && obj.gpioUp === obj.gpioDown) {
|
||||||
ui.errorMessage(document.getElementById('divSomfySettings'), 'For GPIO controlled motors the up and down GPIO selections must be unique.');
|
ui.errorMessage(document.getElementById('divSomfySettings'), 'For GPIO controlled motors the up and down GPIO selections must be unique.');
|
||||||
valid = false;
|
valid = false;
|
||||||
|
|
@ -3702,23 +3538,40 @@ class Somfy {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
let btnPairToGroup = div.querySelector('#btnPairToGroup');
|
let btnPairToGroup = div.querySelector('#btnPairToGroup');
|
||||||
btnPairToGroup.addEventListener('click', (evt) => {
|
let fnRepeatProgCommand = (err, o) => {
|
||||||
|
console.log(o);
|
||||||
|
if (this.btnTimer) {
|
||||||
|
clearTimeout(this.btnTimer);
|
||||||
|
this.btnTimer = null;
|
||||||
|
}
|
||||||
|
if (err) return;
|
||||||
|
if (mouseDown) {
|
||||||
|
if (o.cmd === 'Sensor')
|
||||||
|
somfy.sendSetSensor(o);
|
||||||
|
else if (typeof o.groupId !== 'undefined')
|
||||||
|
somfy.sendGroupRepeat(o.groupId, 'prog', null, fnRepeatProgCommand);
|
||||||
|
else
|
||||||
|
somfy.sendCommandRepeat(o.shadeId, 'prog', null, fnRepeatProgCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btnPairToGroup.addEventListener('mousedown', (evt) => {
|
||||||
|
mouseDown = true;
|
||||||
|
somfy.sendGroupCommand(groupId, 'prog', null, fnRepeatProgCommand);
|
||||||
|
});
|
||||||
|
btnPairToGroup.addEventListener('mouseup', (evt) => {
|
||||||
|
mouseDown = false;
|
||||||
let obj = ui.fromElement(div);
|
let obj = ui.fromElement(div);
|
||||||
putJSONSync('/groupCommand', { groupId: groupId, command: 'prog', repeat: 1 }, (err, shade) => {
|
let prompt = ui.promptMessage('Confirm Motor Response', () => {
|
||||||
if (err) ui.serviceError(err);
|
putJSONSync('/linkToGroup', { groupId: groupId, shadeId: obj.shadeId }, (err, group) => {
|
||||||
else {
|
console.log(group);
|
||||||
let prompt = ui.promptMessage('Confirm Motor Response', () => {
|
somfy.setLinkedShadesList(group);
|
||||||
putJSONSync('/linkToGroup', { groupId: groupId, shadeId: obj.shadeId }, (err, group) => {
|
this.updateGroupList();
|
||||||
console.log(group);
|
});
|
||||||
somfy.setLinkedShadesList(group);
|
prompt.remove();
|
||||||
this.updateGroupList();
|
div.remove();
|
||||||
});
|
|
||||||
prompt.remove();
|
|
||||||
div.remove();
|
|
||||||
});
|
|
||||||
prompt.querySelector('.sub-message').innerHTML = `<hr></hr><p>Did the shade jog? If the shade jogged press the YES button and your shade will be linked to the group. If it did not press the NO button and try again.</p></p><p>Once the shade has jogged the shade will be added to the group and this process will be finished.</p>`;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
prompt.querySelector('.sub-message').innerHTML = `<hr></hr><p>Did the shade jog? If the shade jogged press the YES button and your shade will be linked to the group. If it did not press the NO button and try again.</p></p><p>Once the shade has jogged the shade will be added to the group and this process will be finished.</p>`;
|
||||||
|
|
||||||
});
|
});
|
||||||
getJSONSync(`/groupOptions?groupId=${groupId}`, (err, options) => {
|
getJSONSync(`/groupOptions?groupId=${groupId}`, (err, options) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
||||||
|
|
@ -142,9 +142,25 @@
|
||||||
.shadectl-buttons[data-shadetype="9"] > .button-outline[data-cmd="down"],
|
.shadectl-buttons[data-shadetype="9"] > .button-outline[data-cmd="down"],
|
||||||
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="my"],
|
.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="up"],
|
||||||
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="down"] {
|
.shadectl-buttons[data-shadetype="5"] > .button-outline[data-cmd="down"],
|
||||||
|
.shadectl-buttons[data-shadetype="10"] > .button-outline[data-cmd="my"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadectl-buttons[data-shadetype="10"] > .button-outline[data-cmd="up"],
|
||||||
|
.shadectl-buttons[data-shadetype="10"] > .button-outline[data-cmd="down"] {
|
||||||
|
width: 3em;
|
||||||
|
border-radius: 30%;
|
||||||
|
text-align: center;
|
||||||
|
height:2.4em;
|
||||||
|
}
|
||||||
|
.shadectl-buttons[data-shadetype="10"] > .button-outline[data-cmd="up"] i,
|
||||||
|
.shadectl-buttons[data-shadetype="10"] > .button-outline[data-cmd="down"] i {
|
||||||
|
top:.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.shadectl-buttons:not([data-shadetype="5"]):not([data-shadetype="9"]) > .button-outline[data-cmd="toggle"] {
|
.shadectl-buttons:not([data-shadetype="5"]):not([data-shadetype="9"]) > .button-outline[data-cmd="toggle"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
@ -157,9 +173,11 @@
|
||||||
.somfyShadeCtl:not([data-shadetype="1"][data-tilt="3"]) .shadectl-mypos label.my-pos:after {
|
.somfyShadeCtl:not([data-shadetype="1"][data-tilt="3"]) .shadectl-mypos label.my-pos:after {
|
||||||
content: "My:"
|
content: "My:"
|
||||||
}
|
}
|
||||||
.somfyShadeCtl[data-shadetype="1"][data-tilt="3"] .shadectl-mypos label.my-pos {
|
.somfyShadeCtl[data-shadetype="1"][data-tilt="3"] .shadectl-mypos label.my-pos,
|
||||||
display:none;
|
.somfyShadeCtl[data-shadetype="10"] .shadectl-mypos {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.somfyShadeCtl[data-shadetype="1"][data-tilt="3"] .shadectl-mypos label.my-pos-tilt:after {
|
.somfyShadeCtl[data-shadetype="1"][data-tilt="3"] .shadectl-mypos label.my-pos-tilt:after {
|
||||||
content:"My Tilt:";
|
content:"My Tilt:";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue