first commit
This commit is contained in:
757
ESP8266_DOMOTICZ_OCTOPRINT_WEB_VOLETS/Somfy.cpp
Normal file
757
ESP8266_DOMOTICZ_OCTOPRINT_WEB_VOLETS/Somfy.cpp
Normal file
@@ -0,0 +1,757 @@
|
||||
// -------------------------------------------------------------
|
||||
//
|
||||
// Fichier principal de votre Box compatible Somfy RTS ou Chacon Dio
|
||||
// Version 1.1.0
|
||||
// Mise à jour par TOST Corp. le 02 janvier 2020
|
||||
// www.tostcorp.com/boxsomfyrts
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
|
||||
#include "config.h"
|
||||
// #include "Somfy.h"
|
||||
void blink_function();
|
||||
Ticker mqtt_error_timer(blink_function, 10, 11);
|
||||
Ticker blink_timer(blink_function, 200, 21);
|
||||
Ticker publish_timer(blink_function, 10, 11);
|
||||
void receivedCallback(char* topic, byte* payload, unsigned int length);
|
||||
|
||||
Somfy::Somfy()
|
||||
{
|
||||
}
|
||||
void Somfy::init()
|
||||
{
|
||||
// USB serial port
|
||||
delay(100);
|
||||
|
||||
while(! Serial);
|
||||
Serial.println(" ------------------------------------------------");
|
||||
Serial.println("| |");
|
||||
Serial.println("| TOST Corp. Box V1.0.2 - Copyright 2018-2020 |");
|
||||
Serial.println("| |");
|
||||
Serial.println(" ------------------------------------------------");
|
||||
Serial.println("");
|
||||
Serial.println("Available features:");
|
||||
Serial.println("1 SOMFY RTS");
|
||||
Serial.println("2 CHACON DiO 1.0");
|
||||
Serial.println("");
|
||||
Serial.println("Starting the Box...");
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
|
||||
// Open the output for 433.42MHz transmitter
|
||||
pinMode(PORT_TX, OUTPUT);
|
||||
// Open the output for 433.92MHz transmitter
|
||||
pinMode(PORT_DIO_TX, OUTPUT);
|
||||
SIG_LOW;
|
||||
digitalWrite(PORT_DIO_TX, LOW);
|
||||
|
||||
String device_id = WiFi.macAddress();
|
||||
|
||||
// Remove :
|
||||
while (device_id.indexOf(':') != -1)
|
||||
{
|
||||
int index_to_remove = device_id.indexOf(':');
|
||||
device_id.remove(index_to_remove, 1);
|
||||
}
|
||||
|
||||
Serial.print("Box ID: ");
|
||||
Serial.println(device_id);
|
||||
|
||||
// Connect to WiFi
|
||||
Serial.print("WiFi connection to ");
|
||||
Serial.print(wifi_ssid);
|
||||
Serial.print(" ");
|
||||
|
||||
WiFi.begin(wifi_ssid, wifi_password);
|
||||
WiFi.hostname("ESP8266-somfy");
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
Serial.print("Connected to WiFi | IP adress ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
// Configure MQTT
|
||||
|
||||
PubSubClient _mqtt(wifiClient);
|
||||
mqtt = _mqtt;
|
||||
mqtt.setServer(mqtt_server, mqtt_port);
|
||||
//mqtt.setCallback(receivedCallback);
|
||||
|
||||
mqtt.setCallback([this] (char* topic, byte* payload, unsigned int length) {
|
||||
this->receivedCallback(topic, payload, length);
|
||||
});
|
||||
|
||||
EEPROM.begin(1024);
|
||||
|
||||
// Print out all the configured remotes.
|
||||
// Also reset the rolling codes for ESP8266 if needed.
|
||||
|
||||
Serial.print("");
|
||||
Serial.println("Read the configuration...");
|
||||
|
||||
if (update_database)
|
||||
{
|
||||
clean_database(device_id);
|
||||
}
|
||||
|
||||
for ( REMOTE remote : remotes )
|
||||
{
|
||||
Serial.print("SOMFY RTS: ");
|
||||
Serial.print(remote.mqtt_topic);
|
||||
Serial.print(" | number: ");
|
||||
Serial.print(remote.id, HEX);
|
||||
Serial.print(" | rolling code: ");
|
||||
unsigned int current_code;
|
||||
|
||||
if ( reset_rolling_codes )
|
||||
{
|
||||
EEPROM.put( remote.eeprom_address, remote.default_rolling_code );
|
||||
EEPROM.commit();
|
||||
}
|
||||
EEPROM.get( remote.eeprom_address, current_code );
|
||||
Serial.print( current_code );
|
||||
Serial.print(" | description: ");
|
||||
Serial.println( remote.description );
|
||||
|
||||
// Add to database
|
||||
if (update_database)
|
||||
{
|
||||
add_to_database(device_id, remote.mqtt_topic, remote.description, "somfy_rts", remote.device_group);
|
||||
}
|
||||
}
|
||||
|
||||
for ( DIO_REMOTE dio_remote : dio_remotes )
|
||||
{
|
||||
Serial.print("CHACON DiO: ");
|
||||
Serial.print(dio_remote.mqtt_topic);
|
||||
Serial.print(" | number: ");
|
||||
Serial.print(dio_remote.id, HEX);
|
||||
Serial.print(" | description: ");
|
||||
Serial.println(dio_remote.description);
|
||||
|
||||
// Add to database
|
||||
if (update_database)
|
||||
{
|
||||
add_to_database(device_id, dio_remote.mqtt_topic, dio_remote.description, "chacon_dio_1.0", dio_remote.device_group);
|
||||
}
|
||||
|
||||
} // End of for
|
||||
|
||||
Serial.print("");
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
blink_timer.start();
|
||||
}
|
||||
|
||||
void Somfy::loop()
|
||||
{
|
||||
publish_timer.update();
|
||||
|
||||
// Reconnect MQTT if needed
|
||||
if ( !mqtt.connected() )
|
||||
{
|
||||
mqttconnect();
|
||||
// We are connected stop blinking to Wifi
|
||||
blink_timer.stop();
|
||||
Serial.println("The box is ready.\n");
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
mqtt.loop();
|
||||
loopSerial();
|
||||
delay(100);
|
||||
}
|
||||
|
||||
void Somfy::mqttconnect()
|
||||
{
|
||||
|
||||
// Loop until reconnected
|
||||
while ( !mqtt.connected() )
|
||||
{
|
||||
Serial.print("Connecting to MQTT ...");
|
||||
Serial.print(mqtt_id);
|
||||
Serial.print(mqtt_user);
|
||||
Serial.print(mqtt_password);
|
||||
Serial.print(status_topic);
|
||||
// Connect to MQTT, with retained last will message "offline"
|
||||
if (mqtt.connect(mqtt_id, mqtt_user, mqtt_password, status_topic, 1, 1, "offline")) {
|
||||
Serial.println(" Connected.");
|
||||
|
||||
Serial.print("Suscribe to MQTT .");
|
||||
// Subscribe to the topic of each remote with QoS 1
|
||||
for ( REMOTE remote : remotes ) {
|
||||
mqtt.subscribe(remote.mqtt_topic, 1);
|
||||
mqtt.subscribe(remote.device_group, 1);
|
||||
Serial.print(".");
|
||||
// Serial.print("\nLOG - Subscribed to SOMFY RTS topic: ");
|
||||
// Serial.println(remote.device_group);
|
||||
}
|
||||
|
||||
// Subscribe to the topic of each remote with QoS 1
|
||||
for ( DIO_REMOTE remote : dio_remotes ) {
|
||||
mqtt.subscribe(remote.mqtt_topic, 1);
|
||||
mqtt.subscribe(remote.device_group, 1);
|
||||
Serial.print(".");
|
||||
// Serial.print("\nLOG - Subscribed to DIO topic: ");
|
||||
// Serial.println(remote.mqtt_topic);
|
||||
}
|
||||
|
||||
// Update status, message is retained
|
||||
mqtt.publish(status_topic, "online", true);
|
||||
Serial.println("Done.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("ERR - Failed, status code = ");
|
||||
Serial.print(mqtt.state());
|
||||
Serial.println(" Try again in 5 seconds");
|
||||
// Wait 5 seconds before retrying
|
||||
blink_blue_light(5000, 200);
|
||||
}
|
||||
}
|
||||
blink_blue_light(500, 50);
|
||||
}
|
||||
|
||||
|
||||
void Somfy::receivedCallback(char* topic, byte* payload, unsigned int length) {
|
||||
char command = *payload; // 1st byte of payload
|
||||
bool commandIsValid = false;
|
||||
bool dioCommandIsValid = false;
|
||||
|
||||
String s_topic = String(topic);
|
||||
|
||||
REMOTE currentRemote;
|
||||
REMOTE remote;
|
||||
|
||||
// DIO_REMOTE dio_remote;
|
||||
DIO_REMOTE dio_currentRemote;
|
||||
|
||||
Serial.print("MQTT message received: ");
|
||||
digitalWrite(BUILTIN_LED, LOW);
|
||||
publish_timer.start();
|
||||
Serial.println(topic);
|
||||
|
||||
Serial.print("Payload: ");
|
||||
for (int i = 0; i < length; i++) {
|
||||
Serial.print((char)payload[i]);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Somfy command is valid if the payload contains one of the chars below AND the topic corresponds to one of the remotes
|
||||
if ( length == 1 && ( command == 'u' || command == 's' || command == 'd' || command == 'p' ) )
|
||||
{
|
||||
Serial.println("SOMFY RTS command received");
|
||||
int nb_remotes = sizeof remotes/sizeof remotes[0];
|
||||
for (int i=0; i<nb_remotes; i++)
|
||||
{
|
||||
remote = remotes[i];
|
||||
String s_mqtt_topic = String(remote.mqtt_topic);
|
||||
String s_device_group = String(remote.device_group);
|
||||
|
||||
// if ( strcmp(remote.mqtt_topic, s_topic) == 0 )
|
||||
if ( s_mqtt_topic.compareTo(s_topic) == 0 )
|
||||
{
|
||||
commandIsValid = true;
|
||||
send_somfy_command(command, remote, false);
|
||||
}
|
||||
// if ( strcmp(remote.device_group, s_topic) == 0 )
|
||||
else if ( s_device_group.compareTo(s_topic) == 0 )
|
||||
{
|
||||
Serial.print("SOMFY RTS command is grouped ");
|
||||
Serial.println(remote.mqtt_topic);
|
||||
commandIsValid = true;
|
||||
send_somfy_command(command, remote, true);
|
||||
}
|
||||
} // End of for
|
||||
}
|
||||
|
||||
// DIO command
|
||||
if ( length ==1 && ( command == '1' || command == '0' ) )
|
||||
{
|
||||
Serial.println("DiO command received");
|
||||
for ( DIO_REMOTE dio_remote : dio_remotes )
|
||||
{
|
||||
String s_mqtt_topic = String(dio_remote.mqtt_topic);
|
||||
String s_device_group = String(dio_remote.device_group);
|
||||
|
||||
// Single command
|
||||
// if ( strcmp(dio_remote.mqtt_topic, topic) == 0 )
|
||||
if ( s_mqtt_topic.compareTo(s_topic) == 0 )
|
||||
{
|
||||
dioCommandIsValid = true;
|
||||
send_dio_command(command, dio_remote, false);
|
||||
}
|
||||
// Multiple command
|
||||
// else if ( strcmp(dio_remote.device_group, topic) == 0 )
|
||||
else if ( s_device_group.compareTo(s_topic) == 0 )
|
||||
{
|
||||
Serial.println("DiO command is grouped");
|
||||
dioCommandIsValid = true;
|
||||
send_dio_command(command, dio_remote, true);
|
||||
}
|
||||
|
||||
} // End of for
|
||||
}
|
||||
}
|
||||
|
||||
void Somfy::send_somfy_command(char command, REMOTE currentRemote, bool group)
|
||||
{
|
||||
|
||||
if ( command == 'u' )
|
||||
{
|
||||
Serial.println("COMMAND - Up"); // Somfy is a French company, after all.
|
||||
BuildFrame(frame, HAUT, currentRemote);
|
||||
}
|
||||
else if ( command == 's' )
|
||||
{
|
||||
Serial.println("COMMAND - Stop");
|
||||
BuildFrame(frame, STOP, currentRemote);
|
||||
}
|
||||
else if ( command == 'd' )
|
||||
{
|
||||
Serial.println("COMMAND - Down");
|
||||
BuildFrame(frame, BAS, currentRemote);
|
||||
}
|
||||
else if ( command == 'p' )
|
||||
{
|
||||
Serial.println("COMMAND - Prog");
|
||||
BuildFrame(frame, PROG, currentRemote);
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
|
||||
SendCommand(frame, 2);
|
||||
for ( int i = 0; i<2; i++ ) {
|
||||
SendCommand(frame, 7);
|
||||
}
|
||||
|
||||
// Send the MQTT ack message
|
||||
String ackString = "id: 0x";
|
||||
ackString.concat( String(currentRemote.id, HEX) );
|
||||
ackString.concat(", cmd: ");
|
||||
ackString.concat(command);
|
||||
mqtt.publish(ack_topic, ackString.c_str());
|
||||
if (group)
|
||||
{
|
||||
delay(delay_group_radio_signal);
|
||||
}
|
||||
}
|
||||
|
||||
void Somfy::send_dio_command(char command, DIO_REMOTE dio_currentRemote, bool group)
|
||||
{
|
||||
if ( command == '0' )
|
||||
{
|
||||
Serial.println("COMMAND - 0");
|
||||
// Serial.println(dio_currentRemote.sender);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
transmit(dio_currentRemote.sender, dio_currentRemote.interruptor, 0);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
else if ( command == '1' )
|
||||
{
|
||||
Serial.println("COMMAND - 1");
|
||||
// Serial.println(dio_currentRemote.sender);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
transmit(dio_currentRemote.sender, dio_currentRemote.interruptor, 1);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
|
||||
// Send the MQTT ack message
|
||||
String ackString = "id: 0x";
|
||||
ackString.concat( String(dio_currentRemote.id, HEX) );
|
||||
ackString.concat(", cmd: ");
|
||||
ackString.concat(command);
|
||||
mqtt.publish(ack_topic, ackString.c_str());
|
||||
if (group)
|
||||
{
|
||||
delay(delay_group_radio_signal);
|
||||
}
|
||||
}
|
||||
|
||||
void Somfy::BuildFrame(byte *frame, byte button, REMOTE remote) {
|
||||
unsigned int code;
|
||||
|
||||
EEPROM.get( remote.eeprom_address, code );
|
||||
|
||||
frame[0] = 0xA7; // Encryption key. Doesn't matter much
|
||||
frame[1] = button << 4; // Which button did you press? The 4 LSB will be the checksum
|
||||
frame[2] = code >> 8; // Rolling code (big endian)
|
||||
frame[3] = code; // Rolling code
|
||||
frame[4] = remote.id >> 16; // Remote address
|
||||
frame[5] = remote.id >> 8; // Remote address
|
||||
frame[6] = remote.id; // Remote address
|
||||
|
||||
Serial.print("Frame : ");
|
||||
for(byte i = 0; i < 7; i++) {
|
||||
if(frame[i] >> 4 == 0) { // Displays leading zero in case the most significant nibble is a 0.
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(frame[i],HEX); Serial.print(" ");
|
||||
}
|
||||
|
||||
// Checksum calculation: a XOR of all the nibbles
|
||||
byte checksum = 0;
|
||||
for(byte i = 0; i < 7; i++) {
|
||||
checksum = checksum ^ frame[i] ^ (frame[i] >> 4);
|
||||
}
|
||||
checksum &= 0b1111; // We keep the last 4 bits only
|
||||
|
||||
|
||||
// Checksum integration
|
||||
frame[1] |= checksum; // If a XOR of all the nibbles is equal to 0, the blinds will consider the checksum ok.
|
||||
|
||||
Serial.println(""); Serial.print("With checksum : ");
|
||||
for(byte i = 0; i < 7; i++) {
|
||||
if(frame[i] >> 4 == 0) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(frame[i],HEX); Serial.print(" ");
|
||||
}
|
||||
|
||||
|
||||
// Obfuscation: a XOR of all the bytes
|
||||
for(byte i = 1; i < 7; i++) {
|
||||
frame[i] ^= frame[i-1];
|
||||
}
|
||||
|
||||
Serial.println(""); Serial.print("Obfuscated : ");
|
||||
for(byte i = 0; i < 7; i++) {
|
||||
if(frame[i] >> 4 == 0) {
|
||||
Serial.print("0");
|
||||
}
|
||||
Serial.print(frame[i],HEX); Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("Rolling Code : ");
|
||||
Serial.println(code);
|
||||
|
||||
EEPROM.put( remote.eeprom_address, code + 1 );
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void Somfy::SendCommand(byte *frame, byte sync) {
|
||||
if(sync == 2) { // Only with the first frame.
|
||||
//Wake-up pulse & Silence
|
||||
SIG_HIGH;
|
||||
delayMicroseconds(9415);
|
||||
SIG_LOW;
|
||||
delayMicroseconds(89565);
|
||||
}
|
||||
|
||||
// Hardware sync: two sync for the first frame, seven for the following ones.
|
||||
for (int i = 0; i < sync; i++) {
|
||||
SIG_HIGH;
|
||||
delayMicroseconds(4*SYMBOL);
|
||||
SIG_LOW;
|
||||
delayMicroseconds(4*SYMBOL);
|
||||
}
|
||||
|
||||
// Software sync
|
||||
SIG_HIGH;
|
||||
delayMicroseconds(4550);
|
||||
SIG_LOW;
|
||||
delayMicroseconds(SYMBOL);
|
||||
|
||||
//Data: bits are sent one by one, starting with the MSB.
|
||||
for(byte i = 0; i < 56; i++) {
|
||||
if(((frame[i/8] >> (7 - (i%8))) & 1) == 1) {
|
||||
SIG_LOW;
|
||||
delayMicroseconds(SYMBOL);
|
||||
SIG_HIGH;
|
||||
delayMicroseconds(SYMBOL);
|
||||
}
|
||||
else {
|
||||
SIG_HIGH;
|
||||
delayMicroseconds(SYMBOL);
|
||||
SIG_LOW;
|
||||
delayMicroseconds(SYMBOL);
|
||||
}
|
||||
}
|
||||
|
||||
SIG_LOW;
|
||||
delayMicroseconds(30415); // Inter-frame silence
|
||||
}
|
||||
|
||||
void blink_function()
|
||||
{
|
||||
//toggle state
|
||||
int state = digitalRead(BUILTIN_LED); // get the current state of GPIO1 pin
|
||||
digitalWrite(BUILTIN_LED, !state); // set pin to the opposite state
|
||||
// Serial.print("blink_function()");
|
||||
}
|
||||
|
||||
void Somfy::blink_blue_light(int time_ms, int delay_ms)
|
||||
{
|
||||
int total_time = 0;
|
||||
int light = 0;
|
||||
while (total_time < time_ms)
|
||||
{
|
||||
if (light == 0)
|
||||
{
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
light = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
light = 0;
|
||||
}
|
||||
|
||||
delay(delay_ms);
|
||||
total_time = total_time + delay_ms;
|
||||
}
|
||||
|
||||
// force off
|
||||
digitalWrite(0, HIGH);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Somfy::sendBit(bool b)
|
||||
{
|
||||
if (b) {
|
||||
digitalWrite(PORT_DIO_TX, HIGH);
|
||||
delayMicroseconds(310); //275 originally, but tweaked.
|
||||
digitalWrite(PORT_DIO_TX, LOW);
|
||||
delayMicroseconds(1340); //1225 originally, but tweaked.
|
||||
} else {
|
||||
digitalWrite(PORT_DIO_TX, HIGH);
|
||||
delayMicroseconds(310); //275 originally, but tweaked.
|
||||
digitalWrite(PORT_DIO_TX, LOW);
|
||||
delayMicroseconds(310); //275 originally, but tweaked.
|
||||
}
|
||||
}
|
||||
|
||||
void Somfy::sendPair(bool b) {
|
||||
if (b) {
|
||||
sendBit(true);
|
||||
sendBit(false);
|
||||
} else {
|
||||
sendBit(false);
|
||||
sendBit(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Somfy::transmit(unsigned long sender, int interruptor, int blnOn) {
|
||||
int i;
|
||||
|
||||
digitalWrite(PORT_DIO_TX, HIGH);
|
||||
delayMicroseconds(275);
|
||||
digitalWrite(PORT_DIO_TX, LOW);
|
||||
delayMicroseconds(9900); // first lock
|
||||
digitalWrite(PORT_DIO_TX, HIGH); // high again
|
||||
delayMicroseconds(275); // wait
|
||||
digitalWrite(PORT_DIO_TX, LOW); // second lock
|
||||
delayMicroseconds(2675);
|
||||
digitalWrite(PORT_DIO_TX, HIGH);
|
||||
|
||||
// Emiter ID
|
||||
for(i = 0; i < 26; i++) {
|
||||
sendPair( (sender >> (25 - i)) & 0b1);
|
||||
}
|
||||
|
||||
// 26th bit -- grouped command
|
||||
sendPair(false);
|
||||
|
||||
// 27th bit -- On or off
|
||||
sendPair(blnOn);
|
||||
|
||||
// 4 last bits -- reactor code 0000 -> 0 -- 0001 -> 1
|
||||
for (i = 0; i < 4; i++) {
|
||||
sendPair( (interruptor >> (3 - i)) & 1 );
|
||||
}
|
||||
|
||||
digitalWrite(PORT_DIO_TX, HIGH); // lock - end of data
|
||||
delayMicroseconds(275); // wait
|
||||
digitalWrite(PORT_DIO_TX, LOW); // lock - end of signal
|
||||
}
|
||||
|
||||
int Somfy::add_to_database(String device_id,const char* mqtt_topic, const char* description, const char* type, const char* device_group)
|
||||
{
|
||||
|
||||
if (wifiClient.connect(HOST, 80))
|
||||
{
|
||||
String url = "/somfy_rts/mqtt_web_hook_public.php?service=add_device&device_id=" + device_id +
|
||||
"&topic=" + urlencode(mqtt_topic) + "&description=" + urlencode(description) + "&type=" + type +
|
||||
"&device_group=" + urlencode(device_group)+ "&mqtt_info=" + urlencode(mqtt_password);
|
||||
|
||||
wifiClient.print(String("GET ") + url + " HTTP/1.1\r\n" +
|
||||
"Host: " + HOST + "\r\n" +
|
||||
"Connection: close\r\n\r\n");
|
||||
|
||||
String line = wifiClient.readStringUntil('\r');
|
||||
// Serial.println(line);
|
||||
|
||||
// Read all the lines of the reply from server and print them to Serial
|
||||
while(wifiClient.available())
|
||||
{
|
||||
line = wifiClient.readStringUntil('\r');
|
||||
// Serial.print(line);
|
||||
}
|
||||
|
||||
Serial.print("The device \"");
|
||||
Serial.print(description);
|
||||
Serial.println("\" was added/updated to the database.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("An error occurs while adding the device \"");
|
||||
Serial.print(description);
|
||||
Serial.print("\"");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int Somfy::clean_database(String device_id)
|
||||
{
|
||||
Serial.print("Clean the device ");
|
||||
Serial.println(device_id);
|
||||
|
||||
if (wifiClient.connect(HOST, 80))
|
||||
{
|
||||
String url = "/somfy_rts/mqtt_web_hook_public.php?service=clear_devices&device_id=" + device_id +
|
||||
"&mqtt_info=" + urlencode(mqtt_password);
|
||||
|
||||
wifiClient.print(String("GET ") + url + " HTTP/1.1\r\n" +
|
||||
"Host: " + HOST + "\r\n" +
|
||||
"Connection: close\r\n\r\n");
|
||||
|
||||
String line = wifiClient.readStringUntil('\r');
|
||||
// Serial.println(line);
|
||||
|
||||
// Read all the lines of the reply from server and print them to Serial
|
||||
while(wifiClient.available())
|
||||
{
|
||||
line = wifiClient.readStringUntil('\r');
|
||||
// Serial.print(line);
|
||||
}
|
||||
|
||||
Serial.print("The device \"");
|
||||
Serial.print(device_id);
|
||||
Serial.println("\" was deleted from the database.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("An error occurs while cleaning the device \"");
|
||||
Serial.print(device_id);
|
||||
Serial.print("\"");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String Somfy::urlencode(String str)
|
||||
{
|
||||
String encodedString="";
|
||||
char c;
|
||||
char code0;
|
||||
char code1;
|
||||
char code2;
|
||||
for (int i =0; i < str.length(); i++){
|
||||
c=str.charAt(i);
|
||||
if (c == ' '){
|
||||
encodedString+= '+';
|
||||
} else if (isalnum(c)){
|
||||
encodedString+=c;
|
||||
} else{
|
||||
code1=(c & 0xf)+'0';
|
||||
if ((c & 0xf) >9){
|
||||
code1=(c & 0xf) - 10 + 'A';
|
||||
}
|
||||
c=(c>>4)&0xf;
|
||||
code0=c+'0';
|
||||
if (c > 9){
|
||||
code0=c - 10 + 'A';
|
||||
}
|
||||
code2='\0';
|
||||
encodedString+='%';
|
||||
encodedString+=code0;
|
||||
encodedString+=code1;
|
||||
//encodedString+=code2;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
return encodedString;
|
||||
|
||||
}
|
||||
|
||||
unsigned char Somfy::h2int(char c)
|
||||
{
|
||||
if (c >= '0' && c <='9'){
|
||||
return((unsigned char)c - '0');
|
||||
}
|
||||
if (c >= 'a' && c <='f'){
|
||||
return((unsigned char)c - 'a' + 10);
|
||||
}
|
||||
if (c >= 'A' && c <='F'){
|
||||
return((unsigned char)c - 'A' + 10);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void Somfy::loopSerial() {
|
||||
|
||||
// Send Remote Control Request by Serial
|
||||
if (Serial.available() > 0) {
|
||||
digitalWrite(BUILTIN_LED, LOW);
|
||||
publish_timer.start();
|
||||
REMOTE currentRemote;
|
||||
char inByte[2];
|
||||
Serial.readBytes(inByte, 2);
|
||||
byte idx = inByte[1]-48;
|
||||
Serial.print((char)inByte[0]);
|
||||
char command = (char)inByte[0];
|
||||
Serial.print(command);
|
||||
|
||||
int nb_remotes = sizeof remotes/sizeof remotes[0];
|
||||
for (int i=0; i<nb_remotes; i++) {
|
||||
if (i == idx) {
|
||||
currentRemote = remotes[idx];
|
||||
}
|
||||
}
|
||||
Serial.println(idx);
|
||||
|
||||
if ( command == 'u' ) {
|
||||
Serial.println("Monte"); // Somfy is a French company, after all.
|
||||
BuildFrame(frame, HAUT, currentRemote);
|
||||
}
|
||||
else if ( command == 's' ) {
|
||||
Serial.println("Stop");
|
||||
BuildFrame(frame, STOP, currentRemote);
|
||||
}
|
||||
else if ( command == 'd' ) {
|
||||
Serial.println("Descend");
|
||||
BuildFrame(frame, BAS, currentRemote);
|
||||
}
|
||||
else if ( command == 'p' ) {
|
||||
Serial.println("Prog");
|
||||
BuildFrame(frame, PROG, currentRemote);
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
|
||||
SendCommand(frame, 2);
|
||||
for ( int i = 0; i<2; i++ ) {
|
||||
SendCommand(frame, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user