Dateien nach "/" hochladen
This commit is contained in:
347
ZgatewayRF_RHASK.ino
Normal file
347
ZgatewayRF_RHASK.ino
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
- publish MQTT data to a different topic related to received 433Mhz signal
|
||||||
|
|
||||||
|
Copyright: (c)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 ZgatewayRF_RHASK
|
||||||
|
|
||||||
|
#include <RH_ASK.h>
|
||||||
|
#ifdef RH_HAVE_HARDWARE_SPI
|
||||||
|
#include <SPI.h> // Not actually used but needed to compile
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int RollingCounter = 0;
|
||||||
|
|
||||||
|
//RH_ASK driver(2000,RF_RECEIVER_PIN,RF_EMITTER_PIN);
|
||||||
|
RH_ASK driver(500,4,0);
|
||||||
|
|
||||||
|
void setupRF(){
|
||||||
|
//RF init parameters
|
||||||
|
Serial.println("Setup RF");
|
||||||
|
if (!driver.init())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
// #ifdef RH_HAVE_SERIAL
|
||||||
|
// trc(F("init failed"));
|
||||||
|
// #else
|
||||||
|
// ;
|
||||||
|
// trc(F("RF_EMITTER_PIN "));
|
||||||
|
// trc(RF_EMITTER_PIN);
|
||||||
|
// trc(F("RF_RECEIVER_PIN "));
|
||||||
|
// trc(RF_RECEIVER_PIN);
|
||||||
|
// trc(F("RF setup ok"));
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//uint8_t buf_Stored[RH_ASK_MAX_MESSAGE_LEN];
|
||||||
|
|
||||||
|
int RC_old;
|
||||||
|
void RFtoMQTT(){
|
||||||
|
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
|
||||||
|
uint8_t buflen = sizeof(buf);
|
||||||
|
|
||||||
|
if (driver.recv(buf, &buflen)) // Non-blocking
|
||||||
|
{
|
||||||
|
// Debug
|
||||||
|
String RFTopicDebug;
|
||||||
|
RFTopicDebug = "rf/sensors/";
|
||||||
|
char RFTopicCharDebug[50];
|
||||||
|
RFTopicDebug.toCharArray(RFTopicCharDebug,50);
|
||||||
|
// pubMQTT(RFTopicCharDebug,"Received Sth");
|
||||||
|
// Serial.println("Received sth");
|
||||||
|
// Debug End
|
||||||
|
|
||||||
|
|
||||||
|
int adressIn, parameterIn, RCin;
|
||||||
|
float payloadIn;
|
||||||
|
MessageDecrypt(buf, &adressIn, ¶meterIn, &payloadIn, &RCin);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
Serial.print("RC_in: ");Serial.println(RCin);
|
||||||
|
// Serial.print("Buf: ");Serial.println(buf);
|
||||||
|
Serial.print("Payload: ");Serial.println(payloadIn);
|
||||||
|
|
||||||
|
// debug
|
||||||
|
// trc("Adresse: ");trc(adressIn);
|
||||||
|
// trc("Parameter: ");trc(parameterIn);
|
||||||
|
// trc("Payload: ");trc(payloadIn);
|
||||||
|
// end debug
|
||||||
|
Log.notice(F("Message: %i" CR), adressIn);
|
||||||
|
Log.notice(F("Message: %i" CR), parameterIn);
|
||||||
|
Log.notice(F("Message: %i" CR), RCin);
|
||||||
|
|
||||||
|
|
||||||
|
// Compare old vs new value
|
||||||
|
bool newValue = false;
|
||||||
|
if ((!isAduplicateSignal((uint64_t)buf) || RCin != RC_old) && (unsigned long)buf != 0)
|
||||||
|
{
|
||||||
|
newValue = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// trc("Don't publish");
|
||||||
|
|
||||||
|
}
|
||||||
|
storeSignalValue((uint64_t)buf); // Store value to compare with new values
|
||||||
|
// Serial.print("RC in: ");Serial.print(RCin);Serial.print("RC old: ");Serial.println(RC_old);
|
||||||
|
RC_old = RCin;
|
||||||
|
|
||||||
|
if(newValue)
|
||||||
|
{
|
||||||
|
// match Sensor number in the array with sensor ID
|
||||||
|
int SensorNo;
|
||||||
|
bool FoundSensor = false;
|
||||||
|
for(SensorNo = 0;SensorNo<sizeof(RFSensorNames)/sizeof(RFSensorNames[0]);SensorNo++)
|
||||||
|
{
|
||||||
|
if(adressIn == RFSensorIDs[SensorNo])
|
||||||
|
{
|
||||||
|
FoundSensor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FoundSensor)
|
||||||
|
{
|
||||||
|
// trc(SensorNo);
|
||||||
|
// Publish topic
|
||||||
|
// Define topic name
|
||||||
|
String RFTopic;
|
||||||
|
RFTopic = "rf/sensors/" + RFSensorType[SensorNo] + "/" + RFSensorNames[SensorNo];
|
||||||
|
char RFTopicChar[50];
|
||||||
|
RFTopic.toCharArray(RFTopicChar,50);
|
||||||
|
|
||||||
|
// Publish matrix
|
||||||
|
pubMQTT(RFTopicChar,payloadIn);
|
||||||
|
// pub(subjectRFtoMQTT, RFdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// trc(F("Unkown sensor"));
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if (mySwitchBen.available()){
|
||||||
|
// unsigned long MQTTvalue = (unsigned long)mySwitchBen.getReceivedValue();
|
||||||
|
// mySwitchBen.resetAvailable();
|
||||||
|
// trc(F("Received sth"));
|
||||||
|
//
|
||||||
|
// if (!isAduplicate(MQTTvalue) && MQTTvalue!=0) {// conditions to avoid duplications of RF -->MQTT
|
||||||
|
// int adressIn, payloadIn, parameterIn;
|
||||||
|
// MessageDecrypt(MQTTvalue, &adressIn, ¶meterIn, &payloadIn);
|
||||||
|
// // match Sensor number in the array with sensor ID
|
||||||
|
// int SensorNo;
|
||||||
|
// bool FoundSensor = false;
|
||||||
|
// for(SensorNo = 0;SensorNo<sizeof(RFSensorNames)/sizeof(RFSensorNames[0]);SensorNo++)
|
||||||
|
// {
|
||||||
|
// if(adressIn == RFSensorIDs[SensorNo])
|
||||||
|
// {
|
||||||
|
// FoundSensor = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//// trc(SensorNo);
|
||||||
|
//
|
||||||
|
// // Define topic name
|
||||||
|
// String RFTopic;
|
||||||
|
// RFTopic = "rf/sensors/" + RFSensorType[SensorNo] + "/" + RFSensorNames[SensorNo];
|
||||||
|
//// trc(RFTopic);
|
||||||
|
// char RFTopicChar[50];
|
||||||
|
// RFTopic.toCharArray(RFTopicChar,50);
|
||||||
|
//
|
||||||
|
// // Publish matrix
|
||||||
|
// pub(RFTopicChar,payloadIn);
|
||||||
|
// trc(F("Store to avoid duplicate"));
|
||||||
|
// storeValue(MQTTvalue);
|
||||||
|
// if (repeatRFwMQTT){
|
||||||
|
// trc(F("Pub RF for rpt"));
|
||||||
|
// pub(subjectMQTTtoRF,MQTTvalue);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void MQTTtoRF(char * topicOri, char * datacallback) {
|
||||||
|
|
||||||
|
unsigned long data = strtoul(datacallback, NULL, 10); // we will not be able to pass values > 4294967295
|
||||||
|
String topic = topicOri;
|
||||||
|
//trc(F("Test"));
|
||||||
|
|
||||||
|
// Get the name of the target
|
||||||
|
String TargetName;
|
||||||
|
String ParameterName;
|
||||||
|
int posDivider = topic.lastIndexOf("/");
|
||||||
|
if(posDivider != -1)
|
||||||
|
{
|
||||||
|
ParameterName = topic.substring(posDivider+1);
|
||||||
|
String topicSubstring = topic.substring(0,posDivider);
|
||||||
|
posDivider = topicSubstring.lastIndexOf("/");
|
||||||
|
if(posDivider != -1)
|
||||||
|
TargetName = topicSubstring.substring(posDivider+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// trc(F("Target Name: "));
|
||||||
|
// trc(TargetName);
|
||||||
|
// trc(ParameterName);
|
||||||
|
|
||||||
|
// Get target number in array by sensor name
|
||||||
|
int TargetNo;
|
||||||
|
bool TargetFound = false;
|
||||||
|
for(TargetNo = 0;TargetNo<(sizeof(RFTargetNames)/sizeof(RFTargetNames[0]));TargetNo++)
|
||||||
|
{
|
||||||
|
if(RFTargetNames[TargetNo] == TargetName)
|
||||||
|
{
|
||||||
|
TargetFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trc(TargetNo);
|
||||||
|
|
||||||
|
|
||||||
|
if(TargetFound)
|
||||||
|
{
|
||||||
|
// find parameter ID
|
||||||
|
int ParId;
|
||||||
|
for(ParId=0;ParId<(sizeof(ParameterIds)/sizeof(ParameterIds[0]));ParId++)
|
||||||
|
{
|
||||||
|
if(ParameterIds[ParId] == ParameterName)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Search for target adress
|
||||||
|
|
||||||
|
byte MessageOut[8];
|
||||||
|
MessageEncrypt(RFTargetIDs[TargetNo], ParId, data, MessageOut);
|
||||||
|
for(int i=0;i<=RF_EMITTER_REPEAT;i++)
|
||||||
|
{
|
||||||
|
driver.send(MessageOut,8);
|
||||||
|
driver.waitPacketSent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MessageDecrypt(byte ByteArray[], int *adress, int *parameter, float *payload, int *RCin)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Serial.print("BytAr: ");Serial.println(ByteArray[0]);
|
||||||
|
|
||||||
|
*adress = (int)ByteArray[0];
|
||||||
|
// *parameter = (int)ByteArray[1];
|
||||||
|
|
||||||
|
byte arrayFloat[4];
|
||||||
|
// arrayFloat[0] = ByteArray[2];
|
||||||
|
// arrayFloat[1] = ByteArray[3];
|
||||||
|
// arrayFloat[2] = ByteArray[4];
|
||||||
|
// arrayFloat[3] = ByteArray[5];
|
||||||
|
|
||||||
|
arrayFloat[0] = ByteArray[1];
|
||||||
|
arrayFloat[1] = ByteArray[2];
|
||||||
|
arrayFloat[2] = ByteArray[3];
|
||||||
|
arrayFloat[3] = ByteArray[4];
|
||||||
|
|
||||||
|
// int i = arrayFloat[0] | (arrayFloat[1] << 8) | (arrayFloat[2] << 16) | (arrayFloat[3] << 24);
|
||||||
|
float testfloat;
|
||||||
|
testfloat = *((float*) (arrayFloat));
|
||||||
|
*payload = testfloat;
|
||||||
|
|
||||||
|
//testfloat = *((float*)(arrayFloat));
|
||||||
|
// Serial.print("Number: ");Serial.println(testfloat);
|
||||||
|
// Serial.print("Byte: ");Serial.println(arrayFloat[1]);
|
||||||
|
// byte CRCReceive = ByteArray[6];
|
||||||
|
|
||||||
|
// CRC Check
|
||||||
|
// byte CRCValue = CRC8(ByteArray, 6);
|
||||||
|
|
||||||
|
// bool CRCCheckOK = false;
|
||||||
|
// if(CRCValue == CRCReceive)
|
||||||
|
// {
|
||||||
|
// trc(F("CRC OK"));
|
||||||
|
// CRCCheckOK = true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// *RCin = (int)ByteArray[7];
|
||||||
|
*RCin = (int)ByteArray[5];
|
||||||
|
// Serial.print("RC in: ");Serial.println(RCin);
|
||||||
|
|
||||||
|
// Serial.println(messageInput[0]);
|
||||||
|
|
||||||
|
// return CRCCheckOK;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageEncrypt(int adressIn, int parameterIn, float payloadIn, byte pByteArray[])
|
||||||
|
{
|
||||||
|
// byte ByteArray[6];
|
||||||
|
pByteArray[0] = (byte)adressIn;
|
||||||
|
pByteArray[1] = (byte)parameterIn;
|
||||||
|
|
||||||
|
byte * payloadBArray = (byte *)&payloadIn;
|
||||||
|
pByteArray[2] = payloadBArray[0];
|
||||||
|
pByteArray[3] = payloadBArray[1];
|
||||||
|
pByteArray[4] = payloadBArray[2];
|
||||||
|
pByteArray[5] = payloadBArray[3];
|
||||||
|
|
||||||
|
// long l = *(long*) &payloadIn;
|
||||||
|
|
||||||
|
byte CRCValue = CRC8(pByteArray, 6);
|
||||||
|
pByteArray[6]= CRCValue;
|
||||||
|
|
||||||
|
RollingCounter = RollingCounter + 1;
|
||||||
|
if(RollingCounter > 2)
|
||||||
|
RollingCounter = 0;
|
||||||
|
|
||||||
|
pByteArray[7] = RollingCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CRC-8 - based on the CRC8 formulas by Dallas/Maxim
|
||||||
|
//code released under the therms of the GNU GPL 3.0 license
|
||||||
|
byte CRC8(const byte *data, byte len) {
|
||||||
|
byte crc = 0x00;
|
||||||
|
while (len--) {
|
||||||
|
byte extract = *data++;
|
||||||
|
for (byte tempI = 8; tempI; tempI--) {
|
||||||
|
byte sum = (crc ^ extract) & 0x01;
|
||||||
|
crc >>= 1;
|
||||||
|
if (sum) {
|
||||||
|
crc ^= 0x8C;
|
||||||
|
}
|
||||||
|
extract >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
70
config_RF_RHASK.h
Normal file
70
config_RF_RHASK.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*-------------------RF sensor + hardware settings----------------------*/
|
||||||
|
const int RFSensorIDs[] = {1,2,3,4,5,6,7};
|
||||||
|
const String RFSensorNames[] = {"RainSensor", "Humidity1", "RainSensor1", "LuxSensor1","MoistureSensor1","MoistureSensor_Test","Doorbell"};
|
||||||
|
const String RFSensorType[] = {"RainMass", "Humidity", "Rain", "Light","Moisture","Moisture","Door"};
|
||||||
|
const String RFSensorBaseName = "rf/sensors/";
|
||||||
|
const String RFTargetBaseName = "rf/target/";
|
||||||
|
|
||||||
|
const int RFTargetIDs[] = {5,6,7};
|
||||||
|
const String RFTargetNames[] = {"Light1","Light2","LED1"};
|
||||||
|
const String RFTargetType[] = {"Light", "Light","LED"};
|
||||||
|
const String ParameterIds[] = {"red","green","blue","brightness", "effect", "effectparameter"};
|
||||||
|
|
||||||
|
/*-------------------RF topics & parameters----------------------*/
|
||||||
|
//433Mhz MQTT Subjects and keys
|
||||||
|
#define subjectMQTTtoRF Base_Topic Gateway_Name "/commands/MQTTto433"
|
||||||
|
#define subjectRFtoMQTT Base_Topic Gateway_Name "/433toMQTT"
|
||||||
|
#define subjectGTWRFtoMQTT Base_Topic Gateway_Name "/433toMQTT"
|
||||||
|
#define RFprotocolKey "433_" // protocol will be defined if a subject contains RFprotocolKey followed by a value of 1 digit
|
||||||
|
#define RFbitsKey "RFBITS_" // bits will be defined if a subject contains RFbitsKey followed by a value of 2 digits
|
||||||
|
#define repeatRFwMQTT false // do we repeat a received signal by using mqtt with RF gateway
|
||||||
|
|
||||||
|
/*
|
||||||
|
RF supported protocols
|
||||||
|
433_1
|
||||||
|
433_2
|
||||||
|
433_3
|
||||||
|
433_4
|
||||||
|
433_5
|
||||||
|
433_6
|
||||||
|
*/
|
||||||
|
#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 3
|
||||||
|
|
||||||
|
/*-------------------RF2 topics & parameters----------------------*/
|
||||||
|
//433Mhz newremoteswitch MQTT Subjects and keys
|
||||||
|
#define subjectMQTTtoRF2 Base_Topic Gateway_Name "/commands/MQTTtoRF2"
|
||||||
|
#define subjectRF2toMQTT Base_Topic Gateway_Name "/RF2toMQTT"
|
||||||
|
#define subjectGTWRF2toMQTT Base_Topic Gateway_Name "/433toMQTT"
|
||||||
|
#define RF2codeKey "CODE_" // code will be defined if a subject contains RF2codeKey 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-2 digits
|
||||||
|
#define RF2groupKey "GROUP_" // number of your group value will be defined if a subject contains RF2groupKey followed by a value of 1 digit
|
||||||
|
#define RF2dimKey "DIM" // number of your dim value will be defined if a subject contains RF2dimKey and the payload contains the dim value as digits
|
||||||
|
|
||||||
|
/*-------------------ESPPiLight topics & parameters----------------------*/
|
||||||
|
//433Mhz Pilight MQTT Subjects and keys
|
||||||
|
#define subjectMQTTtoPilight Base_Topic Gateway_Name "/commands/MQTTtoPilight"
|
||||||
|
#define subjectPilighttoMQTT Base_Topic Gateway_Name "/PilighttoMQTT"
|
||||||
|
#define subjectGTWPilighttoMQTT Base_Topic Gateway_Name "/PilighttoMQTT"
|
||||||
|
#define PilightRAW "RAW"
|
||||||
|
|
||||||
|
/*-------------------PIN DEFINITIONS----------------------*/
|
||||||
|
//#ifdef ESP8266
|
||||||
|
// #define RF_RECEIVER_PIN 5 // D3 on nodemcu
|
||||||
|
// #define RF_EMITTER_PIN 4 // RX on nodemcu if it doesn't work with 3, try with 4 (D2)
|
||||||
|
//#elif ESP32
|
||||||
|
// #define RF_RECEIVER_PIN 13 // D13 on DOIT ESP32
|
||||||
|
// #define RF_EMITTER_PIN 12 // D12 on DOIT ESP32
|
||||||
|
//#elif __AVR_ATmega2560__
|
||||||
|
// #define RF_RECEIVER_PIN 1 //1 = D3 on mega
|
||||||
|
// #define RF_EMITTER_PIN 4
|
||||||
|
//#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 <library>IRremote/boarddefs.h so as to free pin D3 for RF RECEIVER PIN
|
||||||
|
// //RF PIN definition
|
||||||
|
// #define RF_RECEIVER_PIN 1 //1 = D3 on arduino
|
||||||
|
// #define RF_EMITTER_PIN 4 //4 = D4 on arduino
|
||||||
|
//#endif
|
||||||
Reference in New Issue
Block a user