split main file so as to be able to load either RF either IR either both
This commit is contained in:
1 parent
a65e5fa595
commit
ec90b44360
9 files changed
+303
-1034
No files matched your search
@@ -1,63 +0,0 @@
|
||||
|
||||
|
||||
|
||||
void setupIR()
|
||||
{
|
||||
|
||||
//IR init parameters
|
||||
#ifdef ESP8266
|
||||
irsend.begin();
|
||||
#endif
|
||||
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void receivingMQTTIR(char * topicOri, char * datacallback) {
|
||||
|
||||
// IR DATA ANALYSIS
|
||||
//send received MQTT value by IR signal (example of signal sent data = 1086296175)
|
||||
boolean signalSent = false;
|
||||
#ifdef ESP8266 // send coolix not available for arduino IRRemote library
|
||||
if (topic.lastIndexOf("IR_COOLIX") != -1 ){
|
||||
irsend.sendCOOLIX(data, 24);
|
||||
signalSent = true;
|
||||
}
|
||||
#endif
|
||||
if (topic.lastIndexOf("IR_NEC")!= -1 || topic == subjectMQTTtoIR){
|
||||
irsend.sendNEC(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Whynter")!=-1){
|
||||
irsend.sendWhynter(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_LG")!=-1){
|
||||
irsend.sendLG(data, 28);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Sony")!=-1){
|
||||
irsend.sendSony(data, 12);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_DISH")!=-1){
|
||||
irsend.sendDISH(data, 16);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_RC5")!=-1){
|
||||
irsend.sendRC5(data, 12);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Sharp")!=-1){
|
||||
irsend.sendSharpRaw(data, 15);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_SAMSUNG")!=-1){
|
||||
irsend.sendSAMSUNG(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (signalSent){
|
||||
boolean result = client.publish(subjectGTWIRtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
}
|
||||
irrecv.enableIRIn(); // ReStart the IR receiver (if not restarted it is not able to receive data)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
|
||||
void setupRF()
|
||||
{
|
||||
|
||||
//RF init parameters
|
||||
mySwitch.enableTransmit(RF_EMITTER_PIN);
|
||||
mySwitch.setRepeatTransmit(RF_EMITTER_REPEAT);
|
||||
mySwitch.enableReceive(RF_RECEIVER_PIN);
|
||||
|
||||
}
|
||||
|
||||
void receivingMQTTRF(char * topicOri, char * datacallback) {
|
||||
String topic = topicOri;
|
||||
|
||||
trc(F("Receiving data by MQTT"));
|
||||
trc(topic);
|
||||
trc(F("Callback value"));
|
||||
trc(String(datacallback));
|
||||
unsigned long data = strtoul(datacallback, NULL, 10); // we will not be able to pass values > 4294967295
|
||||
trc(F("Converted value to unsigned long"));
|
||||
trc(String(data));
|
||||
|
||||
// Storing data received
|
||||
int pos0 = topic.lastIndexOf(subjectMultiGTWKey);
|
||||
if (pos0 != -1){
|
||||
trc(F("Storing signal"));
|
||||
storeValue(data);
|
||||
trc(F("Data stored"));
|
||||
}
|
||||
|
||||
// RF DATA ANALYSIS
|
||||
//We look into the subject to see if a special RF protocol is defined
|
||||
int valuePRT = 0;
|
||||
int valuePLSL = 0;
|
||||
int pos = topic.lastIndexOf(RFprotocolKey);
|
||||
if (pos != -1){
|
||||
pos = pos + +strlen(RFprotocolKey);
|
||||
valuePRT = (topic.substring(pos,pos + 1)).toInt();
|
||||
trc(F("RF Protocol number:"));
|
||||
trc(String(valuePRT));
|
||||
}
|
||||
//We look into the subject to see if a special RF pulselength is defined
|
||||
int pos2 = topic.lastIndexOf(RFpulselengthKey);
|
||||
if (pos2 != -1) {
|
||||
pos2 = pos2 + strlen(RFpulselengthKey);
|
||||
valuePLSL = (topic.substring(pos2,pos2 + 3)).toInt();
|
||||
trc(F("RF Pulse Length:"));
|
||||
trc(String(valuePLSL));
|
||||
}
|
||||
|
||||
if ((topic == subjectMQTTto433) && (valuePRT == 0) && (valuePLSL == 0)){
|
||||
trc(F("Sending data by RF, default parameters"));
|
||||
mySwitch.setProtocol(1,350);
|
||||
mySwitch.send(data, 24);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
|
||||
} else if ((valuePRT != 0) || (valuePLSL != 0)){
|
||||
trc(F("Sending data by RF, user defined parameters"));
|
||||
if (valuePRT == 0) valuePRT = 1;
|
||||
if (valuePLSL == 0) valuePLSL = 350;
|
||||
trc(String(valuePRT));
|
||||
trc(String(valuePLSL));
|
||||
mySwitch.setProtocol(valuePRT,valuePLSL);
|
||||
mySwitch.send(data, 24);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
}
|
||||
|
||||
}
|
||||
+26
-147
@@ -35,7 +35,6 @@ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT
|
||||
*/
|
||||
#include "User_config.h"
|
||||
#include <PubSubClient.h>
|
||||
#include <RCSwitch.h> // library for controling Radio frequency switch
|
||||
|
||||
// array to store previous received RFs, IRs codes and their timestamps
|
||||
unsigned long ReceivedSignal[10][2] ={{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
|
||||
@@ -44,24 +43,14 @@ unsigned long ReceivedSignal[10][2] ={{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
||||
//adding this to bypass the problem of the arduino builder issue 50
|
||||
void callback(char*topic, byte* payload,unsigned int length);
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <IRremoteESP8266.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
IRrecv irrecv(IR_RECEIVER_PIN);
|
||||
IRsend irsend(IR_EMITTER_PIN);
|
||||
WiFiClient eClient;
|
||||
#else
|
||||
#include <IRremote.h>
|
||||
#include <Ethernet.h>
|
||||
EthernetClient eClient;
|
||||
IRrecv irrecv(IR_RECEIVER_PIN);
|
||||
IRsend irsend; //connect IR emitter pin to D9 on arduino, you need to comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library IRremote.h so as to free pin D3 for RF RECEIVER PIN
|
||||
#endif
|
||||
|
||||
decode_results results;
|
||||
|
||||
// client parameters
|
||||
PubSubClient client(mqtt_server, mqtt_port, callback, eClient);
|
||||
|
||||
@@ -129,9 +118,13 @@ void setup()
|
||||
delay(1500);
|
||||
|
||||
lastReconnectAttempt = 0;
|
||||
|
||||
setupIR();
|
||||
setupRF();
|
||||
|
||||
#ifdef ZgatewayIR
|
||||
setupIR();
|
||||
#endif
|
||||
#ifdef ZgatewayRF
|
||||
setupRF();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -147,7 +140,7 @@ 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("OpenMQTTGateway ip adress: ");
|
||||
trc(F("OpenMQTTGateway ip adress: "));
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
@@ -160,7 +153,7 @@ void setup_wifi() {
|
||||
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("OpenMQTTGateway ip adress: ");
|
||||
trc(F("OpenMQTTGateway ip adress: "));
|
||||
Serial.println(Ethernet.localIP());
|
||||
trc(F("Ethernet connected"));
|
||||
}
|
||||
@@ -185,52 +178,21 @@ void loop()
|
||||
#ifdef ZsensorDHT
|
||||
MeasureTempAndHum(); //Addon to measure the temperature with a DHT
|
||||
#endif
|
||||
// Receive loop, if data received by RF433 or IR send it by MQTT
|
||||
if (mySwitch.available() || irrecv.decode(&results)) {
|
||||
boolean result = sendValuebyMQTT();
|
||||
if(result)
|
||||
trc(F("value successfully sent by MQTT"));
|
||||
}
|
||||
// Receive loop, if data received by RF433 or IR send it by MQTT
|
||||
#ifdef ZgatewayRF
|
||||
boolean resultRF = RFtoMQTT();
|
||||
if(resultRF)
|
||||
trc(F("RF successfully sent by MQTT"));
|
||||
#endif
|
||||
#ifdef ZgatewayIR
|
||||
boolean resultIR = IRtoMQTT();
|
||||
if(resultIR)
|
||||
trc(F("IR successfully sent by MQTT"));
|
||||
#endif
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
boolean sendValuebyMQTT(){
|
||||
// Topic on which we will send data
|
||||
trc(F("Receiving 433Mhz or IR signal"));
|
||||
unsigned long MQTTvalue = 0;
|
||||
if (mySwitch.available()||irrecv.decode(&results)){
|
||||
trc(F("Signal detected"));
|
||||
String subject;
|
||||
String valueAdvanced;
|
||||
String subjectAdvanced;
|
||||
if (mySwitch.available()){
|
||||
MQTTvalue = mySwitch.getReceivedValue();
|
||||
valueAdvanced = "Value " + String(MQTTvalue)+" Bit " + String(mySwitch.getReceivedBitlength()) + " Delay " + String(mySwitch.getReceivedDelay()) + " Protocol " + String(mySwitch.getReceivedProtocol());
|
||||
mySwitch.resetAvailable();
|
||||
subject = subject433toMQTT;
|
||||
subjectAdvanced = subject433toMQTTAdvanced;
|
||||
}else if (irrecv.decode(&results)){
|
||||
MQTTvalue=results.value;
|
||||
valueAdvanced = "Value " + String(MQTTvalue)+" Bit " + String(results.bits) + " Protocol " + String(results.decode_type);
|
||||
irrecv.resume(); // Receive the next value
|
||||
subject = subjectIRtoMQTT;
|
||||
subjectAdvanced = subjectIRtoMQTTAdvanced;
|
||||
}
|
||||
if (!isAduplicate(MQTTvalue) && MQTTvalue!=0) {// conditions to avoid duplications of RF -->MQTT
|
||||
trc(F("Sending advanced signal to MQTT"));
|
||||
client.publish((char *)subjectAdvanced.c_str(),(char *)valueAdvanced.c_str());
|
||||
trc(F("Sending signal to MQTT"));
|
||||
String value = String(MQTTvalue);
|
||||
trc(value);
|
||||
boolean result = client.publish((char *)subject.c_str(),(char *)value.c_str());
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void storeValue(long MQTTvalue){
|
||||
long now = millis();
|
||||
// find oldest value of the buffer
|
||||
@@ -295,98 +257,15 @@ void receivingMQTT(char * topicOri, char * datacallback) {
|
||||
storeValue(data);
|
||||
trc(F("Data stored"));
|
||||
}
|
||||
|
||||
// RF DATA ANALYSIS
|
||||
//We look into the subject to see if a special RF protocol is defined
|
||||
int valuePRT = 0;
|
||||
int valuePLSL = 0;
|
||||
int pos = topic.lastIndexOf(RFprotocolKey);
|
||||
if (pos != -1){
|
||||
pos = pos + +strlen(RFprotocolKey);
|
||||
valuePRT = (topic.substring(pos,pos + 1)).toInt();
|
||||
trc(F("RF Protocol number:"));
|
||||
trc(String(valuePRT));
|
||||
}
|
||||
//We look into the subject to see if a special RF pulselength is defined
|
||||
int pos2 = topic.lastIndexOf(RFpulselengthKey);
|
||||
if (pos2 != -1) {
|
||||
pos2 = pos2 + strlen(RFpulselengthKey);
|
||||
valuePLSL = (topic.substring(pos2,pos2 + 3)).toInt();
|
||||
trc(F("RF Pulse Length:"));
|
||||
trc(String(valuePLSL));
|
||||
}
|
||||
|
||||
if ((topic == subjectMQTTto433) && (valuePRT == 0) && (valuePLSL == 0)){
|
||||
trc(F("Sending data by RF, default parameters"));
|
||||
mySwitch.setProtocol(1,350);
|
||||
mySwitch.send(data, 24);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
|
||||
} else if ((valuePRT != 0) || (valuePLSL != 0)){
|
||||
trc(F("Sending data by RF, user defined parameters"));
|
||||
if (valuePRT == 0) valuePRT = 1;
|
||||
if (valuePLSL == 0) valuePLSL = 350;
|
||||
trc(String(valuePRT));
|
||||
trc(String(valuePLSL));
|
||||
mySwitch.setProtocol(valuePRT,valuePLSL);
|
||||
mySwitch.send(data, 24);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
}
|
||||
|
||||
// IR DATA ANALYSIS
|
||||
//send received MQTT value by IR signal (example of signal sent data = 1086296175)
|
||||
boolean signalSent = false;
|
||||
#ifdef ESP8266 // send coolix not available for arduino IRRemote library
|
||||
if (topic.lastIndexOf("IR_COOLIX") != -1 ){
|
||||
irsend.sendCOOLIX(data, 24);
|
||||
signalSent = true;
|
||||
}
|
||||
#endif
|
||||
if (topic.lastIndexOf("IR_NEC")!= -1 || topic == subjectMQTTtoIR){
|
||||
irsend.sendNEC(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Whynter")!=-1){
|
||||
irsend.sendWhynter(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_LG")!=-1){
|
||||
irsend.sendLG(data, 28);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Sony")!=-1){
|
||||
irsend.sendSony(data, 12);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_DISH")!=-1){
|
||||
irsend.sendDISH(data, 16);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_RC5")!=-1){
|
||||
irsend.sendRC5(data, 12);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Sharp")!=-1){
|
||||
irsend.sendSharpRaw(data, 15);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_SAMSUNG")!=-1){
|
||||
irsend.sendSAMSUNG(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (signalSent){
|
||||
boolean result = client.publish(subjectGTWIRtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
}
|
||||
irrecv.enableIRIn(); // ReStart the IR receiver (if not restarted it is not able to receive data)
|
||||
#ifdef ZgatewayRF
|
||||
MQTTtoRF(topicOri, datacallback);
|
||||
#endif
|
||||
#ifdef ZgatewayIR
|
||||
MQTTtoIR(topicOri, datacallback);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
//trace
|
||||
void trc(String msg){
|
||||
if (TRACE) {
|
||||
|
||||
+4
-3
@@ -52,9 +52,10 @@ const byte gateway[] = { 192, 168, 1, 1 }; //ip adress
|
||||
const byte Dns[] = { 192, 168, 1, 1 }; //ip adress
|
||||
const byte subnet[] = { 255, 255, 255, 0 }; //ip adress
|
||||
|
||||
//Addons management, comment the line if you don't use
|
||||
//#define ZaddonDHT true
|
||||
|
||||
//Addons and module management, comment the line if you don't use
|
||||
//#define ZsensorDHT
|
||||
#define ZgatewayRF
|
||||
#define ZgatewayIR
|
||||
/*----------------------------OTHER PARAMETERS-----------------------------*/
|
||||
/*-------------------CHANGING THEM IS NOT COMPULSORY-----------------------*/
|
||||
//variables to avoid duplicates for RF
|
||||
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
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 program enables to:
|
||||
- receive MQTT data from a topic and send RF 433Mhz signal corresponding to the received MQTT data
|
||||
- publish MQTT data to a different topic related to received 433Mhz signal
|
||||
- receive MQTT data from a topic and send IR signal corresponding to the received MQTT data
|
||||
- publish MQTT data to a different topic related to received IR signal
|
||||
|
||||
Copyright: (c)1technophile
|
||||
|
||||
Contributors:
|
||||
- 1technophile
|
||||
- crankyoldgit
|
||||
- Spudtater
|
||||
- rickybrent
|
||||
- ekim from Home assistant forum
|
||||
- ronvl from Home assistant forum
|
||||
|
||||
IMPORTANT NOTE: On arduino connect IR emitter pin to D9 , comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library <library>IRremote/IRremoteInt.h so as to free pin D3 for RF RECEIVER PIN
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifdef ZgatewayIR
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <IRremoteESP8266.h>
|
||||
IRrecv irrecv(IR_RECEIVER_PIN);
|
||||
IRsend irsend(IR_EMITTER_PIN);
|
||||
#else
|
||||
#include <IRremote.h>
|
||||
IRrecv irrecv(IR_RECEIVER_PIN);
|
||||
IRsend irsend; //connect IR emitter pin to D9 on arduino, you need to comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library IRremote.h so as to free pin D3 for RF RECEIVER PIN
|
||||
#endif
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setupIR()
|
||||
{
|
||||
//IR init parameters
|
||||
#ifdef ESP8266
|
||||
irsend.begin();
|
||||
#endif
|
||||
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
|
||||
}
|
||||
boolean IRtoMQTT(){
|
||||
unsigned long MQTTvalue = 0;
|
||||
String valueAdvanced;
|
||||
if (irrecv.decode(&results)){
|
||||
trc(F("Receiving IR signal"));
|
||||
MQTTvalue=results.value;
|
||||
valueAdvanced = "Value " + String(MQTTvalue)+" Bit " + String(results.bits) + " Protocol " + String(results.decode_type);
|
||||
irrecv.resume(); // Receive the next value
|
||||
if (!isAduplicate(MQTTvalue) && MQTTvalue!=0) {// conditions to avoid duplications of RF -->MQTT
|
||||
trc(F("Sending advanced signal to MQTT"));
|
||||
client.publish(subjectIRtoMQTTAdvanced,(char *)valueAdvanced.c_str());
|
||||
trc(F("Sending IR to MQTT"));
|
||||
String value = String(MQTTvalue);
|
||||
trc(value);
|
||||
boolean result = client.publish(subjectIRtoMQTT,(char *)value.c_str());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MQTTtoIR(char * topicOri, char * datacallback) {
|
||||
String topic = topicOri;
|
||||
|
||||
trc(F("Receiving data by MQTT"));
|
||||
trc(topic);
|
||||
trc(F("Callback value"));
|
||||
trc(String(datacallback));
|
||||
unsigned long data = strtoul(datacallback, NULL, 10); // we will not be able to pass values > 4294967295
|
||||
trc(F("Converted value to unsigned long"));
|
||||
trc(String(data));
|
||||
|
||||
// IR DATA ANALYSIS
|
||||
//send received MQTT value by IR signal (example of signal sent data = 1086296175)
|
||||
boolean signalSent = false;
|
||||
#ifdef ESP8266 // send coolix not available for arduino IRRemote library
|
||||
if (topic.lastIndexOf("IR_COOLIX") != -1 ){
|
||||
irsend.sendCOOLIX(data, 24);
|
||||
signalSent = true;
|
||||
}
|
||||
#endif
|
||||
if (topic.lastIndexOf("IR_NEC")!= -1 || topic == subjectMQTTtoIR){
|
||||
irsend.sendNEC(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Whynter")!=-1){
|
||||
irsend.sendWhynter(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_LG")!=-1){
|
||||
irsend.sendLG(data, 28);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Sony")!=-1){
|
||||
irsend.sendSony(data, 12);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_DISH")!=-1){
|
||||
irsend.sendDISH(data, 16);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_RC5")!=-1){
|
||||
irsend.sendRC5(data, 12);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_Sharp")!=-1){
|
||||
irsend.sendSharpRaw(data, 15);
|
||||
signalSent = true;
|
||||
}
|
||||
if (topic.lastIndexOf("IR_SAMSUNG")!=-1){
|
||||
irsend.sendSAMSUNG(data, 32);
|
||||
signalSent = true;
|
||||
}
|
||||
if (signalSent){
|
||||
boolean result = client.publish(subjectGTWIRtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
}
|
||||
irrecv.enableIRIn(); // ReStart the IR receiver (if not restarted it is not able to receive data)
|
||||
}
|
||||
#endif
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
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 program enables to:
|
||||
- receive MQTT data from a topic and send RF 433Mhz signal corresponding to the received MQTT data
|
||||
- publish MQTT data to a different topic related to received 433Mhz signal
|
||||
- receive MQTT data from a topic and send IR signal corresponding to the received MQTT data
|
||||
- publish MQTT data to a different topic related to received IR signal
|
||||
|
||||
Copyright: (c)1technophile
|
||||
|
||||
Contributors:
|
||||
- 1technophile
|
||||
- crankyoldgit
|
||||
- Spudtater
|
||||
- rickybrent
|
||||
- ekim from Home assistant forum
|
||||
- ronvl from Home assistant forum
|
||||
|
||||
IMPORTANT NOTE: On arduino connect IR emitter pin to D9 , comment #define IR_USE_TIMER2 and uncomment #define IR_USE_TIMER1 on library <library>IRremote/IRremoteInt.h so as to free pin D3 for RF RECEIVER PIN
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifdef ZgatewayRF
|
||||
|
||||
#include <RCSwitch.h> // library for controling Radio frequency switch
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
|
||||
void setupRF()
|
||||
{
|
||||
|
||||
//RF init parameters
|
||||
mySwitch.enableTransmit(RF_EMITTER_PIN);
|
||||
mySwitch.setRepeatTransmit(RF_EMITTER_REPEAT);
|
||||
mySwitch.enableReceive(RF_RECEIVER_PIN);
|
||||
|
||||
}
|
||||
|
||||
boolean RFtoMQTT(){
|
||||
unsigned long MQTTvalue = 0;
|
||||
String valueAdvanced;
|
||||
if (mySwitch.available()){
|
||||
trc(F("Receiving 433Mhz signal"));
|
||||
MQTTvalue = mySwitch.getReceivedValue();
|
||||
valueAdvanced = "Value " + String(MQTTvalue)+" Bit " + String(mySwitch.getReceivedBitlength()) + " Delay " + String(mySwitch.getReceivedDelay()) + " Protocol " + String(mySwitch.getReceivedProtocol());
|
||||
mySwitch.resetAvailable();
|
||||
if (!isAduplicate(MQTTvalue) && MQTTvalue!=0) {// conditions to avoid duplications of RF -->MQTT
|
||||
trc(F("Sending advanced signal to MQTT"));
|
||||
client.publish(subject433toMQTTAdvanced,(char *)valueAdvanced.c_str());
|
||||
trc(F("Sending RF to MQTT"));
|
||||
String value = String(MQTTvalue);
|
||||
trc(value);
|
||||
boolean result = client.publish(subject433toMQTT,(char *)value.c_str());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MQTTtoRF(char * topicOri, char * datacallback) {
|
||||
String topic = topicOri;
|
||||
|
||||
trc(F("Receiving data by MQTT"));
|
||||
trc(topic);
|
||||
trc(F("Callback value"));
|
||||
trc(String(datacallback));
|
||||
unsigned long data = strtoul(datacallback, NULL, 10); // we will not be able to pass values > 4294967295
|
||||
trc(F("Converted value to unsigned long"));
|
||||
trc(String(data));
|
||||
|
||||
// Storing data received
|
||||
int pos0 = topic.lastIndexOf(subjectMultiGTWKey);
|
||||
if (pos0 != -1){
|
||||
trc(F("Storing signal"));
|
||||
storeValue(data);
|
||||
trc(F("Data stored"));
|
||||
}
|
||||
|
||||
// RF DATA ANALYSIS
|
||||
//We look into the subject to see if a special RF protocol is defined
|
||||
int valuePRT = 0;
|
||||
int valuePLSL = 0;
|
||||
int pos = topic.lastIndexOf(RFprotocolKey);
|
||||
if (pos != -1){
|
||||
pos = pos + +strlen(RFprotocolKey);
|
||||
valuePRT = (topic.substring(pos,pos + 1)).toInt();
|
||||
trc(F("RF Protocol number:"));
|
||||
trc(String(valuePRT));
|
||||
}
|
||||
//We look into the subject to see if a special RF pulselength is defined
|
||||
int pos2 = topic.lastIndexOf(RFpulselengthKey);
|
||||
if (pos2 != -1) {
|
||||
pos2 = pos2 + strlen(RFpulselengthKey);
|
||||
valuePLSL = (topic.substring(pos2,pos2 + 3)).toInt();
|
||||
trc(F("RF Pulse Length:"));
|
||||
trc(String(valuePLSL));
|
||||
}
|
||||
|
||||
if ((topic == subjectMQTTto433) && (valuePRT == 0) && (valuePLSL == 0)){
|
||||
trc(F("Sending data by RF, default parameters"));
|
||||
mySwitch.setProtocol(1,350);
|
||||
mySwitch.send(data, 24);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
|
||||
} else if ((valuePRT != 0) || (valuePLSL != 0)){
|
||||
trc(F("Sending data by RF, user defined parameters"));
|
||||
if (valuePRT == 0) valuePRT = 1;
|
||||
if (valuePLSL == 0) valuePLSL = 350;
|
||||
trc(String(valuePRT));
|
||||
trc(String(valuePLSL));
|
||||
mySwitch.setProtocol(valuePRT,valuePLSL);
|
||||
mySwitch.send(data, 24);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFtoMQTT, datacallback);
|
||||
if (result)trc(F("Acknowedgement of reception published"));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
FanRemoteGPIO - Arduino libary to control a fan remote connected via GPIO pins.
|
||||
Copyright (c) 2017 Ricky Brent
|
||||
|
||||
Contributors:
|
||||
- Ricky Brent
|
||||
|
||||
Project home: https://github.com/rickybrent/fan-remote-gpio/
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
****************************************************/
|
||||
|
||||
#include "FanRemoteGPIO.h"
|
||||
|
||||
FanRemoteGPIO::FanRemoteGPIO() {
|
||||
this->lightPin = -1;
|
||||
this->lightPinOff = -1;
|
||||
this->fanPinFast = -1;
|
||||
this->fanPinMedium = -1;
|
||||
this->fanPinSlow = -1;
|
||||
this->fanPinOff = -1;
|
||||
this->nFanSpeed = 0;
|
||||
this->nBrightness = 0;
|
||||
this->nMaxBrightness = 3;
|
||||
this->bLightOn = false;
|
||||
this->bFanOn = false;
|
||||
this->looping = false;
|
||||
this->heldPin = -1;
|
||||
this->heldUntil = 0;
|
||||
this->queue = Queue<QueuedPress>(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a single light button and assign the pin.
|
||||
*
|
||||
* @param pin Arduino Pin to which the ligh button is connected to
|
||||
*/
|
||||
void FanRemoteGPIO::enableLight(int pin) {
|
||||
this->lightPin = pin;
|
||||
this->lightPinOff = -1;
|
||||
initPin(this->lightPin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable controlling the light, with separate pins for on and off.
|
||||
*
|
||||
* @param pinOn Arduino Pin to which the light on button is connected to
|
||||
* @param pinOff Arduino Pin to which the light off button is connected to
|
||||
*/
|
||||
void FanRemoteGPIO::enableLight(int pinOn, int pinOff) {
|
||||
this->lightPin = pinOn;
|
||||
this->lightPinOff = pinOff;
|
||||
initPin(this->lightPin);
|
||||
initPin(this->lightPinOff);
|
||||
// If we have an on and off button, we can guarentee the proper sync state:
|
||||
this->turnLight(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable controlling the light
|
||||
*/
|
||||
void FanRemoteGPIO::disableLight() {
|
||||
this->lightPin = -1;
|
||||
this->lightPinOff = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable controlling the fan speeds by separate pins per speed.
|
||||
*
|
||||
* @param pinFast Arduino Pin connected to the fast button
|
||||
* @param pinMedium Arduino Pin connected to the medium button
|
||||
* @param pinSlow Arduino Pin connected to the slow button
|
||||
* @param pinOff Arduino Pin connected to the off button
|
||||
*/
|
||||
void FanRemoteGPIO::enableFanSpeeds(int pinFast, int pinMedium, int pinSlow, int pinOff) {
|
||||
this->fanPinFast = pinFast;
|
||||
this->fanPinMedium = pinMedium;
|
||||
this->fanPinSlow = pinSlow;
|
||||
this->fanPinOff = pinOff;
|
||||
initPin(this->fanPinFast);
|
||||
initPin(this->fanPinMedium);
|
||||
initPin(this->fanPinSlow);
|
||||
initPin(this->fanPinOff);
|
||||
this->turnFan(false); // Easiest way to keep the real fan speed identical.
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable controlling the fan speeds
|
||||
*/
|
||||
void FanRemoteGPIO::disableFanSpeeds() {
|
||||
this->fanPinFast = -1;
|
||||
this->fanPinMedium = -1;
|
||||
this->fanPinSlow = -1;
|
||||
this->fanPinOff = -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the fan light brightness.
|
||||
* Ideally, this should track the brightness level, then adjust it by timing
|
||||
* how long the button is held down for. This is hard to get right.
|
||||
*/
|
||||
void FanRemoteGPIO::setBrightness(int level) {
|
||||
if (level == 0) {
|
||||
this->bLightOn = false;
|
||||
if (this->lightPinOff < 0) {
|
||||
press(this->lightPin);
|
||||
} else {
|
||||
press(this->lightPinOff);
|
||||
}
|
||||
} else if (level > 0) {
|
||||
this->bLightOn = true;
|
||||
// Visible changes at: 1600, 1800, 2000, 2200, 2400. Difficult to time
|
||||
// correctly matched with a level, and I rarely want the lights dimmed.
|
||||
this->nBrightness = level;
|
||||
press(this->lightPin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Power the light back on without attempting to change its brightness level.
|
||||
*/
|
||||
void FanRemoteGPIO::turnLight(bool on) {
|
||||
if (!on) {
|
||||
setBrightness(0);
|
||||
} else {
|
||||
this->nBrightness = this->nMaxBrightness;
|
||||
this->bLightOn = true;
|
||||
press(this->lightPin, 200);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fan light brightness.
|
||||
*/
|
||||
void FanRemoteGPIO::setSpeed(int speed) {
|
||||
if (speed == 0) {
|
||||
this->bFanOn = false;
|
||||
press(this->fanPinOff);
|
||||
} else {
|
||||
this->bFanOn = true;
|
||||
this->nFanSpeed = speed;
|
||||
if (speed == 1) {
|
||||
press(this->fanPinSlow);
|
||||
} else if (speed == 2) {
|
||||
press(this->fanPinMedium);
|
||||
} else if (speed == 3) {
|
||||
press(this->fanPinFast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Power the fan back on to its last set speed.
|
||||
*/
|
||||
void FanRemoteGPIO::turnFan(bool on) {
|
||||
if (!on) {
|
||||
setSpeed(0);
|
||||
} else {
|
||||
setSpeed(this->nFanSpeed > 0 ? this->nFanSpeed : 3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release any buttons being held down long enough.
|
||||
*/
|
||||
bool FanRemoteGPIO::available() {
|
||||
this->looping = true;
|
||||
if (this->heldPin >= 0 && this->heldUntil != 0 && this->heldUntil <= millis()) {
|
||||
digitalWrite(this->heldPin, HIGH);
|
||||
this->heldPin = -1;
|
||||
if ((queue.count()) > 0) {
|
||||
QueuedPress queued = queue.pop();
|
||||
press(queued.pin, queued.time);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int FanRemoteGPIO::getBrightness() {
|
||||
return ((this->bLightOn) ? this->nBrightness : 0);
|
||||
}
|
||||
|
||||
int FanRemoteGPIO::getSpeed() {
|
||||
return ((this->bFanOn) ? this->nFanSpeed : 0);
|
||||
}
|
||||
|
||||
bool FanRemoteGPIO::isLightOn() {
|
||||
return this->bLightOn;
|
||||
}
|
||||
|
||||
bool FanRemoteGPIO::isFanOn() {
|
||||
return this->bFanOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set pin to output and HIGH.
|
||||
*/
|
||||
void FanRemoteGPIO::initPin(int pin) {
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hold down the light button for the given ms. Useful for testing.
|
||||
*/
|
||||
void FanRemoteGPIO::holdLightButton(int time) {
|
||||
press(this->lightPin, time);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Press a button.
|
||||
*/
|
||||
void FanRemoteGPIO::press(int pin) {
|
||||
press(pin, 200); // Too long, and the light will begin adjusting brightness.
|
||||
}
|
||||
|
||||
/**
|
||||
* Press a button, hold for the specified time, then release.
|
||||
* @param pin Pin to press.
|
||||
* @param time Delay before releasing, in milliseconds.
|
||||
*/
|
||||
void FanRemoteGPIO::press(int pin, int time) {
|
||||
if (pin < 0)
|
||||
return;
|
||||
if (this->heldPin > -1) {
|
||||
struct QueuedPress queued;
|
||||
queued.pin = pin;
|
||||
queued.time = time;
|
||||
this->queue.push(queued);
|
||||
return;
|
||||
}
|
||||
digitalWrite(pin, LOW);
|
||||
if (this->looping) {
|
||||
this->heldPin = pin;
|
||||
this->heldUntil = millis() + time;
|
||||
} else {
|
||||
if (time > 0) delay(time);
|
||||
digitalWrite(pin, HIGH);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
FanRemoteGPIO - Arduino libary to control a fan remote connected via GPIO pins.
|
||||
Copyright (c) 2017 Ricky Brent
|
||||
|
||||
Contributors:
|
||||
- Ricky Brent
|
||||
|
||||
Project home: https://github.com/rickybrent/fan-remote-gpio/
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
****************************************************/
|
||||
|
||||
#ifndef FanRemoteGPIO_h
|
||||
#define FanRemoteGPIO_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "Queue.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
class FanRemoteGPIO
|
||||
{
|
||||
public:
|
||||
FanRemoteGPIO();
|
||||
void enableLight(int pin);
|
||||
void enableLight(int pinOn, int pinOff);
|
||||
void enableFanSpeeds(int pinFast, int pinMedium, int pinSlow, int pinOff);
|
||||
void disableLight();
|
||||
void disableFanSpeeds();
|
||||
void turnLight(bool on);
|
||||
void setBrightness(int brightness);
|
||||
void turnFan(bool on);
|
||||
void setSpeed(int speed);
|
||||
void holdLightButton(int time);
|
||||
int getBrightness();
|
||||
int getSpeed();
|
||||
bool isLightOn();
|
||||
bool isFanOn();
|
||||
bool available();
|
||||
private:
|
||||
void initPin(int pin);
|
||||
void press(int pin);
|
||||
void press(int pin, int time);
|
||||
int lightPin;
|
||||
int lightPinOff;
|
||||
int fanPinFast;
|
||||
int fanPinMedium;
|
||||
int fanPinSlow;
|
||||
int fanPinOff;
|
||||
int heldPin;
|
||||
unsigned long heldUntil;
|
||||
bool looping;
|
||||
bool bLightOn;
|
||||
bool bFanOn;
|
||||
uint8_t nBrightness;
|
||||
uint8_t nMaxBrightness;
|
||||
uint8_t nFanSpeed;
|
||||
struct QueuedPress {
|
||||
int pin;
|
||||
int time;
|
||||
};
|
||||
Queue<QueuedPress> queue;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,415 +0,0 @@
|
||||
/*
|
||||
433nIRtoMQTTto433nIR - ESP8266 program for home automation
|
||||
Tested OK on GeekCreek ESP12F
|
||||
Fan remote control tested OK on Wemos D1 Mini
|
||||
Not working on NodeMCU V0.9
|
||||
Act as a wifi gateway between your 433mhz/infrared IR signal and a MQTT broker
|
||||
Send and receiving command by MQTT
|
||||
|
||||
This program enables to:
|
||||
- receive MQTT data from a topic and send RF 433Mhz signal corresponding to the received MQTT data
|
||||
- publish MQTT data to a different topic related to received 433Mhz signal
|
||||
- receive MQTT data from a topic and send IR signal corresponding to the received MQTT data
|
||||
- publish MQTT data to a different topic related to received IR signal
|
||||
|
||||
Contributors:
|
||||
- 1technophile
|
||||
- crankyoldgit
|
||||
- rickybrent
|
||||
Based on:
|
||||
- MQTT library (https://github.com/knolleary)
|
||||
- RCSwitch (https://github.com/sui77/rc-switch)
|
||||
- ESP8266Wifi
|
||||
- IRremoteESP8266 (https://github.com/markszabo/IRremoteESP8266)
|
||||
|
||||
Project home: https://github.com/1technophile/433nIRtoMQTTto433nIR_ESP8266
|
||||
Blog, tutorial: http://1technophile.blogspot.com/2016/09/433nIRtomqttto433nIR-bidirectional-esp8266.html
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Some usefull commands to test gateway with mosquitto:
|
||||
Subscribe to the subject for data receiption from RF signal
|
||||
mosquitto_sub -t home/433toMQTT
|
||||
Send data by MQTT to convert it on RF signal
|
||||
mosquitto_pub -t home/MQTTto433/ -m 1315153
|
||||
*/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <RCSwitch.h> // library for controling Radio frequency switch
|
||||
#include <IRremoteESP8266.h>
|
||||
#include <FanRemoteGPIO.h> // library for controlling a fan remote via GPIO pins
|
||||
#include <pins_arduino.h>
|
||||
|
||||
RCSwitch mySwitch = RCSwitch();
|
||||
FanRemoteGPIO fanRemote = FanRemoteGPIO();
|
||||
|
||||
//TODO: Disabled IR] IRrecv irrecv(D3); // Untested. Moved from 2.
|
||||
//TODO: Disabled IR] IRsend irsend(D4); // Untested. Moved from 14.
|
||||
|
||||
decode_results results;
|
||||
|
||||
//Do we want to see trace for debugging purposes
|
||||
#define TRACE 1 // 0= trace off 1 = trace on
|
||||
|
||||
// Update these with values suitable for your network.
|
||||
#define wifi_ssid "mywifiid"
|
||||
#define wifi_password "mypwd"
|
||||
#define mqtt_server "192.168.0.22"
|
||||
#define mqtt_user "your_username" // not compulsory if you set it uncomment line 143 and comment line 145
|
||||
#define mqtt_password "your_password" // not compulsory if you set it uncomment line 143 and comment line 145
|
||||
|
||||
//variables to avoid duplicates for RF
|
||||
#define time_avoid_duplicate 3000 // if you want to avoid duplicate mqtt message received set this to > 0, the value is the time in milliseconds during which we don't publish duplicates
|
||||
// array to store previous received RFs codes and their timestamps
|
||||
long ReceivedRF[10][2] ={{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
|
||||
|
||||
#define subjectMQTTtoX "home/commands/#"
|
||||
//RF MQTT Subjects
|
||||
#define subject433toMQTT "home/433toMQTT"
|
||||
#define subjectMQTTto433 "home/commands/MQTTto433"
|
||||
//IR MQTT Subjects
|
||||
/*TODO: Disabled IR]
|
||||
#define subjectIRtoMQTT "home/sensors/ir"
|
||||
#define subjectMQTTtoIRCOOLIX "home/commands/sendCOOLIX"
|
||||
#define subjectMQTTtoIRWhynter "home/commands/sendWhynter"
|
||||
#define subjectMQTTtoIRNEC "home/commands/sendNEC"
|
||||
#define subjectMQTTtoIRLG "home/commands/sendLG"
|
||||
#define subjectMQTTtoIRSony "home/commands/sendSony"
|
||||
#define subjectMQTTtoIRDISH "home/commands/sendDISH"
|
||||
#define subjectMQTTtoIRSharp "home/commands/sendSharp"
|
||||
#define subjectMQTTtoIRPanasonic "home/commands/sendPanasonic"
|
||||
#define subjectMQTTtoIRSAMSUNG "home/commands/sendSAMSUNG"
|
||||
TODO: Disabled IR] */
|
||||
//Fan MQTT Subjects
|
||||
#define subjectMQTTtoFanSpeed "home/commands/MQTTtoFan/speed" // 0 to 3
|
||||
#define subjectMQTTtoFanBrightness "home/commands/MQTTtoFan/brightness" // 0 to 3
|
||||
#define subjectMQTTtoFanLight "home/commands/MQTTtoFan/light" // ON or OFF
|
||||
#define subjectMQTTtoFan "home/commands/MQTTtoFan/fan" // ON or OFF
|
||||
#define subjectMQTTtoFanHoldLight "home/commands/MQTTtoFan/holdLight"
|
||||
#define subjectFanToMQTT "home/FanToMQTT"
|
||||
|
||||
//adding this to bypass to problem of the arduino builder issue 50
|
||||
void callback(char*topic, byte* payload,unsigned int length);
|
||||
WiFiClient espClient;
|
||||
|
||||
// client parameters
|
||||
PubSubClient client(mqtt_server, 1883, callback, espClient);
|
||||
|
||||
//MQTT last attemps reconnection number
|
||||
long lastReconnectAttempt = 0;
|
||||
|
||||
// Callback function, when the gateway receive an MQTT value on the topics subscribed this function is called
|
||||
void callback(char* topic, byte* payload, unsigned int length) {
|
||||
// In order to republish this payload, a copy must be made
|
||||
// as the orignal payload buffer will be overwritten whilst
|
||||
// constructing the PUBLISH packet.
|
||||
trc("Hey I got a callback ");
|
||||
// Allocate the correct amount of memory for the payload copy
|
||||
byte* p = (byte*)malloc(length + 1);
|
||||
// Copy the payload to the new buffer
|
||||
memcpy(p,payload,length);
|
||||
|
||||
// Conversion to a printable string
|
||||
p[length] = '\0';
|
||||
String callbackstring = String((char *) p);
|
||||
String topicNameRec = String((char*) topic);
|
||||
|
||||
//launch the function to treat received data
|
||||
receivingMQTT(topicNameRec,callbackstring);
|
||||
|
||||
// Free the memory
|
||||
free(p);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
//Launch serial for debugging purposes
|
||||
Serial.begin(9600);
|
||||
|
||||
//Begining wifi connection
|
||||
setup_wifi();
|
||||
delay(1500);
|
||||
|
||||
lastReconnectAttempt = 0;
|
||||
|
||||
//IR init parameters
|
||||
//TODO: Disabled IR] irsend.begin();
|
||||
//TODO: Disabled IR] irrecv.enableIRIn(); // Start the receiver
|
||||
|
||||
//RF init parameters
|
||||
mySwitch.enableTransmit(D2); // RF Transmitter is connected to Pin D2
|
||||
mySwitch.setRepeatTransmit(20); //increase transmit repeat to avoid lost of rf sendings
|
||||
mySwitch.enableReceive(D1); // Receiver on pin D1
|
||||
|
||||
//FanRemote init parameters.
|
||||
fanRemote.enableFanSpeeds(D0, D5, D6, D7);
|
||||
fanRemote.enableLight(D4);
|
||||
}
|
||||
|
||||
void setup_wifi() {
|
||||
delay(10);
|
||||
// We start by connecting to a WiFi network
|
||||
trc("Connecting to ");
|
||||
trc(wifi_ssid);
|
||||
|
||||
WiFi.begin(wifi_ssid, wifi_password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
trc(".");
|
||||
}
|
||||
trc("WiFi connected");
|
||||
}
|
||||
|
||||
boolean reconnect() {
|
||||
// Loop until we're reconnected
|
||||
while (!client.connected()) {
|
||||
trc("Attempting MQTT connection...");
|
||||
// Attempt to connect
|
||||
// If you want to use a username and password, uncomment next line and comment the line if (client.connect("433toMQTTto433")) {
|
||||
//if (client.connect("433nIRtoMQTTto433nIR", mqtt_user, mqtt_password)) {
|
||||
// and set username and password at the program beginning
|
||||
if (client.connect("433nIRtoMQTTto433nIR")) {
|
||||
// Once connected, publish an announcement...
|
||||
client.publish("outTopic","hello world");
|
||||
publishFanState();
|
||||
trc("connected");
|
||||
//Subscribing to topic(s)
|
||||
subscribing(subjectMQTTtoX);
|
||||
} else {
|
||||
trc("failed, rc=");
|
||||
trc(String(client.state()));
|
||||
trc(" try again in 5 seconds");
|
||||
// Wait 5 seconds before retrying
|
||||
delay(5000);
|
||||
}
|
||||
}
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//MQTT client connexion management
|
||||
if (!client.connected()) {
|
||||
long now = millis();
|
||||
if (now - lastReconnectAttempt > 5000) {
|
||||
lastReconnectAttempt = now;
|
||||
trc("client mqtt not connected, trying to connect");
|
||||
// Attempt to reconnect
|
||||
if (reconnect()) {
|
||||
lastReconnectAttempt = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// MQTT loop
|
||||
client.loop();
|
||||
}
|
||||
|
||||
// Receive loop, if data received by RF433 send it by MQTT to subject433toMQTT
|
||||
if (mySwitch.available()) {
|
||||
// Topic on which we will send data
|
||||
trc("Receiving 433Mhz signal");
|
||||
unsigned long MQTTvalue;
|
||||
MQTTvalue=mySwitch.getReceivedValue();
|
||||
mySwitch.resetAvailable();
|
||||
if (client.connected()) {
|
||||
if (!isAduplicate(MQTTvalue)) {// conditions to avoid duplications of RF -->MQTT
|
||||
trc("Sending 433Mhz signal to MQTT");
|
||||
trc(String(MQTTvalue));
|
||||
sendMQTT(subject433toMQTT,String(MQTTvalue));
|
||||
storeValue(MQTTvalue);
|
||||
}
|
||||
} else {
|
||||
if (reconnect()) {
|
||||
trc("Sending 433Mhz signal to MQTT after reconnect");
|
||||
trc(String(MQTTvalue));
|
||||
sendMQTT(subject433toMQTT,String(MQTTvalue));
|
||||
storeValue(MQTTvalue);
|
||||
lastReconnectAttempt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive loop, if data received by IR send it by MQTT to subjectIRtoMQTT
|
||||
/*TODO: Disabled IR]
|
||||
if (irrecv.decode(&results)) {
|
||||
trc("Receiving IR signal");
|
||||
String MQTTvalue;
|
||||
MQTTvalue=results.value;
|
||||
trc("Sending IR signal to MQTT");
|
||||
trc(MQTTvalue);
|
||||
sendMQTT(subjectIRtoMQTT,MQTTvalue);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
TODO: Disabled IR] */
|
||||
|
||||
// Receive loop, check for data from fan remote and release held buttons.
|
||||
if (fanRemote.available()) {
|
||||
publishFanState();
|
||||
}
|
||||
|
||||
delay(100);
|
||||
|
||||
}
|
||||
|
||||
void storeValue(long MQTTvalue){
|
||||
long now = millis();
|
||||
// find oldest value of the buffer
|
||||
int o = getMin();
|
||||
trc("Minimum index: " + String(o));
|
||||
// replace it by the new one
|
||||
ReceivedRF[o][0] = MQTTvalue;
|
||||
ReceivedRF[o][1] = now;
|
||||
trc("send this code :" + String(ReceivedRF[o][0])+"/"+String(ReceivedRF[o][1]));
|
||||
trc("Col: value/timestamp");
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
trc(String(i) + ":" + String(ReceivedRF[i][0])+"/"+String(ReceivedRF[i][1]));
|
||||
}
|
||||
}
|
||||
|
||||
int getMin(){
|
||||
int minimum = ReceivedRF[0][1];
|
||||
int minindex=0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (ReceivedRF[i][1] < minimum) {
|
||||
minimum = ReceivedRF[i][1];
|
||||
minindex = i;
|
||||
}
|
||||
}
|
||||
return minindex;
|
||||
}
|
||||
|
||||
boolean isAduplicate(long value){
|
||||
trc("isAduplicate");
|
||||
// check if the value has been already sent during the last "time_avoid_duplicate"
|
||||
for (int i=0; i<10;i++){
|
||||
if (ReceivedRF[i][0] == value){
|
||||
long now = millis();
|
||||
if (now - ReceivedRF[i][1] < time_avoid_duplicate){
|
||||
trc("don't send this code :" + String(ReceivedRF[i][0])+"/"+String(ReceivedRF[i][1]));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void subscribing(String topicNameRec){ // MQTT subscribing to topic
|
||||
char topicStrRec[26];
|
||||
topicNameRec.toCharArray(topicStrRec,26);
|
||||
// subscription to topic for receiving data
|
||||
boolean pubresult = client.subscribe(topicStrRec);
|
||||
if (pubresult) {
|
||||
trc("subscription OK to");
|
||||
trc(topicNameRec);
|
||||
}
|
||||
}
|
||||
|
||||
void receivingMQTT(String topicNameRec, String callbackstring) {
|
||||
trc("Receiving data by MQTT");
|
||||
trc(topicNameRec);
|
||||
char topicOri[26] = "";
|
||||
char topicStrAck[26] = "";
|
||||
char datacallback[32] = "";
|
||||
// Acknowledgement inside a subtopic to avoid loop
|
||||
topicNameRec.toCharArray(topicOri,26);
|
||||
char DataAck[26] = "OK";
|
||||
client.publish("home/ack", DataAck);
|
||||
callbackstring.toCharArray(datacallback,32);
|
||||
trc(datacallback);
|
||||
unsigned long data = strtoul(datacallback, NULL, 10); // we will not be able to pass value > 4294967295
|
||||
trc(String(data));
|
||||
String topicNamePart = topicNameRec.substring(0, topicNameRec.lastIndexOf("/"));
|
||||
if (topicNameRec == subjectMQTTto433) {
|
||||
mySwitch.setProtocol(1); // default
|
||||
mySwitch.setPulseLength(350); // default
|
||||
trc("Send received data by RF 433");
|
||||
//send received MQTT value by RF signal (example of signal sent data = 5264660)
|
||||
mySwitch.send(data, 24);
|
||||
} else if (topicNamePart == subjectMQTTto433) {
|
||||
trc("Send received data by RF 433 with custom protocol/pulseLength");
|
||||
String s = topicNameRec.substring(topicNameRec.lastIndexOf("/") + 1);
|
||||
int sep = s.indexOf("-");
|
||||
mySwitch.setProtocol(s.substring(0, sep).toInt());
|
||||
mySwitch.setPulseLength(s.substring(sep + 1).toInt());
|
||||
mySwitch.send(data, 24);
|
||||
}
|
||||
/*TODO: Disabled IR]
|
||||
//send received MQTT value by IR signal (example of signal sent data = 1086296175)
|
||||
if (topicNameRec == subjectMQTTtoIRCOOLIX)
|
||||
irsend.sendCOOLIX(data, 24);
|
||||
if (topicNameRec == subjectMQTTtoIRWhynter)
|
||||
irsend.sendWhynter(data, 32);
|
||||
if (topicNameRec == subjectMQTTtoIRNEC)
|
||||
irsend.sendNEC(data, 32);
|
||||
if (topicNameRec == subjectMQTTtoIRLG)
|
||||
irsend.sendLG(data, 28);
|
||||
if (topicNameRec == subjectMQTTtoIRSony)
|
||||
irsend.sendSony(data, 12);
|
||||
if (topicNameRec == subjectMQTTtoIRDISH)
|
||||
irsend.sendDISH(data, 16);
|
||||
if (topicNameRec == subjectMQTTtoIRSharp)
|
||||
irsend.sendSharpRaw(data, 15);
|
||||
Panasonic has a two arguments per call. An address(16bit) and data(32bit), not data and nr_bits.
|
||||
if (topicNameRec == subjectMQTTtoIRPanasonic)
|
||||
irsend.sendPanasonic(data, 36);
|
||||
if (topicNameRec == subjectMQTTtoIRSAMSUNG)
|
||||
irsend.sendSAMSUNG(data, 32);
|
||||
TODO: Disabled IR] */
|
||||
//control attached fan remote control based on recieved MQTT values
|
||||
if (topicNameRec == subjectMQTTtoFanBrightness)
|
||||
fanRemote.setBrightness(data);
|
||||
if (topicNameRec == subjectMQTTtoFanLight)
|
||||
fanRemote.turnLight(((callbackstring == "ON") || data > 0) ? true : false);
|
||||
if (topicNameRec == subjectMQTTtoFan)
|
||||
fanRemote.turnFan(((callbackstring == "ON") || data > 0) ? true : false);
|
||||
if (topicNameRec == subjectMQTTtoFanSpeed)
|
||||
fanRemote.setSpeed(data);
|
||||
if (topicNameRec == subjectMQTTtoFanHoldLight)
|
||||
fanRemote.holdLightButton(data);
|
||||
|
||||
}
|
||||
|
||||
//send MQTT data dataStr to topic topicNameSend
|
||||
void sendMQTT(String topicNameSend, String dataStr){
|
||||
|
||||
char topicStrSend[26];
|
||||
topicNameSend.toCharArray(topicStrSend,26);
|
||||
char dataStrSend[200];
|
||||
dataStr.toCharArray(dataStrSend,200);
|
||||
boolean pubresult = client.publish(topicStrSend,dataStrSend);
|
||||
trc("sending ");
|
||||
trc(dataStr);
|
||||
trc("to ");
|
||||
trc(topicNameSend);
|
||||
|
||||
}
|
||||
|
||||
// function called to publish the state of the fan
|
||||
void publishFanState() {
|
||||
String json = String("{\"brightness\":") + fanRemote.getBrightness() + ","
|
||||
" \"speed\":" + fanRemote.getSpeed() + ","
|
||||
" \"light\":\"" + (fanRemote.isLightOn() ? "ON" : "OFF") + "\","
|
||||
" \"fan\":\"" + (fanRemote.isFanOn() ? "ON" : "OFF") + "\""
|
||||
"}";
|
||||
const char * msg = json.c_str();
|
||||
client.publish(subjectFanToMQTT, msg, true);
|
||||
}
|
||||
|
||||
//trace
|
||||
void trc(String msg){
|
||||
if (TRACE) {
|
||||
Serial.println(msg);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user