Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <WiFi.h>
- #include <PubSubClient.h>
- #include <DHT.h>
- #include <ESPmDNS.h>
- #include <WiFiUdp.h>
- #include <ArduinoOTA.h>
- #include <EEPROM.h>
- #define PORT_TX 32
- /*
- Value Button(s) Description
- 0x1 My Stop or move to favourite position
- 0x2 Up Move up
- 0x3 My + Up Set upper motor limit in initial programming mode
- 0x4 Down Move down
- 0x5 My + Down Set lower motor limit in initial programming mode
- 0x6 Up + Down Change motor limit and initial programming mode
- 0x8 Prog Used for (de-)registering remotes, see below
- 0x9 Sun + Flag Enable sun and wind detector (SUN and FLAG symbol on the Telis Soliris RC)
- 0xA Flag Disable sun detector (FLAG symbol on the Telis Instructor Excellence Award – Expert, čím sa zaradil medzi top 10 % najlepších inštruktorov na celom svete.Soliris RC)
- */
- #define SYMBOL 640
- #define HAUT 0x2
- #define STOP 0x1
- #define BAS 0x4
- #define PROG 0x8
- #define UPS 0x0E
- #define EEPROM_ADDRESS 0
- #define REMOTE 0x121110 //<-- Change it!
- const char* inTopic = "localcomm/esp32/cmd/+";
- const char* outTopic = "localcomm/esp32/data/roll/status";
- unsigned int newRollingCode = 1; //<-- Change it!
- unsigned int rollingCode = 0;
- byte frame[7];
- byte checksum;
- /*****************************************************
- * LED and doorbel settings
- ******************************************************/
- int LED_BUILTIN = 2;
- byte doorbel = 12;
- bool doorbel_status = false;
- /*****************************************************
- * MQTT settings
- * WIFI settings
- *****************************************************/
- const char* ssid = "w-eki";
- const char* password = "Ekino123";
- const char* mqttServer = "192.168.25.20";
- const int mqttPort = 1883;
- const char* mqttUser = "yourMQTTuser";
- const char* mqttPassword = "yourMQTTpassword";
- WiFiClient espClient;
- PubSubClient client(espClient);
- /*****************************************************
- * ESP32 DHT Reading
- * DHT Input
- *****************************************************/
- #define DHTPIN 33
- #define DHTTYPE DHT22
- DHT dht(DHTPIN, DHTTYPE);
- float localHum = 0;
- float localTemp = 0;
- char temp[35];
- char hum[35];
- /*****************************************************
- * Global settings
- *
- *****************************************************/
- int LoopCounter = 0;
- /***************************************************
- * Get indoor Temp/Hum data
- ****************************************************/
- void getDHT()
- {
- float tempIni = localTemp;
- float humIni = localHum;
- localTemp = dht.readTemperature();
- localHum = dht.readHumidity();
- if (isnan(localHum) || isnan(localTemp) || localHum > 100 || localTemp < 15) // Check if any reads failed and exit early (to try again).
- {
- localTemp = tempIni;
- localHum = humIni;
- return;
- }
- }
- void callback(char* topic, byte* payload, unsigned int length) {
- payload[length]='\0'; // Null terminator used to terminate the char array
- String message = (char*)payload;
- Serial.print("Message arrived on topic: [");
- Serial.print(topic);
- Serial.print("]: ");
- Serial.println(message);
- //get last part of topic
- char* cmnd = "test";
- char* cmnd_tmp=strtok(topic, "/");
- while(cmnd_tmp !=NULL) {
- cmnd=cmnd_tmp; //take over last not NULL string
- cmnd_tmp=strtok(NULL, "/"); //passing Null continues on string
- //Serial.println(cmnd_tmp);
- }
- if (!strcmp(cmnd, "control")) {
- if (message == "UP") {
- Serial.println("Received Somfy Up");
- BuildFrame(frame, HAUT);
- }
- if (message == "UPS") {
- Serial.println("Received Somfy Up");
- BuildFrame(frame, UPS);
- }
- else if (message == "DOWN") {
- Serial.println("Received Somfy Down");
- BuildFrame(frame, BAS);
- }
- else if (message == "STOP") {
- Serial.println("Received Somfy Stop");
- BuildFrame(frame, STOP);
- }
- else if (message == "PROG") {
- Serial.println("Received Somfy Prog");
- BuildFrame(frame, PROG);
- }
- //TODO add custom series as send over MQTT
- SendCommand(frame, 2);
- for(int i = 0; i<2; i++) {
- SendCommand(frame, 7);
- }
- sendSomfyStatus();
- }
- else if (!strcmp(cmnd, "reset")) {
- Serial.println("Received reset command");
- //ESP.reset();
- }
- else if (!strcmp(cmnd, "code")) {
- Serial.print("Received new code");
- unsigned int code;
- //get code from message
- code=message.toInt();
- Serial.println(code);
- //store in EEPROM and set global var
- EEPROM.put(EEPROM_ADDRESS, code);
- rollingCode=code;
- }
- else if (!strcmp(cmnd, "status")) {
- Serial.println("Printing status");
- sendSomfyStatus();
- }
- }
- void connect_mqtt()
- {
- while (!client.connected())
- {
- Serial.println("Connecting to MQTT...");
- if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
- Serial.println("connected to MQTT");
- }
- else
- {
- Serial.print("failed with state ");
- Serial.print(client.state());
- delay(2000);
- }
- }
- }
- void connect_wifi()
- {
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED)
- {
- delay(500);
- Serial.println("Connecting to WiFi..");
- }
- }
- void sendSomfyStatus() {
- char outTopic_status[50];
- char msg[50];
- //IP Address
- strcpy(outTopic_status,outTopic);
- strcat(outTopic_status,"ip_address");
- WiFi.localIP().toString().toCharArray(msg,50);
- client.publish(outTopic_status,msg );
- //Rolling Code
- strcpy(outTopic_status,outTopic);
- strcat(outTopic_status,"rolling_code");
- unsigned int code;
- EEPROM.get(EEPROM_ADDRESS, code);
- dtostrf(code,2,0,msg);
- client.publish(outTopic_status,msg );
- //Remote number
- strcpy(outTopic_status,outTopic);
- strcat(outTopic_status,"remote");
- dtostrf(REMOTE,2,0,msg);
- client.publish(outTopic_status,msg );
- }
- void setup()
- {
- pinMode(LED_BUILTIN, OUTPUT);
- pinMode(doorbel, INPUT_PULLUP);
- attachInterrupt(digitalPinToInterrupt(doorbel), doorbel_signal, RISING);
- Serial.begin(115200);
- connect_wifi();
- Serial.println("Connected to the WiFi network");
- client.setServer(mqttServer, mqttPort);
- connect_mqtt();
- client.subscribe("localcomm/esp32/cmd/+");
- Serial.println("Setting up DHT");
- dht.begin();
- pinMode(PORT_TX,OUTPUT);
- digitalWrite(PORT_TX,0);
- EEPROM.begin(512); //added Smo
- if (EEPROM.get(EEPROM_ADDRESS, rollingCode) < newRollingCode) {
- EEPROM.put(EEPROM_ADDRESS, newRollingCode);
- }
- //EEPROM.put(EEPROM_ADDRESS, newRollingCode); //only needed ONCE for init of EEPROM.
- Serial.print("Simulated remote number : "); Serial.println(REMOTE, HEX);
- Serial.print("Current rolling code : "); Serial.println(rollingCode);
- client.setCallback(callback);
- sendSomfyStatus();
- // OTA settings
- // Port defaults to 3232
- // ArduinoOTA.setPort(3232);
- // Hostname defaults to esp3232-[MAC]
- ArduinoOTA.setHostname("myesp32");
- // No authentication by default
- // ArduinoOTA.setPassword("admin");
- // Password can be set with it's md5 value as well
- // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
- // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
- ArduinoOTA
- .onStart([]() {
- String type;
- if (ArduinoOTA.getCommand() == U_FLASH)
- type = "sketch";
- else // U_SPIFFS
- type = "filesystem";
- // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
- Serial.println("Start updating " + type);
- })
- .onEnd([]() {
- Serial.println("\nEnd");
- })
- .onProgress([](unsigned int progress, unsigned int total) {
- Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
- })
- .onError([](ota_error_t error) {
- Serial.printf("Error[%u]: ", error);
- if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
- else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
- else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
- else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
- else if (error == OTA_END_ERROR) Serial.println("End Failed");
- });
- ArduinoOTA.begin();
- }
- void loop()
- {
- ArduinoOTA.handle();
- LoopCounter++;
- client.loop();
- getDHT();
- if (LoopCounter > 10)
- {
- if (!client.connected())
- {
- connect_mqtt();
- }
- if (WiFi.status() != WL_CONNECTED)
- {
- connect_wifi();
- }
- digitalWrite(LED_BUILTIN, HIGH);
- snprintf(temp,10,"%4g",localTemp);
- Serial.println(localTemp);
- snprintf(hum,10,"%4g",localHum);
- Serial.println(localHum);
- client.publish("localcomm/esp32/data/hum/status",hum);
- //delay(100);
- client.publish("localcomm/esp32/data/temp/status",temp);;
- LoopCounter = 0;
- digitalWrite(LED_BUILTIN, LOW);
- }
- if (doorbel_status){
- client.publish("localcomm/esp32/data/doorbel/status","ON");
- delay(1000);
- client.publish("localcomm/esp32/data/doorbel/status","OFF");
- doorbel_status = false;
- }
- delay(2000);
- }
- void doorbel_signal(){
- Serial.println("Interrupted");
- doorbel_status = true;
- }
- void BuildFrame(byte *frame, byte button) {
- unsigned int code;
- EEPROM.get(EEPROM_ADDRESS, code);
- Serial.print("Sending w/ rolling code : "); Serial.println(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 >> 16; // Remote address
- frame[5] = REMOTE >> 8; // Remote address
- frame[6] = REMOTE; // 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
- Serial.print("0"); // nibble is a 0.
- }
- Serial.print(frame[i],HEX); Serial.print(" ");
- }
- // Checksum calculation: a XOR of all the nibbles
- 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(EEPROM_ADDRESS, code + 1); // We store the value of the rolling code in the
- EEPROM.commit(); // EEPROM. It should take up to 2 adresses but the
- // Arduino function takes care of it.
- }
- void SendCommand(byte *frame, byte sync) {
- if(sync == 2) { // Only with the first frame.
- //Wake-up pulse & Silence
- //PORTD |= 1<<PORT_TX;
- //GPOS |= 1<<PORT_TX; //wrong usage anyway
- digitalWrite(PORT_TX,1);
- delayMicroseconds(9415);
- //PORTD &= !(1<<PORT_TX);
- //GPOS &= !(1<<PORT_TX);
- digitalWrite(PORT_TX,0);
- delayMicroseconds(89565);
- }
- // Hardware sync: two sync for the first frame, seven for the following ones.
- for (int i = 0; i < sync; i++) {
- //PORTD |= 1<<PORT_TX;
- //GPOS |= 1<<PORT_TX;
- digitalWrite(PORT_TX,1);
- delayMicroseconds(4*SYMBOL);
- //PORTD &= !(1<<PORT_TX);
- //GPOS &= !(1<<PORT_TX);
- digitalWrite(PORT_TX,0);
- delayMicroseconds(4*SYMBOL);
- }
- // Software sync
- //PORTD |= 1<<PORT_TX;
- //GPOS |= 1<<PORT_TX;
- digitalWrite(PORT_TX,1);
- delayMicroseconds(4550);
- //PORTD &= !(1<<PORT_TX);
- //GPOS &= !(1<<PORT_TX);
- digitalWrite(PORT_TX,0);
- 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) {
- //PORTD &= !(1<<PORT_TX);
- //GPOS &= !(1<<PORT_TX);
- digitalWrite(PORT_TX,0);
- delayMicroseconds(SYMBOL);
- //PORTD ^= 1<<5;
- //GPOS ^= 1<<5; //dont need to xor if I know state
- digitalWrite(PORT_TX,1);
- delayMicroseconds(SYMBOL);
- }
- else {
- //PORTD |= (1<<PORT_TX);
- //GPOS |= (1<<PORT_TX);
- digitalWrite(PORT_TX,1);
- delayMicroseconds(SYMBOL);
- //PORTD ^= 1<<5;
- //GPOS ^= 1<<5;
- digitalWrite(PORT_TX,0);
- delayMicroseconds(SYMBOL);
- }
- }
- //PORTD &= !(1<<PORT_TX);
- //GPOS &= !(1<<PORT_TX);
- digitalWrite(PORT_TX,0);
- delayMicroseconds(30415); // Inter-frame silence
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement