Files
OpenMQTT-Gateway/main/ZgatewayPilight.ino
T
melyux fd2d25bf31 Add ability to specify repeats for raw Pilight strings (#803)
* Add ability to specify repeats for raw Pilight strings

* Updated RF Pilight doc to add raw transmission tut

Added information about transmitting raw messages using the MQTTtoPilight topic, including using the new repeats functionality. Fixed some scattered English mistakes.
2020-11-24 21:58:03 -05:00

179 lines
6.7 KiB
Arduino

/*
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 based on ESPilight library
- publish MQTT data to a different topic related to received 433Mhz signal based on ESPilight library
Copyright: (c)Florian ROBERT
Pilight Gateway made by steadramon, improvments with the help of puuu
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/>.
*/
#include "User_config.h"
#ifdef ZgatewayPilight
# ifdef ZradioCC1101
# include <ELECHOUSE_CC1101_SRC_DRV.h>
# endif
# include <ESPiLight.h>
ESPiLight rf(RF_EMITTER_GPIO); // use -1 to disable transmitter
void pilightCallback(const String& protocol, const String& message, int status,
size_t repeats, const String& deviceID) {
if (status == VALID) {
Log.trace(F("Creating RF PiLight buffer" CR));
StaticJsonBuffer<JSON_MSG_BUFFER> jsonBuffer;
JsonObject& RFPiLightdata = jsonBuffer.createObject();
StaticJsonBuffer<JSON_MSG_BUFFER> jsonBuffer2;
JsonObject& msg = jsonBuffer2.parseObject(message);
RFPiLightdata.set("message", msg);
RFPiLightdata.set("protocol", (char*)protocol.c_str());
RFPiLightdata.set("length", (char*)deviceID.c_str());
const char* device_id = deviceID.c_str();
if (!strlen(device_id)) {
// deviceID returned from Pilight is only extracted from id field
// but some device may use another name as unique identifier
char* choices[] = {"key", "unit", "device_id", "systemcode", "unitcode", "programcode"};
for (uint8_t i = 0; i < 6; i++) {
if (msg[choices[i]]) {
device_id = (const char*)msg[choices[i]];
break;
}
}
}
RFPiLightdata.set("value", device_id);
RFPiLightdata.set("repeats", (int)repeats);
RFPiLightdata.set("status", (int)status);
pub(subjectPilighttoMQTT, RFPiLightdata);
if (repeatPilightwMQTT) {
Log.trace(F("Pub Pilight for rpt" CR));
pub(subjectMQTTtoPilight, RFPiLightdata);
}
}
}
void setupPilight() {
# ifndef ZgatewayRF&& ZgatewayRF2 //receiving with Pilight is not compatible with ZgatewayRF or RF2 or RF315 as far as I can tell
# ifdef ZradioCC1101 //receiving with CC1101
ELECHOUSE_cc1101.Init();
ELECHOUSE_cc1101.setMHZ(CC1101_FREQUENCY);
ELECHOUSE_cc1101.SetRx(CC1101_FREQUENCY);
rf.enableReceiver();
# endif
rf.setCallback(pilightCallback);
rf.initReceiver(RF_RECEIVER_GPIO);
pinMode(RF_EMITTER_GPIO, OUTPUT); // Set this here, because if this is the RX pin it was reset to INPUT by Serial.end();
Log.notice(F("RF_EMITTER_GPIO: %d " CR), RF_EMITTER_GPIO);
Log.notice(F("RF_RECEIVER_GPIO: %d " CR), RF_RECEIVER_GPIO);
Log.trace(F("ZgatewayPilight setup done " CR));
# else
Log.trace(F("ZgatewayPilight setup cannot be done, comment first ZgatewayRF && ZgatewayRF2" CR));
# endif
}
void PilighttoMQTT() {
rf.loop();
}
void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) {
# ifdef ZradioCC1101
ELECHOUSE_cc1101.SetTx(CC1101_FREQUENCY); // set Transmit on
rf.disableReceiver();
# endif
if (cmpToMainTopic(topicOri, subjectMQTTtoPilight)) {
Log.trace(F("MQTTtoPilight json data analysis" CR));
const char* message = Pilightdata["message"];
const char* protocol = Pilightdata["protocol"];
const char* raw = Pilightdata["raw"];
if (raw) {
uint16_t codes[MAXPULSESTREAMLENGTH];
int repeats = rf.stringToRepeats(raw);
if (repeats < 0) {
switch (repeats) {
case ESPiLight::ERROR_INVALID_PULSETRAIN_MSG_R:
Log.trace(F("'r' not found in string, or has no data" CR));
break;
case ESPiLight::ERROR_INVALID_PULSETRAIN_MSG_END:
Log.trace(F("';' or '@' not found in data string" CR));
break;
}
repeats = 10;
}
int msgLength = rf.stringToPulseTrain(raw, codes, MAXPULSESTREAMLENGTH);
if (msgLength > 0) {
rf.sendPulseTrain(codes, msgLength, repeats);
Log.notice(F("MQTTtoPilight raw ok" CR));
} else {
Log.trace(F("MQTTtoPilight raw KO" CR));
switch (msgLength) {
case ESPiLight::ERROR_INVALID_PULSETRAIN_MSG_C:
Log.trace(F("'c' not found in string, or has no data" CR));
break;
case ESPiLight::ERROR_INVALID_PULSETRAIN_MSG_P:
Log.trace(F("'p' not found in string, or has no data" CR));
break;
case ESPiLight::ERROR_INVALID_PULSETRAIN_MSG_END:
Log.trace(F("';' or '@' not found in data string" CR));
break;
case ESPiLight::ERROR_INVALID_PULSETRAIN_MSG_TYPE:
Log.trace(F("pulse type not defined" CR));
break;
}
Log.error(F("Invalid JSON: raw data malformed" CR));
}
} else if (message && protocol) {
Log.trace(F("MQTTtoPilight msg & protocol ok" CR));
int msgLength = rf.send(protocol, message);
if (msgLength > 0) {
Log.trace(F("Adv data MQTTtoPilight push state via PilighttoMQTT" CR));
pub(subjectGTWPilighttoMQTT, Pilightdata);
} else {
switch (msgLength) {
case ESPiLight::ERROR_UNAVAILABLE_PROTOCOL:
Log.error(F("protocol is not available" CR));
break;
case ESPiLight::ERROR_INVALID_PILIGHT_MSG:
Log.error(F("message is invalid" CR));
break;
case ESPiLight::ERROR_INVALID_JSON:
Log.error(F("message is not a proper json object" CR));
break;
case ESPiLight::ERROR_NO_OUTPUT_PIN:
Log.error(F("no transmitter pin" CR));
break;
default:
Log.error(F("Invalid JSON: can't read message/protocol" CR));
}
}
} else {
Log.error(F("MQTTtoPilight failed json read" CR));
}
}
# ifdef ZradioCC1101
ELECHOUSE_cc1101.SetRx(CC1101_FREQUENCY); // set Receive on
rf.enableReceiver();
# endif
}
#endif