mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2025-12-13 11:02:12 +01:00
parent
bbebc22bb9
commit
87995bf707
9 changed files with 174 additions and 29 deletions
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
extern Preferences pref;
|
extern Preferences pref;
|
||||||
|
|
||||||
#define SHADE_HDR_VER 15
|
#define SHADE_HDR_VER 16
|
||||||
#define SHADE_HDR_SIZE 56
|
#define SHADE_HDR_SIZE 56
|
||||||
#define SHADE_REC_SIZE 264
|
#define SHADE_REC_SIZE 268
|
||||||
#define GROUP_REC_SIZE 184
|
#define GROUP_REC_SIZE 184
|
||||||
#define TRANS_REC_SIZE 74
|
#define TRANS_REC_SIZE 74
|
||||||
|
|
||||||
|
|
@ -661,16 +661,21 @@ bool ShadeConfigFile::readShadeRecord(SomfyShade *shade) {
|
||||||
shade->gpioUp = this->readUInt8(shade->gpioUp);
|
shade->gpioUp = this->readUInt8(shade->gpioUp);
|
||||||
shade->gpioDown = this->readUInt8(shade->gpioDown);
|
shade->gpioDown = this->readUInt8(shade->gpioDown);
|
||||||
}
|
}
|
||||||
|
if(this->header.version > 15) {
|
||||||
|
shade->gpioMy = this->readUInt8(shade->gpioMy);
|
||||||
|
}
|
||||||
|
|
||||||
if(shade->getShadeId() == 255) shade->clear();
|
if(shade->getShadeId() == 255) shade->clear();
|
||||||
else if(shade->tiltType == tilt_types::tiltonly) {
|
else if(shade->tiltType == tilt_types::tiltonly) {
|
||||||
shade->myPos = shade->currentPos = shade->target = 100.0f;
|
shade->myPos = shade->currentPos = shade->target = 100.0f;
|
||||||
}
|
}
|
||||||
pref.end();
|
pref.end();
|
||||||
if(shade->proto == radio_proto::GPIO) {
|
if(shade->proto == radio_proto::GP_Relay || shade->proto == radio_proto::GP_Remote) {
|
||||||
pinMode(shade->gpioUp, OUTPUT);
|
pinMode(shade->gpioUp, OUTPUT);
|
||||||
pinMode(shade->gpioDown, OUTPUT);
|
pinMode(shade->gpioDown, OUTPUT);
|
||||||
}
|
}
|
||||||
|
if(shade->proto == radio_proto::GP_Remote)
|
||||||
|
pinMode(shade->gpioMy, OUTPUT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ShadeConfigFile::loadFile(SomfyShadeController *s, const char *filename) {
|
bool ShadeConfigFile::loadFile(SomfyShadeController *s, const char *filename) {
|
||||||
|
|
@ -769,7 +774,8 @@ bool ShadeConfigFile::writeShadeRecord(SomfyShade *shade) {
|
||||||
this->writeUInt8(shade->repeats);
|
this->writeUInt8(shade->repeats);
|
||||||
this->writeUInt8(shade->sortOrder);
|
this->writeUInt8(shade->sortOrder);
|
||||||
this->writeUInt8(shade->gpioUp);
|
this->writeUInt8(shade->gpioUp);
|
||||||
this->writeUInt8(shade->gpioDown, CFG_REC_END);
|
this->writeUInt8(shade->gpioDown);
|
||||||
|
this->writeUInt8(shade->gpioMy, CFG_REC_END);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ShadeConfigFile::writeSettingsRecord() {
|
bool ShadeConfigFile::writeSettingsRecord() {
|
||||||
|
|
|
||||||
5
MQTT.cpp
5
MQTT.cpp
|
|
@ -4,6 +4,7 @@
|
||||||
#include "MQTT.h"
|
#include "MQTT.h"
|
||||||
#include "ConfigSettings.h"
|
#include "ConfigSettings.h"
|
||||||
#include "Somfy.h"
|
#include "Somfy.h"
|
||||||
|
#include "Network.h"
|
||||||
|
|
||||||
WiFiClient tcpClient;
|
WiFiClient tcpClient;
|
||||||
PubSubClient mqttClient(tcpClient);
|
PubSubClient mqttClient(tcpClient);
|
||||||
|
|
@ -13,6 +14,9 @@ static char g_content[MQTT_MAX_RESPONSE];
|
||||||
|
|
||||||
extern ConfigSettings settings;
|
extern ConfigSettings settings;
|
||||||
extern SomfyShadeController somfy;
|
extern SomfyShadeController somfy;
|
||||||
|
extern Network net;
|
||||||
|
|
||||||
|
|
||||||
bool MQTTClass::begin() {
|
bool MQTTClass::begin() {
|
||||||
this->suspended = false;
|
this->suspended = false;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -197,6 +201,7 @@ bool MQTTClass::connect() {
|
||||||
this->publish("host", settings.hostname, true);
|
this->publish("host", settings.hostname, true);
|
||||||
this->publish("firmware", settings.fwVersion, true);
|
this->publish("firmware", settings.fwVersion, true);
|
||||||
this->publish("serverId", settings.serverId, true);
|
this->publish("serverId", settings.serverId, true);
|
||||||
|
this->publish("mac", net.mac.c_str());
|
||||||
somfy.publish();
|
somfy.publish();
|
||||||
this->subscribe("shades/+/target/set");
|
this->subscribe("shades/+/target/set");
|
||||||
this->subscribe("shades/+/tiltTarget/set");
|
this->subscribe("shades/+/tiltTarget/set");
|
||||||
|
|
|
||||||
117
Somfy.cpp
117
Somfy.cpp
|
|
@ -801,7 +801,7 @@ bool SomfyShade::isInGroup() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void SomfyShade::setGPIOs() {
|
void SomfyShade::setGPIOs() {
|
||||||
if(this->proto == radio_proto::GPIO) {
|
if(this->proto == radio_proto::GP_Relay) {
|
||||||
// Determine whether the direction needs to be set.
|
// Determine whether the direction needs to be set.
|
||||||
int8_t dir = this->direction;
|
int8_t dir = this->direction;
|
||||||
if(dir == 0 && this->tiltType == tilt_types::integrated)
|
if(dir == 0 && this->tiltType == tilt_types::integrated)
|
||||||
|
|
@ -825,6 +825,63 @@ void SomfyShade::setGPIOs() {
|
||||||
}
|
}
|
||||||
this->gpioDir = dir;
|
this->gpioDir = dir;
|
||||||
}
|
}
|
||||||
|
else if(this->proto == radio_proto::GP_Remote) {
|
||||||
|
if(millis() > this->gpioRelease) {
|
||||||
|
digitalWrite(this->gpioUp, LOW);
|
||||||
|
digitalWrite(this->gpioDown, LOW);
|
||||||
|
digitalWrite(this->gpioMy, LOW);
|
||||||
|
this->gpioRelease = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SomfyRemote::triggerGPIOs(somfy_frame_t &frame) {
|
||||||
|
if(this->proto == radio_proto::GP_Remote) {
|
||||||
|
int8_t dir = 0;
|
||||||
|
switch(frame.cmd) {
|
||||||
|
case somfy_commands::My:
|
||||||
|
digitalWrite(this->gpioUp, LOW);
|
||||||
|
digitalWrite(this->gpioDown, LOW);
|
||||||
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
|
dir = 0;
|
||||||
|
if(dir != this->gpioDir) Serial.printf("UP: false, DOWN: false, MY: true\n");
|
||||||
|
break;
|
||||||
|
case somfy_commands::Up:
|
||||||
|
digitalWrite(this->gpioMy, LOW);
|
||||||
|
digitalWrite(this->gpioDown, LOW);
|
||||||
|
digitalWrite(this->gpioUp, HIGH);
|
||||||
|
dir = -1;
|
||||||
|
Serial.printf("UP: true, DOWN: false, MY: false\n");
|
||||||
|
break;
|
||||||
|
case somfy_commands::Toggle:
|
||||||
|
case somfy_commands::Down:
|
||||||
|
digitalWrite(this->gpioMy, LOW);
|
||||||
|
digitalWrite(this->gpioUp, LOW);
|
||||||
|
digitalWrite(this->gpioDown, HIGH);
|
||||||
|
dir = 1;
|
||||||
|
Serial.printf("UP: false, DOWN: true, MY: false\n");
|
||||||
|
break;
|
||||||
|
case somfy_commands::MyUp:
|
||||||
|
digitalWrite(this->gpioDown, LOW);
|
||||||
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
|
digitalWrite(this->gpioUp, HIGH);
|
||||||
|
Serial.printf("UP: true, DOWN: false, MY: true\n");
|
||||||
|
break;
|
||||||
|
case somfy_commands::MyDown:
|
||||||
|
digitalWrite(this->gpioUp, LOW);
|
||||||
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
|
digitalWrite(this->gpioDown, HIGH);
|
||||||
|
Serial.printf("UP: true, DOWN: false, MY: true\n");
|
||||||
|
break;
|
||||||
|
case somfy_commands::MyUpDown:
|
||||||
|
digitalWrite(this->gpioUp, HIGH);
|
||||||
|
digitalWrite(this->gpioMy, HIGH);
|
||||||
|
digitalWrite(this->gpioDown, HIGH);
|
||||||
|
Serial.printf("UP: true, DOWN: true, MY: true\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->gpioRelease = millis() + (frame.repeats * 200);
|
||||||
|
this->gpioDir = dir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void SomfyShade::checkMovement() {
|
void SomfyShade::checkMovement() {
|
||||||
const uint64_t curTime = millis();
|
const uint64_t curTime = millis();
|
||||||
|
|
@ -2439,11 +2496,12 @@ int8_t SomfyShade::validateJSON(JsonObject &obj) {
|
||||||
int8_t ret = 0;
|
int8_t ret = 0;
|
||||||
if(obj.containsKey("proto")) {
|
if(obj.containsKey("proto")) {
|
||||||
radio_proto proto = this->proto;
|
radio_proto proto = this->proto;
|
||||||
if(proto == radio_proto::GPIO) {
|
if(proto == radio_proto::GP_Relay || proto == radio_proto::GP_Remote) {
|
||||||
// Check to see if we are using the up and or down
|
// Check to see if we are using the up and or down
|
||||||
// GPIOs anywhere else.
|
// GPIOs anywhere else.
|
||||||
uint8_t upPin = obj.containsKey("gpioUp") ? obj["gpioUp"].as<uint8_t>() : this->gpioUp;
|
uint8_t upPin = obj.containsKey("gpioUp") ? obj["gpioUp"].as<uint8_t>() : this->gpioUp;
|
||||||
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;
|
||||||
if(somfy.transceiver.config.enabled) {
|
if(somfy.transceiver.config.enabled) {
|
||||||
if(somfy.transceiver.config.SCKPin == upPin || somfy.transceiver.config.SCKPin == downPin ||
|
if(somfy.transceiver.config.SCKPin == upPin || somfy.transceiver.config.SCKPin == downPin ||
|
||||||
somfy.transceiver.config.TXPin == upPin || somfy.transceiver.config.TXPin == downPin ||
|
somfy.transceiver.config.TXPin == upPin || somfy.transceiver.config.TXPin == downPin ||
|
||||||
|
|
@ -2452,27 +2510,55 @@ int8_t SomfyShade::validateJSON(JsonObject &obj) {
|
||||||
somfy.transceiver.config.MISOPin == upPin || somfy.transceiver.config.MISOPin == downPin ||
|
somfy.transceiver.config.MISOPin == upPin || somfy.transceiver.config.MISOPin == downPin ||
|
||||||
somfy.transceiver.config.CSNPin == upPin || somfy.transceiver.config.CSNPin == downPin)
|
somfy.transceiver.config.CSNPin == upPin || somfy.transceiver.config.CSNPin == downPin)
|
||||||
ret = -10; // Pin in use with transceiver.
|
ret = -10; // Pin in use with transceiver.
|
||||||
|
else if(proto == radio_proto::GP_Remote) {
|
||||||
|
if(somfy.transceiver.config.SCKPin == myPin ||
|
||||||
|
somfy.transceiver.config.TXPin == myPin ||
|
||||||
|
somfy.transceiver.config.RXPin == myPin ||
|
||||||
|
somfy.transceiver.config.MOSIPin == myPin ||
|
||||||
|
somfy.transceiver.config.MISOPin == myPin ||
|
||||||
|
somfy.transceiver.config.CSNPin == myPin)
|
||||||
|
ret = -10; // Pin in use with transceiver.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(settings.connType == conn_types::ethernet || settings.connType == conn_types::ethernetpref) {
|
if(settings.connType == conn_types::ethernet || settings.connType == conn_types::ethernetpref) {
|
||||||
if((settings.Ethernet.CLKMode == 0 || settings.Ethernet.CLKMode == 1) && (upPin == 0 || downPin == 0))
|
if((settings.Ethernet.CLKMode == 0 || settings.Ethernet.CLKMode == 1) && (upPin == 0 || downPin == 0))
|
||||||
ret = -11; // Pin in use with ethernet.
|
ret = -11; // Pin in use with ethernet.
|
||||||
|
else if(proto == radio_proto::GP_Remote && ((settings.Ethernet.CLKMode == 0 || settings.Ethernet.CLKMode == 1) && myPin == 0))
|
||||||
|
ret = -11; // Pin in use with ethernet.
|
||||||
else if((settings.Ethernet.CLKMode == 2 && (upPin == 16 || downPin == 16)) ||
|
else if((settings.Ethernet.CLKMode == 2 && (upPin == 16 || downPin == 16)) ||
|
||||||
(settings.Ethernet.CLKMode == 3 && (upPin == 17 || downPin == 17)))
|
(settings.Ethernet.CLKMode == 3 && (upPin == 17 || downPin == 17)))
|
||||||
ret = -11;
|
ret = -11;
|
||||||
|
else if(proto == radio_proto::GP_Remote && (settings.Ethernet.CLKMode == 2 && myPin == 16 || settings.Ethernet.CLKMode == 3 && myPin == 17))
|
||||||
|
ret = -11;
|
||||||
else if(settings.Ethernet.PWRPin == upPin || settings.Ethernet.PWRPin == downPin ||
|
else if(settings.Ethernet.PWRPin == upPin || settings.Ethernet.PWRPin == downPin ||
|
||||||
settings.Ethernet.MDCPin == upPin || settings.Ethernet.MDCPin == downPin ||
|
settings.Ethernet.MDCPin == upPin || settings.Ethernet.MDCPin == downPin ||
|
||||||
settings.Ethernet.MDIOPin == upPin || settings.Ethernet.MDIOPin == downPin)
|
settings.Ethernet.MDIOPin == upPin || settings.Ethernet.MDIOPin == downPin)
|
||||||
ret = -11;
|
ret = -11;
|
||||||
|
else if(proto == radio_proto::GP_Remote && (settings.Ethernet.PWRPin == myPin ||
|
||||||
|
settings.Ethernet.MDCPin == myPin || settings.Ethernet.MDIOPin == myPin))
|
||||||
|
ret = -11;
|
||||||
}
|
}
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
|
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
|
||||||
SomfyShade *shade = &somfy.shades[i];
|
SomfyShade *shade = &somfy.shades[i];
|
||||||
if(shade->getShadeId() == this->getShadeId() || shade->getShadeId() == 255) continue;
|
if(shade->getShadeId() == this->getShadeId() || shade->getShadeId() == 255) continue;
|
||||||
if(shade->proto == radio_proto::GPIO) {
|
if(shade->proto == radio_proto::GP_Relay || shade->proto == radio_proto::GP_Remote) {
|
||||||
if(shade->gpioUp == upPin || shade->gpioDown == upPin || shade->gpioDown == upPin || shade->gpioDown == downPin) {
|
if(shade->gpioUp == upPin || shade->gpioDown == upPin || shade->gpioDown == upPin || shade->gpioDown == downPin) {
|
||||||
ret = -12;
|
ret = -12;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if(proto == radio_proto::GP_Remote && (shade->gpioUp == myPin || shade->gpioDown == myPin)) {
|
||||||
|
ret = -12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(shade->proto == radio_proto::GP_Remote && (shade->gpioMy == upPin || shade->gpioMy == downPin)) {
|
||||||
|
ret = -12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(shade->proto == radio_proto::GP_Remote && proto == radio_proto::GP_Remote && (shade->gpioMy == myPin)) {
|
||||||
|
ret = -12;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2550,12 +2636,16 @@ int8_t SomfyShade::fromJSON(JsonObject &obj) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(obj.containsKey("flags")) this->flags = obj["flags"];
|
if(obj.containsKey("flags")) this->flags = obj["flags"];
|
||||||
if(this->proto == radio_proto::GPIO) {
|
if(this->proto == radio_proto::GP_Remote || this->proto == radio_proto::GP_Relay) {
|
||||||
if(obj.containsKey("gpioUp")) this->gpioUp = obj["gpioUp"];
|
if(obj.containsKey("gpioUp")) this->gpioUp = obj["gpioUp"];
|
||||||
if(obj.containsKey("gpioDown")) this->gpioDown = obj["gpioDown"];
|
if(obj.containsKey("gpioDown")) this->gpioDown = obj["gpioDown"];
|
||||||
pinMode(this->gpioUp, OUTPUT);
|
pinMode(this->gpioUp, OUTPUT);
|
||||||
pinMode(this->gpioDown, OUTPUT);
|
pinMode(this->gpioDown, OUTPUT);
|
||||||
}
|
}
|
||||||
|
if(this->proto == radio_proto::GP_Remote) {
|
||||||
|
if(obj.containsKey("gpioMy")) this->gpioMy = obj["gpioMy"];
|
||||||
|
pinMode(this->gpioMy, OUTPUT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
@ -2612,6 +2702,7 @@ bool SomfyShade::toJSON(JsonObject &obj) {
|
||||||
obj["sortOrder"] = this->sortOrder;
|
obj["sortOrder"] = this->sortOrder;
|
||||||
obj["gpioUp"] = this->gpioUp;
|
obj["gpioUp"] = this->gpioUp;
|
||||||
obj["gpioDown"] = this->gpioDown;
|
obj["gpioDown"] = this->gpioDown;
|
||||||
|
obj["gpioMy"] = this->gpioMy;
|
||||||
SomfyRemote::toJSON(obj);
|
SomfyRemote::toJSON(obj);
|
||||||
JsonArray arr = obj.createNestedArray("linkedRemotes");
|
JsonArray arr = obj.createNestedArray("linkedRemotes");
|
||||||
for(uint8_t i = 0; i < SOMFY_MAX_LINKED_REMOTES; i++) {
|
for(uint8_t i = 0; i < SOMFY_MAX_LINKED_REMOTES; i++) {
|
||||||
|
|
@ -2958,7 +3049,7 @@ void SomfyRemote::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
||||||
// We have to set the processed to clear this if we are sending
|
// We have to set the processed to clear this if we are sending
|
||||||
// another command.
|
// another command.
|
||||||
this->lastFrame.processed = false;
|
this->lastFrame.processed = false;
|
||||||
if(this->proto == radio_proto::GPIO) {
|
if(this->proto == radio_proto::GP_Relay) {
|
||||||
Serial.print("CMD:");
|
Serial.print("CMD:");
|
||||||
Serial.print(translateSomfyCommand(this->lastFrame.cmd));
|
Serial.print(translateSomfyCommand(this->lastFrame.cmd));
|
||||||
Serial.print(" ADDR:");
|
Serial.print(" ADDR:");
|
||||||
|
|
@ -2967,6 +3058,16 @@ void SomfyRemote::sendCommand(somfy_commands cmd, uint8_t repeat) {
|
||||||
Serial.print(this->lastFrame.rollingCode);
|
Serial.print(this->lastFrame.rollingCode);
|
||||||
Serial.println(" SETTING GPIO");
|
Serial.println(" SETTING GPIO");
|
||||||
}
|
}
|
||||||
|
else if(this->proto == radio_proto::GP_Remote) {
|
||||||
|
Serial.print("CMD:");
|
||||||
|
Serial.print(translateSomfyCommand(this->lastFrame.cmd));
|
||||||
|
Serial.print(" ADDR:");
|
||||||
|
Serial.print(this->lastFrame.remoteAddress);
|
||||||
|
Serial.print(" RCODE:");
|
||||||
|
Serial.print(this->lastFrame.rollingCode);
|
||||||
|
Serial.println(" TRIGGER GPIO");
|
||||||
|
this->triggerGPIOs(this->lastFrame);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
Serial.print("CMD:");
|
Serial.print("CMD:");
|
||||||
Serial.print(translateSomfyCommand(this->lastFrame.cmd));
|
Serial.print(translateSomfyCommand(this->lastFrame.cmd));
|
||||||
|
|
@ -2988,6 +3089,12 @@ bool SomfyRemote::isLastCommand(somfy_commands cmd) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void SomfyRemote::repeatFrame(uint8_t repeat) {
|
void SomfyRemote::repeatFrame(uint8_t repeat) {
|
||||||
|
if(this->proto == radio_proto::GP_Relay)
|
||||||
|
return;
|
||||||
|
else if(this->proto == radio_proto::GP_Remote) {
|
||||||
|
this->triggerGPIOs(this->lastFrame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
somfy.transceiver.beginTransmit();
|
somfy.transceiver.beginTransmit();
|
||||||
byte frm[10];
|
byte frm[10];
|
||||||
this->lastFrame.encodeFrame(frm);
|
this->lastFrame.encodeFrame(frm);
|
||||||
|
|
|
||||||
11
Somfy.h
11
Somfy.h
|
|
@ -26,7 +26,8 @@ enum class radio_proto : byte { // Ordinal byte 0-255
|
||||||
RTS = 0x00,
|
RTS = 0x00,
|
||||||
RTW = 0x01,
|
RTW = 0x01,
|
||||||
RTV = 0x02,
|
RTV = 0x02,
|
||||||
GPIO = 0x08
|
GP_Relay = 0x08,
|
||||||
|
GP_Remote = 0x09
|
||||||
};
|
};
|
||||||
enum class somfy_commands : byte {
|
enum class somfy_commands : byte {
|
||||||
Unknown0 = 0x0,
|
Unknown0 = 0x0,
|
||||||
|
|
@ -185,8 +186,11 @@ class SomfyRemote {
|
||||||
uint32_t m_remoteAddress = 0;
|
uint32_t m_remoteAddress = 0;
|
||||||
public:
|
public:
|
||||||
radio_proto proto = radio_proto::RTS;
|
radio_proto proto = radio_proto::RTS;
|
||||||
|
int8_t gpioDir = 0;
|
||||||
uint8_t gpioUp = 0;
|
uint8_t gpioUp = 0;
|
||||||
uint8_t gpioDown = 0;
|
uint8_t gpioDown = 0;
|
||||||
|
uint8_t gpioMy = 0;
|
||||||
|
uint32_t gpioRelease = 0;
|
||||||
somfy_frame_t lastFrame;
|
somfy_frame_t lastFrame;
|
||||||
bool flipCommands = false;
|
bool flipCommands = false;
|
||||||
uint16_t lastRollingCode = 0;
|
uint16_t lastRollingCode = 0;
|
||||||
|
|
@ -210,6 +214,8 @@ class SomfyRemote {
|
||||||
void repeatFrame(uint8_t repeat);
|
void repeatFrame(uint8_t repeat);
|
||||||
virtual uint16_t p_lastRollingCode(uint16_t code);
|
virtual uint16_t p_lastRollingCode(uint16_t code);
|
||||||
somfy_commands transformCommand(somfy_commands cmd);
|
somfy_commands transformCommand(somfy_commands cmd);
|
||||||
|
void triggerGPIOs(somfy_frame_t &frame);
|
||||||
|
|
||||||
};
|
};
|
||||||
class SomfyLinkedRemote : public SomfyRemote {
|
class SomfyLinkedRemote : public SomfyRemote {
|
||||||
public:
|
public:
|
||||||
|
|
@ -236,7 +242,6 @@ class SomfyShade : public SomfyRemote {
|
||||||
bool settingTiltPos = false;
|
bool settingTiltPos = false;
|
||||||
uint32_t awaitMy = 0;
|
uint32_t awaitMy = 0;
|
||||||
public:
|
public:
|
||||||
int8_t gpioDir = 0;
|
|
||||||
int8_t sortOrder = 0;
|
int8_t sortOrder = 0;
|
||||||
bool flipPosition = false;
|
bool flipPosition = false;
|
||||||
shade_types shadeType = shade_types::roller;
|
shade_types shadeType = shade_types::roller;
|
||||||
|
|
@ -296,9 +301,9 @@ class SomfyShade : public SomfyRemote {
|
||||||
void commitShadePosition();
|
void commitShadePosition();
|
||||||
void commitTiltPosition();
|
void commitTiltPosition();
|
||||||
void commitMyPosition();
|
void commitMyPosition();
|
||||||
void setGPIOs();
|
|
||||||
void clear();
|
void clear();
|
||||||
int8_t transformPosition(float fpos);
|
int8_t transformPosition(float fpos);
|
||||||
|
void setGPIOs();
|
||||||
|
|
||||||
// State Setters
|
// State Setters
|
||||||
int8_t p_direction(int8_t dir);
|
int8_t p_direction(int8_t dir);
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -293,7 +293,8 @@
|
||||||
<option value="0">RTS</option>
|
<option value="0">RTS</option>
|
||||||
<option value="1">RTW</option>
|
<option value="1">RTW</option>
|
||||||
<option value="2">RTV</option>
|
<option value="2">RTV</option>
|
||||||
<option value="8">GPIO</option>
|
<option value="8">Relay</option>
|
||||||
|
<option value="9">Remote</option>
|
||||||
</select>
|
</select>
|
||||||
<label for="selShadeProto">Protocol</label>
|
<label for="selShadeProto">Protocol</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -304,17 +305,23 @@
|
||||||
</select>
|
</select>
|
||||||
<label for="selShadeBitLength">Bit Length</label>
|
<label for="selShadeBitLength">Bit Length</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="divGPIOControl" class=" field-group">
|
<div id="divGPIOControl" class="field-group">
|
||||||
<div class="field-group" style="width:70px;display:inline-block;">
|
<div class="field-group" style="">
|
||||||
<select id="selShadeGPIOUp" data-bind="gpioUp" data-datatype="int" style="width:70px;">
|
<select id="selShadeGPIOUp" data-bind="gpioUp" data-datatype="int" style="width:70px;">
|
||||||
</select>
|
</select>
|
||||||
<label for="selShadeGPIOUp">UP</label>
|
<label for="selShadeGPIOUp">UP</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-group" style="width:70px;display:inline-block;">
|
<div class="field-group" style="">
|
||||||
<select id="selShadeGPIODown" data-bind="gpioDown" data-datatype="int" style="width:70px;">
|
<select id="selShadeGPIODown" data-bind="gpioDown" data-datatype="int" style="width:70px;">
|
||||||
</select>
|
</select>
|
||||||
<label for="selShadeGPIODown">Down</label>
|
<label for="selShadeGPIODown">Down</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="divGPIOMy" class="field-group" style="">
|
||||||
|
<select id="selShadeGPIOMy" data-bind="gpioMy" data-datatype="int" style="width:70px;">
|
||||||
|
</select>
|
||||||
|
<label for="selShadeGPIOMy">My</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -1857,10 +1857,11 @@ class Somfy {
|
||||||
this.loadPins('input', document.getElementById('selTransRXPin'));
|
this.loadPins('input', document.getElementById('selTransRXPin'));
|
||||||
//this.loadSomfy();
|
//this.loadSomfy();
|
||||||
ui.toElement(document.getElementById('divTransceiverSettings'), {
|
ui.toElement(document.getElementById('divTransceiverSettings'), {
|
||||||
transceiver: { config: { proto: 0, SCKPin: 18, CSNPin: 5, MOSIPin: 23, MISOPin: 19, TXPin: 12, RXPin: 13, frequency: 433.42, rxBandwidth: 97.96, type:56, deviation: 11.43, txPower: 10, enabled: false } }
|
transceiver: { config: { proto: 0, SCKPin: 18, CSNPin: 5, MOSIPin: 23, MISOPin: 19, TXPin: 12, RXPin: 13, frequency: 433.42, rxBandwidth: 97.96, type: 56, deviation: 11.43, txPower: 10, enabled: false } }
|
||||||
});
|
});
|
||||||
this.loadPins('out', document.getElementById('selShadeGPIOUp'));
|
this.loadPins('out', document.getElementById('selShadeGPIOUp'));
|
||||||
this.loadPins('out', document.getElementById('selShadeGPIODown'));
|
this.loadPins('out', document.getElementById('selShadeGPIODown'));
|
||||||
|
this.loadPins('out', document.getElementById('selShadeGPIOMy'));
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
async loadSomfy() {
|
async loadSomfy() {
|
||||||
|
|
@ -2112,7 +2113,7 @@ class Somfy {
|
||||||
divCtl += `<span class="shadectl-name">${shade.name}</span>`;
|
divCtl += `<span class="shadectl-name">${shade.name}</span>`;
|
||||||
if (shade.tiltType === 3)
|
if (shade.tiltType === 3)
|
||||||
divCtl += `<span class="shadectl-mypos"><label>My Tilt: </label><span id="spanMyTiltPos">${shade.myTiltPos > 0 ? shade.myTiltPos + '%' : '---'}</span>`
|
divCtl += `<span class="shadectl-mypos"><label>My Tilt: </label><span id="spanMyTiltPos">${shade.myTiltPos > 0 ? shade.myTiltPos + '%' : '---'}</span>`
|
||||||
else if(shade.shadeType !== 5 && shade.shadeType !== 9) {
|
else if (shade.shadeType !== 5 && shade.shadeType !== 9) {
|
||||||
divCtl += `<span class="shadectl-mypos"><label>My: </label><span id="spanMyPos">${shade.myPos > 0 ? shade.myPos + '%' : '---'}</span>`;
|
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>`;
|
if (shade.myTiltPos > 0 && shade.tiltType !== 3) divCtl += `<label> Tilt: </label><span id="spanMyTiltPos">${shade.myTiltPos > 0 ? shade.myTiltPos + '%' : '---'}</span>`;
|
||||||
}
|
}
|
||||||
|
|
@ -2248,7 +2249,7 @@ class Somfy {
|
||||||
let changed = false;
|
let changed = false;
|
||||||
let timerStart = null;
|
let timerStart = null;
|
||||||
let dragDiv = null;
|
let dragDiv = null;
|
||||||
let fnDragStart = function(e) {
|
let fnDragStart = function (e) {
|
||||||
//console.log({ evt: 'dragStart', e: e, this: this });
|
//console.log({ evt: 'dragStart', e: e, this: this });
|
||||||
if (typeof e.dataTransfer !== 'undefined') {
|
if (typeof e.dataTransfer !== 'undefined') {
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
|
@ -2317,7 +2318,7 @@ class Somfy {
|
||||||
console.log({ evt: 'dragLeave', e: e, this: this });
|
console.log({ evt: 'dragLeave', e: e, this: this });
|
||||||
this.classList.remove('over');
|
this.classList.remove('over');
|
||||||
};
|
};
|
||||||
let fnDrop = function(e) {
|
let fnDrop = function (e) {
|
||||||
// Shift around the items.
|
// Shift around the items.
|
||||||
console.log({ evt: 'drop', e: e, this: this });
|
console.log({ evt: 'drop', e: e, this: this });
|
||||||
let elDrag = list.querySelector('.dragging');
|
let elDrag = list.querySelector('.dragging');
|
||||||
|
|
@ -2333,7 +2334,7 @@ class Somfy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let fnDragEnd = function(e) {
|
let fnDragEnd = function (e) {
|
||||||
console.log({ evt: 'dragEnd', e: e, this: this });
|
console.log({ evt: 'dragEnd', e: e, this: this });
|
||||||
let elOver = list.querySelector('.over');
|
let elOver = list.querySelector('.over');
|
||||||
[].forEach.call(items, (item) => { item.classList.remove('over') });
|
[].forEach.call(items, (item) => { item.classList.remove('over') });
|
||||||
|
|
@ -2604,7 +2605,7 @@ class Somfy {
|
||||||
case 9:
|
case 9:
|
||||||
case 10:
|
case 10:
|
||||||
case 11:
|
case 11:
|
||||||
if(type !== 'inout' && type !== 'input') continue;
|
if (type !== 'inout' && type !== 'input') continue;
|
||||||
break;
|
break;
|
||||||
case 37:
|
case 37:
|
||||||
case 38:
|
case 38:
|
||||||
|
|
@ -3110,12 +3111,18 @@ class Somfy {
|
||||||
ui.errorMessage(document.getElementById('divSomfySettings'), 'Down Time must be a value between 0 and 4,294,967,295 milliseconds. This is the travel time to go from full open to full closed.');
|
ui.errorMessage(document.getElementById('divSomfySettings'), 'Down Time must be a value between 0 and 4,294,967,295 milliseconds. This is the travel time to go from full open to full closed.');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (obj.proto === 8) {
|
if (obj.proto === 8 || obj.proto === 9) {
|
||||||
if (obj.gpioUp === obj.gpioDown) {
|
if (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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (obj.proto === 9) {
|
||||||
|
if (obj.gpioMy === obj.gpioUp || obj.gpioMy === obj.gpioDown) {
|
||||||
|
ui.errorMessage(document.getElementById('divSomfySettings'), 'For GPIO controlled motors the up and down and my GPIO selections must be unique.');
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (isNaN(shadeId) || shadeId >= 255) {
|
if (isNaN(shadeId) || shadeId >= 255) {
|
||||||
// We are adding.
|
// We are adding.
|
||||||
|
|
|
||||||
|
|
@ -141,25 +141,33 @@
|
||||||
#somfyShade #divShadeBitLength {
|
#somfyShade #divShadeBitLength {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
}
|
}
|
||||||
#somfyShade[data-proto="8"] #divGPIOControl {
|
#somfyShade[data-proto="8"] #divGPIOControl,
|
||||||
|
#somfyShade[data-proto="9"] #divGPIOControl {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: auto;
|
width: auto;
|
||||||
margin-top: -18px;
|
margin-top: -18px;
|
||||||
}
|
}
|
||||||
#somfyShade[data-proto="8"] #divShadeBitLength {
|
#somfyShade[data-proto="8"] #divShadeBitLength,
|
||||||
|
#somfyShade[data-proto="9"] #divShadeBitLength {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#divGPIOControl {
|
#divGPIOControl {
|
||||||
text-align:center;
|
text-align:center;
|
||||||
margin-left:7px;
|
margin-left:7px;
|
||||||
}
|
}
|
||||||
|
#divGPIOControl > div.field-group {
|
||||||
|
width: 70px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
#somfyShade[data-proto="8"] #divStepSettings,
|
#somfyShade[data-proto="8"] #divStepSettings,
|
||||||
|
#somfyShade[data-proto="9"] #divStepSettings,
|
||||||
|
#somfyShade[data-proto="8"] #divGPIOMy,
|
||||||
#somfyShade[data-bitlength="56"] #divStepSettings,
|
#somfyShade[data-bitlength="56"] #divStepSettings,
|
||||||
#somfyShade[data-shadetype="5"] #divStepSettings,
|
#somfyShade[data-shadetype="5"] #divStepSettings,
|
||||||
#somfyShade[data-shadetype="6"] #divStepSettings,
|
#somfyShade[data-shadetype="6"] #divStepSettings {
|
||||||
#somfyShade[data-shadetype="9"] #divStepSettings {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.group-draggable,
|
.group-draggable,
|
||||||
.shade-draggable {
|
.shade-draggable {
|
||||||
height:32px;
|
height:32px;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue