Zgateway srfb (#143)

* compatibility with sonoff rf bridge

#81

* update extract_char call
This commit is contained in:
Florian
2017-11-24 23:00:21 +01:00
committed by GitHub
parent 974d738212
commit af5e4e8ec9
6 changed files with 356 additions and 33 deletions

View File

@@ -135,7 +135,12 @@ void setup()
{
#ifdef ESP8266
//Launch serial for debugging purposes
Serial.begin(SERIAL_BAUD, SERIAL_8N1, SERIAL_TX_ONLY);
#ifdef ZgatewaySRFB
Serial.begin(SERIAL_BAUD); // in the case of sonoff RF Bridge the link to the RF emitter/receiver is made by serial and need TX/RX
#else
Serial.begin(SERIAL_BAUD, SERIAL_8N1, SERIAL_TX_ONLY);
#endif
//Begining wifi connection in case of ESP8266
setup_wifi();
// Port defaults to 8266
@@ -282,29 +287,28 @@ void loop()
#endif
// Receive loop, if data received by RF433 or IR send it by MQTT
#ifdef ZgatewayRF
boolean resultRF = RFtoMQTT();
if(resultRF)
if(RFtoMQTT())
trc(F("RFtoMQTT OK"));
#endif
#ifdef ZgatewayRF2
boolean resultRF2 = RF2toMQTT();
if(resultRF2)
if(RF2toMQTT())
trc(F("RF2toMQTT OK"));
#endif
#ifdef ZgatewaySRFB
if(SRFBtoMQTT())
trc(F("SRFBtoMQTT OK"));
#endif
#ifdef ZgatewayIR
boolean resultIR = IRtoMQTT();
if(resultIR)
if(IRtoMQTT())
trc(F("IRtoMQTT OK"));
delay(100);
#endif
#ifdef ZgatewayBT
boolean resultBT = BTtoMQTT();
if(resultBT)
if(BTtoMQTT())
trc(F("BTtoMQTT OK"));
#endif
#ifdef ZgatewayRFM69
boolean resultRFM69 = RFM69toMQTT();
if(resultRFM69)
if(RFM69toMQTT())
trc(F("RFM69toMQTT OK"));
#endif
}
@@ -373,6 +377,9 @@ void receivingMQTT(char * topicOri, char * datacallback) {
#ifdef ZgatewayRF2
MQTTtoRF2(topicOri, datacallback);
#endif
#ifdef ZgatewaySRFB
MQTTtoSRFB(topicOri, datacallback);
#endif
#ifdef ZgatewayIR
MQTTtoIR(topicOri, datacallback);
#endif
@@ -381,6 +388,35 @@ void receivingMQTT(char * topicOri, char * datacallback) {
#endif
}
void extract_char(char * token_char, char * subset, int start ,int l, boolean reverse, boolean isNumber){
char tmp_subset[l+1];
memcpy( tmp_subset, &token_char[start], l );
tmp_subset[l] = '\0';
if (isNumber){
char tmp_subset2[l+1];
if (reverse) revert_hex_data(tmp_subset, tmp_subset2, l+1);
else strncpy( tmp_subset2, tmp_subset , l+1);
long long_value = strtoul(tmp_subset2, NULL, 16);
sprintf(tmp_subset2, "%d", long_value);
strncpy( subset, tmp_subset2 , l+1);
}else{
if (reverse) revert_hex_data(tmp_subset, subset, l+1);
else strncpy( subset, tmp_subset , l+1);
}
}
void revert_hex_data(char * in, char * out, int l){
//reverting array 2 by 2 to get the data in good order
int i = l-2 , j = 0;
while ( i != -2 ) {
if (i%2 == 0) out[j] = in[i+1];
else out[j] = in[i-1];
j++;
i--;
}
out[l-1] = '\0';
}
//trace
void trc(String msg){
if (TRACE) {

View File

@@ -29,8 +29,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*----------------------------USER PARAMETERS-----------------------------*/
#define SERIAL_BAUD 115200
/*-------------DEFINE YOUR NETWORK PARAMETERS BELOW----------------*/
//MQTT Parameters definition
#define mqtt_server "192.168.1.17"
@@ -70,6 +68,8 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress
#define ZgatewayRF
#include "config_RF.h"
//#define ZgatewayRF2
//#define ZgatewaySRFB
//#include "config_SRFB.h"
#define ZgatewayIR
#include "config_IR.h"
#define ZgatewayBT
@@ -117,6 +117,12 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress
#endif
/*----------------------------OTHER PARAMETERS-----------------------------*/
/*-------------------CHANGING THEM IS NOT COMPULSORY-----------------------*/
/*----------------------------USER PARAMETERS-----------------------------*/
#ifdef ZgatewaySRFB
#define SERIAL_BAUD 19200
#else
#define SERIAL_BAUD 115200
#endif
/*--------------MQTT general topics-----------------*/
// global MQTT subject listened by the gateway to execute commands (send RF, IR or others)
#define subjectMQTTtoX "home/commands/#"

View File

@@ -83,7 +83,7 @@ boolean BTtoMQTT() {
for(int i =0; i<6;i++)
{
extract_char(token_char,d[i].extract,d[i].start, d[i].len ,d[i].reverse);
extract_char(token_char,d[i].extract,d[i].start, d[i].len ,d[i].reverse, false);
if (i == 3) d[5].len = (int)strtol(d[i].extract, NULL, 16) * 2; // extracting the length of the rest data
}
@@ -162,25 +162,6 @@ boolean process_miflora_data(char * rest_data, char * mac_adress){
return true;
}
void revert_hex_data(char * in, char * out, int l){
//reverting array 2 by 2 to get the data in good order
int i = l-2 , j = 0;
while ( i != -2 ) {
if (i%2 == 0) out[j] = in[i+1];
else out[j] = in[i-1];
j++;
i--;
}
out[l-1] = '\0';
}
void extract_char(char * token_char, char * subset, int start ,int l, boolean reverse){
char tmp_subset[l+1];
memcpy( tmp_subset, &token_char[start], l );
tmp_subset[l] = '\0';
if (reverse) revert_hex_data(tmp_subset, subset, l+1);
else strncpy( subset, tmp_subset , l+1);
}
#endif
#ifdef ZgatewayBT_stable

236
ZgatewaySRFB.ino Normal file
View File

@@ -0,0 +1,236 @@
/*
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:
- receive MQTT data from a topic and send RF 433Mhz signal corresponding to the received MQTT data using SONOFF RF BRIDGE
- publish MQTT data to a different topic related to received 433Mhz signal using SONOFF RF BRIDGE
This implementation into OpenMQTTGateway is based on Xose Pérez work ESPURNA (https://bitbucket.org/xoseperez/espurna)
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
OpenMQTTGateway integration by Florian ROBERT
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 <http://www.gnu.org/licenses/>.
*/
#ifdef ZgatewaySRFB
unsigned char _uartbuf[RF_MESSAGE_SIZE+3] = {0};
unsigned char _uartpos = 0;
void MQTTtoSRFB(char * topicOri, char * datacallback) {
// RF DATA ANALYSIS
String topic = topicOri;
if (topic == subjectMQTTtoSRFB){
int valueRPT = 0;
int valueMiniPLSL = 0;
int valueMaxiPLSL = 0;
int valueSYNC = 0;
int pos = topic.lastIndexOf(SRFBRptKey);
if (pos != -1){
pos = pos + +strlen(SRFBRptKey);
valueRPT = (topic.substring(pos,pos + 1)).toInt();
trc(F("SRFB Repeat:"));
trc(String(valueRPT));
}
int pos2 = topic.lastIndexOf(SRFBminipulselengthKey);
if (pos2 != -1) {
pos2 = pos2 + strlen(SRFBminipulselengthKey);
valueMiniPLSL = (topic.substring(pos2,pos2 + 3)).toInt();
trc(F("RF Mini Pulse Lgth:"));
trc(String(valueMiniPLSL));
}
int pos3 = topic.lastIndexOf(SRFBmaxipulselengthKey);
if (pos3 != -1){
pos3 = pos3 + strlen(SRFBmaxipulselengthKey);
valueMaxiPLSL = (topic.substring(pos3,pos3 + 2)).toInt();
trc(F("RF Maxi Pulse Lgth:"));
trc(String(valueMaxiPLSL));
}
int pos4 = topic.lastIndexOf(SRFBsyncKey);
if (pos4 != -1){
pos4 = pos4 + strlen(SRFBsyncKey);
valueSYNC = (topic.substring(pos4,pos4 + 2)).toInt();
trc(F("RF sync:"));
trc(String(valueSYNC));
}
trc(F("MQTTtoSRFB default prts"));
if (valueRPT == 0) valueRPT = 1;
if (valueMiniPLSL == 0) valueMiniPLSL = 320;
if (valueMaxiPLSL == 0) valueMaxiPLSL = 900;
if (valueSYNC == 0) valueSYNC = 9500;
byte hex_valueMiniPLSL[2];
hex_valueMiniPLSL[0] = (int)((valueMiniPLSL >> 8) & 0xFF) ;
hex_valueMiniPLSL[1] = (int)(valueMiniPLSL & 0xFF) ;
byte hex_valueMaxiPLSL[2];
hex_valueMaxiPLSL[0] = (int)((valueMaxiPLSL >> 8) & 0xFF) ;
hex_valueMaxiPLSL[1] = (int)(valueMaxiPLSL & 0xFF) ;
byte hex_valueSYNC[2];
hex_valueSYNC[0] = (int)((valueSYNC >> 8) & 0xFF) ;
hex_valueSYNC[1] = (int)(valueSYNC & 0xFF) ;
unsigned long data = strtoul(datacallback, NULL, 10); // we will not be able to pass values > 4294967295
byte hex_data[3];
hex_data[0] = (unsigned long)((data >> 16) & 0xFF) ;
hex_data[1] = (unsigned long)((data >> 8) & 0xFF) ;
hex_data[2] = (unsigned long)(data & 0xFF) ;
byte message_b[RF_MESSAGE_SIZE];
memcpy(message_b, hex_valueSYNC, 2);
memcpy(message_b + 2, hex_valueMiniPLSL, 2);
memcpy(message_b + 4, hex_valueMaxiPLSL, 2);
memcpy(message_b + 6, hex_data, 3);
_rfbSend(message_b, valueRPT);
// Acknowledgement to the GTWRF topic
boolean result = client.publish(subjectGTWSRFBtoMQTT, 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("MQTTtoSRFB ack pub."));
}
}
void _rfbSend(byte * message) {
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_RFOUT);
for (unsigned char j=0; j<RF_MESSAGE_SIZE; j++) {
Serial.write(message[j]);
}
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
}
void _rfbSend(byte * message, int times) {
char buffer[RF_MESSAGE_SIZE];
_rfbToChar(message, buffer);
trc("[RFBRIDGE] Sending MESSAGE '%s' %d time(s)\n");
for (int i=0; i<times; i++) {
if (i>0) {
unsigned long start = millis();
while (millis() - start < RF_SEND_DELAY) delay(1);
}
_rfbSend(message);
}
}
boolean SRFBtoMQTT() {
static bool receiving = false;
while (Serial.available()) {
yield();
byte c = Serial.read();
if (receiving) {
if (c == RF_CODE_STOP) {
_rfbDecode();
receiving = false;
} else {
_uartbuf[_uartpos++] = c;
}
} else if (c == RF_CODE_START) {
_uartpos = 0;
receiving = true;
}
}
return receiving;
}
void _rfbDecode() {
static unsigned long last = 0;
if (millis() - last < RF_RECEIVE_DELAY) return;
last = millis();
byte action = _uartbuf[0];
char buffer[RF_MESSAGE_SIZE * 2 + 1] = {0};
if (action == RF_CODE_RFIN) {
_rfbToChar(&_uartbuf[1], buffer);
client.publish(subjectSRFBtoMQTTRaw,buffer);
char val[7]= {0};
extract_char(buffer, val, 12 ,7, false,true);
client.publish(subjectSRFBtoMQTT,val);
char val_Tsyn[4]= {0};
extract_char(buffer, val_Tsyn, 0 ,4, false, true);
client.publish(subjectSRFBtoMQTTTsyn,val_Tsyn);
char val_Thigh[4]= {0};
extract_char(buffer, val_Thigh, 4 ,4, false, true);
client.publish(subjectSRFBtoMQTTThigh,val_Thigh);
char val_Tlow[4]= {0};
extract_char(buffer, val_Tlow, 8 ,4, false, true);
client.publish(subjectSRFBtoMQTTTlow,val_Tlow);
_rfbAck();
}
}
void _rfbAck() {
trc("[RFBRIDGE] Sending ACK\n");
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_ACK);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
}
/*
From an hexa char array ("A220EE...") to a byte array (half the size)
*/
bool _rfbToArray(const char * in, byte * out) {
if (strlen(in) != RF_MESSAGE_SIZE * 2) return false;
char tmp[3] = {0};
for (unsigned char p = 0; p<RF_MESSAGE_SIZE; p++) {
memcpy(tmp, &in[p*2], 2);
out[p] = strtol(tmp, NULL, 16);
}
return true;
}
/*
From a byte array to an hexa char array ("A220EE...", double the size)
*/
bool _rfbToChar(byte * in, char * out) {
for (unsigned char p = 0; p<RF_MESSAGE_SIZE; p++) {
sprintf_P(&out[p*2], PSTR("%02X"), in[p]);
}
return true;
}
#endif

62
config_SRFB.h Normal file
View File

@@ -0,0 +1,62 @@
/*
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 files enables to set your parameter for the radiofrequency gateway on sonoff rf bridge (ZgatewaySRFB)
This implementation is based on Xose Pérez work ESPURNA (https://bitbucket.org/xoseperez/espurna)
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
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 <http://www.gnu.org/licenses/>.
*/
/*-------------------RF topics & parameters----------------------*/
//433Mhz MQTT Subjects and keys
#define subjectMQTTtoSRFB "home/commands/MQTTtoSRFB"
#define subjectMQTTtoSRFBRaw "home/commands/MQTTtoSRFB/Raw"
#define subjectSRFBtoMQTTTsyn "home/SRFBtoMQTT/Tsyn"
#define subjectSRFBtoMQTTTlow "home/SRFBtoMQTT/Tlow"
#define subjectSRFBtoMQTTThigh "home/SRFBtoMQTT/Thigh"
#define subjectSRFBtoMQTT "home/SRFBtoMQTT"
#define subjectGTWSRFBtoMQTT "home/SRFBtoMQTT"
#define subjectSRFBtoMQTTRaw "home/SRFBtoMQTT/Raw"
#define SRFBRptKey "RPT_"
#define SRFBmaxipulselengthKey "Thigh_"
#define SRFBminipulselengthKey "Tlow_"
#define SRFBsyncKey "Tsyn_"
// -----------------------------------------------------------------------------
// RFBRIDGE
// -----------------------------------------------------------------------------
#define RF_SEND_TIMES 4 // How many times to send the message
#define RF_SEND_DELAY 500 // Interval between sendings in ms
#define RF_RECEIVE_DELAY 500 // Interval between recieving in ms (avoid debouncing)
// -----------------------------------------------------------------------------
// DEFINITIONS
// -----------------------------------------------------------------------------
#define RF_MESSAGE_SIZE 9
#define RF_CODE_START 0xAA
#define RF_CODE_ACK 0xA0
#define RF_CODE_RFIN 0xA4
#define RF_CODE_RFOUT 0xA5
#define RF_CODE_STOP 0x55

View File

@@ -69,6 +69,8 @@ const byte subnet[] = { 255, 255, 255, 0 }; //ip adress
#ifdef ESP8266 // for nodemcu, weemos and esp8266
#define ZgatewayRF
#include "config_RF.h"
#define ZgatewaySRFB
#include "config_SRFB.h"
#define ZgatewayRF2
#define ZgatewayIR
#include "config_IR.h"