diff --git a/.gitmodules b/.gitmodules index 44ec0ce..bd9be51 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "libraries/RFM69"] path = libraries/RFM69 url = https://github.com/LowPowerLab/RFM69 +[submodule "libraries/NewRemoteSwitch"] + path = libraries/NewRemoteSwitch + url = https://github.com/1technophile/NewRemoteSwitch diff --git a/.travis.yml b/.travis.yml index 24ce2f9..e51d282 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ dist: trusty env: - BD=arduino:avr:uno - BD=arduino:avr:mega:cpu=atmega2560 - - BD=arduino:avr:nano:cpu=atmega328 - BD=esp8266:esp8266:nodemcuv2:CpuFrequency=80,FlashSize=4M3M - BD=esp8266:esp8266:d1_mini:CpuFrequency=80,FlashSize=4M3M before_install: @@ -22,6 +21,7 @@ install: - wget https://github.com/markszabo/IRremoteESP8266/archive/v2.1.1.zip -O /tmp/IRremoteESP8266.zip - unzip /tmp/IRremoteESP8266.zip -d /usr/local/share/arduino/libraries - git clone https://github.com/ekstrand/ESP8266wifi /usr/local/share/arduino/libraries/ESP8266wifi + - git clone https://github.com/1technophile/NewRemoteSwitch /usr/local/share/arduino/libraries/NewRemoteSwitch - wget https://github.com/knolleary/pubsubclient/archive/v2.6.zip -O /tmp/pubsubclient.zip - unzip /tmp/pubsubclient.zip -d /usr/local/share/arduino/libraries - wget https://github.com/sui77/rc-switch/archive/2.6.2.zip -O /tmp/rcswitch.zip diff --git a/OpenMQTTGateway.ino b/OpenMQTTGateway.ino index 246e6c7..3878778 100644 --- a/OpenMQTTGateway.ino +++ b/OpenMQTTGateway.ino @@ -75,18 +75,18 @@ unsigned long lastReconnectAttempt = 0; boolean reconnect() { // Loop until we're reconnected while (!client.connected()) { - trc(F("Attempting MQTT connection...")); //F function enable to decrease sram usage + trc(F("MQTT connection...")); //F function enable to decrease sram usage #ifdef mqtt_user if (client.connect(Gateway_Name, mqtt_user, mqtt_password, will_Topic, will_QoS, will_Retain, will_Message)) { // if an mqtt user is defined we connect to the broker with authentication #else if (client.connect(Gateway_Name, will_Topic, will_QoS, will_Retain, will_Message)) { #endif - trc(F("connected to broker")); + trc(F("Connected to broker")); // Once connected, publish an announcement... client.publish(will_Topic,Gateway_AnnouncementMsg,will_Retain); //Subscribing to topic if (client.subscribe(subjectMQTTtoX) && client.subscribe(subjectMultiGTWRF)&& client.subscribe(subjectMultiGTWIR)) { - trc(F("subscription OK to the subjects defined")); + trc(F("Subscription OK to the subjects")); } } else { trc(F("failed, rc=")); @@ -195,22 +195,22 @@ void setup_wifi() { IPAddress dns_adress(Dns); WiFi.begin(wifi_ssid, wifi_password); //WiFi.config(ip_adress,gateway_adress,subnet_adress); //Uncomment this line if you want to use advanced network config - trc(F("OpenMQTTGateway ip adress: ")); + trc(F("OpenMQTTGateway ip: ")); Serial.println(WiFi.localIP()); while (WiFi.status() != WL_CONNECTED) { delay(500); trc(F(".")); } - trc(F("WiFi connected")); + trc(F("WiFi ok")); } #else void setup_ethernet() { Ethernet.begin(mac, ip); //Comment and uncomment the following line if you want to use advanced network config //Ethernet.begin(mac, ip, Dns, gateway, subnet); - trc(F("OpenMQTTGateway ip adress: ")); + trc(F("OpenMQTTGateway ip: ")); Serial.println(Ethernet.localIP()); - trc(F("Ethernet connected")); + trc(F("Ethernet ok")); } #endif @@ -247,26 +247,24 @@ void loop() #ifdef ZgatewayRF boolean resultRF = RFtoMQTT(); if(resultRF) - trc(F("RF sent by MQTT")); + trc(F("RFtoMQTT OK")); #endif #ifdef ZgatewayIR boolean resultIR = IRtoMQTT(); if(resultIR) - trc(F("IR sent by MQTT")); + trc(F("IRtoMQTT OK")); delay(100); #endif #ifdef ZgatewayBT boolean resultBT = BTtoMQTT(); if(resultBT) - trc(F("BT sent by MQTT")); + trc(F("BTtoMQTT OK")); #endif #ifdef ZgatewayRFM69 boolean resultRFM69 = RFM69toMQTT(); if(resultRFM69) - trc(F("RFM69 data sent by MQTT")); - #endif - - + trc(F("RFM69toMQTT OK")); + #endif } } @@ -275,7 +273,7 @@ void storeValue(long MQTTvalue){ unsigned long now = millis(); // find oldest value of the buffer int o = getMin(); - trc(F("Min index: ")); + trc(F("Min ind: ")); trc(String(o)); // replace it by the new one ReceivedSignal[o][0] = MQTTvalue; @@ -309,7 +307,7 @@ for (int i = 0; i < array_size;i++){ if (ReceivedSignal[i][0] == value){ unsigned long now = millis(); if (now - ReceivedSignal[i][1] < time_avoid_duplicate){ // change - trc(F("---don't publish the code duplicate---")); + trc(F("--don't pub. duplicate--")); return true; } } @@ -330,13 +328,15 @@ void receivingMQTT(char * topicOri, char * datacallback) { #ifdef ZgatewayRF MQTTtoRF(topicOri, datacallback); #endif +#ifdef ZgatewayRF2 + MQTTtoRF2(topicOri, datacallback); +#endif #ifdef ZgatewayIR MQTTtoIR(topicOri, datacallback); #endif #ifdef ZgatewayRFM69 MQTTtoRFM69(topicOri, datacallback); #endif - } //trace diff --git a/User_config.h b/User_config.h index 3f9e5f4..c6fcd96 100644 --- a/User_config.h +++ b/User_config.h @@ -75,6 +75,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #ifdef ESP8266 // for nodemcu, weemos and esp8266 //#define ZsensorDHT #define ZgatewayRF + #define ZgatewayRF2 #ifdef RFM69_Wiring #define ZgatewayRFM69 #endif @@ -86,6 +87,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #endif #else // for arduino + W5100 #define ZgatewayRF + #define ZgatewayRF2 #ifdef RFM69_Wiring //#define ZgatewayRFM69 not tested #endif @@ -104,7 +106,7 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress #define subjectMQTTtoX "home/commands/#" #define subjectMultiGTWKey "toMQTT" -/*-------------------RF topics----------------------*/ +/*-------------------RF topics & parameters----------------------*/ //433Mhz MQTT Subjects and keys #define subjectMQTTtoRF "home/commands/MQTTto433" #define subjectRFtoMQTT "home/433toMQTT" @@ -127,8 +129,17 @@ RF supported protocols #define RFpulselengthKey "PLSL_" // pulselength will be defined if a subject contains RFprotocolKey followed by a value of 3 digits // subject monitored to listen traffic processed by other gateways to store data and avoid ntuple #define subjectMultiGTWRF "+/433toMQTT" +//RF number of signal repetition +#define RF_EMITTER_REPEAT 20 -/*-------------------IR topics----------------------*/ +/*-------------------RF2 topics & parameters----------------------*/ +//433Mhz newremoteswitch MQTT Subjects and keys +#define subjectMQTTtoRF2 "home/commands/MQTTtoRF2" +#define RF2codeKey "CODE_" // code will be defined if a subject contains RF2codeKeyrotocolKey followed by a value of 7 digits +#define RF2periodKey "PERIOD_" // period will be defined if a subject contains RF2periodKey followed by a value of 3 digits +#define RF2unitKey "UNIT_" // number of your unit value will be defined if a subject contains RF2unitKey followed by a value of 1 digit + +/*-------------------IR topics & parameters----------------------*/ //IR MQTT Subjects #define subjectGTWIRtoMQTT "home/IRtoMQTT" #define subjectIRtoMQTT "home/IRtoMQTT" @@ -171,8 +182,34 @@ RF supported protocols //#define IR_PANASONIC #endif -/*----------------------BT topics-------------------------*/ +/*----------------------BT topics & parameters-------------------------*/ #define subjectBTtoMQTT "home/BTtoMQTT/" +#define HM-10 +//#define HM-11 // uncomment this line if you use HM-11 and comment the line above + +/*----------------------RFM69 topics & parameters -------------------------*/ +#define subjectRFM69toMQTT "home/RFM69toMQTT" +#define subjectRFM69toMQTTrssi "home/RFM69toMQTT/rssi" +#define subjectRFM69toMQTTsender "home/RFM69toMQTT/sender" +#define subjectMQTTtoRFM69 "home/commands/MQTTtoRFM69" +#define RFM69receiverKey "RCV_" // receiver id will be defined if a subject contains RFM69receiverKey followed by a value of 3 digits +#define subjectGTWRFM69toMQTT "home/RFM69toMQTT" +#define defaultRFM69ReceiverId 99 + +// Default values +const char PROGMEM ENCRYPTKEY[] = "sampleEncryptKey"; +const char PROGMEM MDNS_NAME[] = "rfm69gw1"; +const char PROGMEM MQTT_BROKER[] = "raspi2"; +const char PROGMEM RFM69AP_NAME[] = "RFM69-AP"; +#define NETWORKID 200 //the same on all nodes that talk to each other +#define NODEID 10 + +//Match frequency to the hardware version of the radio +#define FREQUENCY RF69_433MHZ +//#define FREQUENCY RF69_868MHZ +//#define FREQUENCY RF69_915MHZ +#define IS_RFM69HCW true // set to 'true' if you are using an RFM69HCW module +#define POWER_LEVEL 31 /*----------------------RFM69 topics & parameters -------------------------*/ #define subjectRFM69toMQTT "home/RFM69toMQTT" @@ -208,14 +245,14 @@ const char PROGMEM RFM69AP_NAME[] = "RFM69-AP"; #define IR_EMITTER_PIN 16 // 16 = D0 on nodemcu #define only usefull for ESP8266 //RF PIN definition #define RF_RECEIVER_PIN 0 // 0 = D3 on nodemcu - #define BT_RX D7 //ESP8266 RX connect HM-10 TX - #define BT_TX D6 //ESP8266 TX connect HM-10 RX + #define BT_RX D7 //ESP8266 RX connect HM-10 or 11 TX + #define BT_TX D6 //ESP8266 TX connect HM-10 or 11 RX #else //IMPORTANT NOTE: On arduino UNO connect IR emitter pin to D9 , comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library IRremote/IRremoteInt.h so as to free pin D3 for RF RECEIVER PIN //RF PIN definition #define RF_RECEIVER_PIN 1 // 1 = D3 on arduino - #define BT_RX 5 //arduino RX connect HM-10 TX - #define BT_TX 6 //arduino TX connect HM-10 RX + #define BT_RX 5 //arduino RX connect HM-10 or 11 TX + #define BT_TX 6 //arduino TX connect HM-10 or 11 RX #endif #endif @@ -228,17 +265,29 @@ const char PROGMEM RFM69AP_NAME[] = "RFM69-AP"; #define IR_EMITTER_PIN 14 // 14 = D5 on nodemcu #define only usefull for ESP8266 //RF PIN definition #define RF_RECEIVER_PIN 5 // 5 = D1 on nodemcu - #define BT_RX D7 //ESP8266 RX connect HM-10 TX - #define BT_TX D6 //ESP8266 TX connect HM-10 RX + #define BT_RX D7 //ESP8266 RX connect HM-10 or 11 TX + #define BT_TX D6 //ESP8266 TX connect HM-10 or 11 RX #else //IMPORTANT NOTE: On arduino UNO connect IR emitter pin to D9 , comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library IRremote/IRremoteInt.h so as to free pin D3 for RF RECEIVER PIN //RF PIN definition #define RF_RECEIVER_PIN 1 // 1 = D3 on arduino - #define BT_RX 5 //arduino RX connect HM-10 TX - #define BT_TX 6 //arduino TX connect HM-10 RX + #define BT_RX 5 //arduino RX connect HM-10 or 11 TX + #define BT_TX 6 //arduino TX connect HM-10 or 11 RX #endif #endif +#ifdef RFM69_Wiring // Without Support for I2C Modules and HM10 or 11 + #define DHT_RECEIVER_PIN 0 //on nodeMCU this is D3 GPIO0 + #define IR_RECEIVER_PIN 2 // put 2 = D4 on nodemcu, 2 = D2 on arduino + + #ifdef ESP8266 + #define IR_EMITTER_PIN 16 // 16 = D0 on nodemcu + //RF PIN definition + #define RF_RECEIVER_PIN 0 // 0 = D3 on nodemcu + #define RF_EMITTER_PIN D2 //put D2 on nodemcu + #define RFM69_CS D1 // GPIO5/HCS/D1 + #define RFM69_IRQ D8 // GPIO15/D8 +======= #ifdef RFM69_Wiring // Without Support for I2C Modules #define DHT_RECEIVER_PIN 0 //on nodeMCU this is D3 GPIO0 #define IR_RECEIVER_PIN 2 // put 2 = D4 on nodemcu, 2 = D2 on arduino @@ -256,8 +305,11 @@ const char PROGMEM RFM69AP_NAME[] = "RFM69-AP"; //IMPORTANT NOTE: On arduino UNO connect IR emitter pin to D9 , comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library IRremote/IRremoteInt.h so as to free pin D3 for RF RECEIVER PIN //RF PIN definition #define RF_RECEIVER_PIN 1 // 1 = D3 on arduino - #define BT_RX 5 //arduino RX connect HM-10 TX - #define BT_TX 6 //arduino TX connect HM-10 RX + + #define RF_EMITTER_PIN 4 //4 = D4 on arduino + #define BT_RX 5 //arduino RX connect HM-10 or 11 TX + #define BT_TX 6 //arduino TX connect HM-10 or 11 RX + //RFM69 not tested with arduino #define RFM69_CS 10 #define RFM69_IRQ 2 #define RFM69_IRQN digitalPinToInterrupt(RFM69_IRQ) @@ -265,9 +317,11 @@ const char PROGMEM RFM69AP_NAME[] = "RFM69-AP"; #endif #endif + //RF number of signal repetition #define RF_EMITTER_REPEAT 20 + /*-------------------ACTIVATE TRACES----------------------*/ #define TRACE 1 // 0= trace off 1 = trace on diff --git a/ZgatewayIR.ino b/ZgatewayIR.ino index 26c37f3..d19e6ba 100644 --- a/ZgatewayIR.ino +++ b/ZgatewayIR.ino @@ -53,7 +53,7 @@ boolean IRtoMQTT(){ decode_results results; if (irrecv.decode(&results)){ - trc(F("Receiving IR")); + trc(F("Rcv. IR")); unsigned long MQTTvalue = 0; String MQTTprotocol; String MQTTbits; @@ -69,7 +69,7 @@ boolean IRtoMQTT(){ trc(rawCode); irrecv.resume(); // Receive the next value if (pubIRunknownPrtcl == false && MQTTprotocol == "-1"){ // don't publish unknown IR protocol - trc(F("---no publish unknown protocol---")); + trc(F("--no pub. unknown protocol--")); } else if (!isAduplicate(MQTTvalue) && MQTTvalue!=0) {// conditions to avoid duplications of RF -->MQTT trc(F("Adv data IRtoMQTT")); client.publish(subjectIRtoMQTTprotocol,(char *)MQTTprotocol.c_str()); @@ -80,7 +80,7 @@ boolean IRtoMQTT(){ trc(value); boolean result = client.publish(subjectIRtoMQTT,(char *)value.c_str()); if (repeatIRwMQTT){ - trc(F("Publishing IR for repeat")); + trc(F("Pub. IR for repeat")); client.publish(subjectMQTTtoIR,(char *)value.c_str()); } return result; @@ -163,7 +163,7 @@ void MQTTtoIR(char * topicOri, char * datacallback) { if (pos != -1){ pos = pos + +strlen(IRbitsKey); valueBITS = (topic.substring(pos,pos + 2)).toInt(); - trc(F("Bits number:")); + trc(F("Bits nb:")); trc(String(valueBITS)); } //We look into the subject to see if a special repeat number is defined @@ -256,7 +256,7 @@ void MQTTtoIR(char * topicOri, char * datacallback) { if (signalSent){ // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also boolean result = client.publish(subjectGTWIRtoMQTT, datacallback); if (result){ - trc(F("MQTTtoIR OK ack published")); + trc(F("MQTTtoIR ack pub.")); }; } irrecv.enableIRIn(); // ReStart the IR receiver (if not restarted it is not able to receive data) diff --git a/ZgatewayRF.ino b/ZgatewayRF.ino index e8c93b5..f1e8c67 100644 --- a/ZgatewayRF.ino +++ b/ZgatewayRF.ino @@ -43,7 +43,7 @@ void setupRF(){ boolean RFtoMQTT(){ if (mySwitch.available()){ - trc(F("Receiving RF")); + trc(F("Rcv. RF")); unsigned long MQTTvalue = 0; String MQTTprotocol; String MQTTbits; @@ -63,7 +63,7 @@ boolean RFtoMQTT(){ trc(value); boolean result = client.publish(subjectRFtoMQTT,(char *)value.c_str()); if (repeatRFwMQTT){ - trc(F("Publishing RF for repeat")); + trc(F("Publish RF for repeat")); client.publish(subjectMQTTtoRF,(char *)value.c_str()); } return result; @@ -94,7 +94,7 @@ void MQTTtoRF(char * topicOri, char * datacallback) { if (pos2 != -1) { pos2 = pos2 + strlen(RFpulselengthKey); valuePLSL = (topic.substring(pos2,pos2 + 3)).toInt(); - trc(F("RF Pulse Length:")); + trc(F("RF Pulse Lgth:")); trc(String(valuePLSL)); } int pos3 = topic.lastIndexOf(RFbitsKey); @@ -106,15 +106,15 @@ void MQTTtoRF(char * topicOri, char * datacallback) { } if ((topic == subjectMQTTtoRF) && (valuePRT == 0) && (valuePLSL == 0) && (valueBITS == 0)){ - trc(F("MQTTtoRF default")); + trc(F("MQTTtoRF dflt")); mySwitch.setProtocol(1,350); mySwitch.send(data, 24); // Acknowledgement to the GTWRF topic boolean result = client.publish(subjectGTWRFtoMQTT, datacallback); - if (result)trc(F("Ack published")); + if (result)trc(F("Ack pub.")); } else if ((valuePRT != 0) || (valuePLSL != 0)|| (valueBITS != 0)){ - trc(F("MQTTtoRF user parameters")); + trc(F("MQTTtoRF usr par.")); if (valuePRT == 0) valuePRT = 1; if (valuePLSL == 0) valuePLSL = 350; if (valueBITS == 0) valueBITS = 24; @@ -126,7 +126,7 @@ void MQTTtoRF(char * topicOri, char * datacallback) { // Acknowledgement to the GTWRF topic boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);// we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also if (result){ - trc(F("MQTTtoRF OK ack published")); + trc(F("MQTTtoRF ack pub.")); trc(String(data)); }; } diff --git a/ZgatewayRF2.ino b/ZgatewayRF2.ino new file mode 100644 index 0000000..cb20816 --- /dev/null +++ b/ZgatewayRF2.ino @@ -0,0 +1,98 @@ +/* + OpenMQTTGateway - ESP8266 or Arduino program for home automation + + Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker + Send and receiving command by MQTT + + This gateway enables to: + - publish MQTT data to a different topic related to received 433Mhz signal DIO/new kaku protocol + + Receiving cannot be used with this gateway as it is not currently compatible with pubsubclient, emitting can be used with both RF gateway on the same program. + Note that repeater and acknowledgement are not available with this gateway. + -->So as to know the code of your devices use ShowReceivedCode from https://github.com/1technophile/NewRemoteSwitch + + Copyright: (c)Florian ROBERT + Copyright: (c)Randy Simons http://randysimons.nl/ + + This file is part of OpenMQTTGateway. + + OpenMQTTGateway is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenMQTTGateway is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/*Command example for switching off: +sudo mosquitto_pub -t home/commands/MQTTtoRF2/CODE_8233372/UNIT_0/PERIOD_272 -m 0 +Command example for switching on: +sudo mosquitto_pub -t home/commands/MQTTtoRF2/CODE_8233372/UNIT_0/PERIOD_272 -m 1 +*/ + +#ifdef ZgatewayRF2 + +#include + +void MQTTtoRF2(char * topicOri, char * datacallback) { + + // RF DATA ANALYSIS + //We look into the subject to see if a special RF protocol is defined + String topic = topicOri; + bool boolSWITCHTYPE; + boolSWITCHTYPE = to_bool(datacallback); + + long valueCODE = 0; + int valueUNIT = -1; + int valuePERIOD = 0; + int valueBIT = 0; + + int pos = topic.lastIndexOf(RF2codeKey); + if (pos != -1){ + pos = pos + +strlen(RF2codeKey); + valueCODE = (topic.substring(pos,pos + 7)).toInt(); + trc(F("RF2 code:")); + trc(String(valueCODE)); + } + int pos2 = topic.lastIndexOf(RF2periodKey); + if (pos2 != -1) { + pos2 = pos2 + strlen(RF2periodKey); + valuePERIOD = (topic.substring(pos2,pos2 + 3)).toInt(); + trc(F("RF2 Period:")); + trc(String(valuePERIOD)); + } + int pos3 = topic.lastIndexOf(RF2unitKey); + if (pos3 != -1){ + pos3 = pos3 + strlen(RF2unitKey); + valueUNIT = (topic.substring(pos3,pos3 + 1)).toInt(); + trc(F("Unit:")); + trc(String(valueUNIT)); + } + + if ((topic == subjectMQTTtoRF2) || (valueCODE != 0) || (valueUNIT != -1)|| (valuePERIOD != 0)){ + trc(F("MQTTtoRF2")); + if (valueCODE == 0) valueCODE = 8233378; + if (valueUNIT == -1) valueUNIT = 0; + if (valuePERIOD == 0) valuePERIOD = 272; + trc(String(valueCODE)); + trc(String(valueUNIT)); + trc(String(valuePERIOD)); + trc(String(boolSWITCHTYPE)); + trc(F("Creating transmitter")); + NewRemoteTransmitter transmitter(valueCODE, RF_EMITTER_PIN, valuePERIOD); + trc(F("Sending data")); + transmitter.sendUnit(valueUNIT, boolSWITCHTYPE); + trc(F("Data sent")); + } +} + +bool to_bool(String const& s) { // thanks Chris Jester-Young from stackoverflow + return s != "0"; +} +#endif diff --git a/libraries/NewRemoteSwitch b/libraries/NewRemoteSwitch new file mode 160000 index 0000000..0e8e8ce --- /dev/null +++ b/libraries/NewRemoteSwitch @@ -0,0 +1 @@ +Subproject commit 0e8e8ce25adc504986069bf4d5c95cea4fc2b4f1