mirror of https://github.com/arendst/Tasmota.git
parent
bea3174ec8
commit
8875787935
|
@ -28,8 +28,17 @@
|
||||||
|
|
||||||
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_SYNTAX_IRHVAC };
|
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_SYNTAX_IRHVAC };
|
||||||
|
|
||||||
enum IrRemoteCommands { CMND_IRSEND, CMND_IRHVAC };
|
const char kIrRemoteCommands[] PROGMEM =
|
||||||
const char kIrRemoteCommands[] PROGMEM = D_CMND_IRSEND "|" D_CMND_IRHVAC ;
|
#ifdef USE_IR_HVAC
|
||||||
|
D_CMND_IRHVAC "|"
|
||||||
|
#endif
|
||||||
|
D_CMND_IRSEND ;
|
||||||
|
|
||||||
|
void (* const IrRemoteCommand[])(void) PROGMEM = {
|
||||||
|
#ifdef USE_IR_HVAC
|
||||||
|
&CmndIrHvac,
|
||||||
|
#endif
|
||||||
|
&CmndIrSend };
|
||||||
|
|
||||||
// Based on IRremoteESP8266.h enum decode_type_t
|
// Based on IRremoteESP8266.h enum decode_type_t
|
||||||
static const uint8_t MAX_STANDARD_IR = SHARP; // this is the last code mapped to decode_type_t
|
static const uint8_t MAX_STANDARD_IR = SHARP; // this is the last code mapped to decode_type_t
|
||||||
|
@ -46,22 +55,6 @@ const char kIrRemoteProtocols[] PROGMEM =
|
||||||
#endif // USE_IR_SEND_PIONEER
|
#endif // USE_IR_SEND_PIONEER
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC
|
|
||||||
|
|
||||||
#include <ir_Mitsubishi.h>
|
|
||||||
#include <ir_Fujitsu.h>
|
|
||||||
|
|
||||||
enum IrHvacVendors {
|
|
||||||
VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU, VNDR_MIDEA };
|
|
||||||
const char kIrHvacVendors[] PROGMEM =
|
|
||||||
"Toshiba|Mitsubishi|LG|Fujitsu|Midea" ;
|
|
||||||
|
|
||||||
IRMitsubishiAC *mitsubir = nullptr;
|
|
||||||
|
|
||||||
const char kFanSpeedOptions[] = "A12345S";
|
|
||||||
const char kHvacModeOptions[] = "HDCA";
|
|
||||||
#endif // USE_IR_HVAC
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* IR Send
|
* IR Send
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -75,10 +68,6 @@ void IrSendInit(void)
|
||||||
{
|
{
|
||||||
irsend = new IRsend(pin[GPIO_IRSEND]); // an IR led is at GPIO_IRSEND
|
irsend = new IRsend(pin[GPIO_IRSEND]); // an IR led is at GPIO_IRSEND
|
||||||
irsend->begin();
|
irsend->begin();
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC
|
|
||||||
mitsubir = new IRMitsubishiAC(pin[GPIO_IRSEND]);
|
|
||||||
#endif //USE_IR_HVAC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* IrUint64toHex(uint64_t value, char *str, uint16_t bits)
|
char* IrUint64toHex(uint64_t value, char *str, uint16_t bits)
|
||||||
|
@ -102,6 +91,7 @@ char* IrUint64toHex(uint64_t value, char *str, uint16_t bits)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_IR_RECEIVE
|
#ifdef USE_IR_RECEIVE
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* IR Receive
|
* IR Receive
|
||||||
|
@ -202,15 +192,22 @@ void IrReceiveCheck(void)
|
||||||
}
|
}
|
||||||
#endif // USE_IR_RECEIVE
|
#endif // USE_IR_RECEIVE
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC
|
#ifdef USE_IR_HVAC
|
||||||
/********************************************************************************************* \
|
/*********************************************************************************************\
|
||||||
* IR Heating, Ventilation and Air Conditioning using IRMitsubishiAC library
|
* IR Heating, Ventilation and Air Conditioning
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
enum IrHvacVendors { VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU, VNDR_MIDEA };
|
||||||
|
const char kIrHvacVendors[] PROGMEM = "Toshiba|Mitsubishi|LG|Fujitsu|Midea" ;
|
||||||
|
|
||||||
|
const char kFanSpeedOptions[] = "A12345S";
|
||||||
|
const char kHvacModeOptions[] = "HDCA";
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC_TOSHIBA
|
#ifdef USE_IR_HVAC_TOSHIBA
|
||||||
/*******************
|
/*-------------------------------------------------------------------------------------------*\
|
||||||
TOSHIBA
|
* Toshiba
|
||||||
********************/
|
\*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
const uint16_t HVAC_TOSHIBA_HDR_MARK = 4400;
|
const uint16_t HVAC_TOSHIBA_HDR_MARK = 4400;
|
||||||
const uint16_t HVAC_TOSHIBA_HDR_SPACE = 4300;
|
const uint16_t HVAC_TOSHIBA_HDR_SPACE = 4300;
|
||||||
|
@ -303,7 +300,6 @@ uint8_t IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
|
||||||
rawdata[i++] = HVAC_TOSHIBA_RPT_SPACE;
|
rawdata[i++] = HVAC_TOSHIBA_RPT_SPACE;
|
||||||
|
|
||||||
// noInterrupts();
|
// noInterrupts();
|
||||||
irsend_active = true;
|
|
||||||
irsend->sendRaw(rawdata, i, 38);
|
irsend->sendRaw(rawdata, i, 38);
|
||||||
irsend->sendRaw(rawdata, i, 38);
|
irsend->sendRaw(rawdata, i, 38);
|
||||||
// interrupts();
|
// interrupts();
|
||||||
|
@ -313,9 +309,9 @@ uint8_t IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
|
||||||
#endif // USE_IR_HVAC_TOSHIBA
|
#endif // USE_IR_HVAC_TOSHIBA
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC_MIDEA
|
#ifdef USE_IR_HVAC_MIDEA
|
||||||
/*******************
|
/*-------------------------------------------------------------------------------------------*\
|
||||||
MIDEA / KOMECO
|
* Midea / Komeco
|
||||||
********************/
|
\*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// http://veillard.com/embedded/midea.html
|
// http://veillard.com/embedded/midea.html
|
||||||
// https://github.com/sheinz/esp-midea-ir/blob/master/midea-ir.c
|
// https://github.com/sheinz/esp-midea-ir/blob/master/midea-ir.c
|
||||||
|
@ -431,27 +427,29 @@ uint8_t IrHvacMidea(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_P
|
||||||
rawdata[i++] = HVAC_MIDEA_RPT_MARK;
|
rawdata[i++] = HVAC_MIDEA_RPT_MARK;
|
||||||
rawdata[i++] = HVAC_MIDEA_RPT_SPACE;
|
rawdata[i++] = HVAC_MIDEA_RPT_SPACE;
|
||||||
|
|
||||||
// noInterrupts();
|
|
||||||
// this takes ~180 ms :
|
// this takes ~180 ms :
|
||||||
irsend->sendRaw(rawdata, i, 38);
|
irsend->sendRaw(rawdata, i, 38);
|
||||||
irsend->sendRaw(rawdata, i, 38);
|
irsend->sendRaw(rawdata, i, 38);
|
||||||
// interrupts();
|
|
||||||
|
|
||||||
return IE_NO_ERROR;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC_MIDEA
|
#endif // USE_IR_HVAC_MIDEA
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC_MITSUBISHI
|
#ifdef USE_IR_HVAC_MITSUBISHI
|
||||||
/*******************
|
/*-------------------------------------------------------------------------------------------*\
|
||||||
MITSUBISHI
|
* Mitsubishi
|
||||||
********************/
|
\*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <ir_Mitsubishi.h>
|
||||||
|
|
||||||
uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
|
|
||||||
mitsubir->stateReset();
|
IRMitsubishiAC mitsubir(pin[GPIO_IRSEND]);
|
||||||
|
|
||||||
|
mitsubir.stateReset();
|
||||||
|
|
||||||
if (HVAC_Mode == nullptr) {
|
if (HVAC_Mode == nullptr) {
|
||||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||||
|
@ -463,9 +461,9 @@ uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool H
|
||||||
return IE_SYNTAX_IRHVAC;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
|
mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
|
||||||
mitsubir->setMode(mode);
|
mitsubir.setMode(mode);
|
||||||
|
|
||||||
mitsubir->setPower(HVAC_Power);
|
mitsubir.setPower(HVAC_Power);
|
||||||
|
|
||||||
if (HVAC_FanMode == nullptr) {
|
if (HVAC_FanMode == nullptr) {
|
||||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||||
|
@ -477,11 +475,11 @@ uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool H
|
||||||
return IE_SYNTAX_IRHVAC;
|
return IE_SYNTAX_IRHVAC;
|
||||||
}
|
}
|
||||||
mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
|
mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
|
||||||
mitsubir->setFan(mode);
|
mitsubir.setFan(mode);
|
||||||
|
|
||||||
mitsubir->setTemp(HVAC_Temp);
|
mitsubir.setTemp(HVAC_Temp);
|
||||||
mitsubir->setVane(MITSUBISHI_AC_VANE_AUTO);
|
mitsubir.setVane(MITSUBISHI_AC_VANE_AUTO);
|
||||||
mitsubir->send();
|
mitsubir.send();
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
|
||||||
// mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
|
// mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
|
||||||
|
@ -491,9 +489,9 @@ uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool H
|
||||||
#endif // USE_IR_HVAC_MITSUBISHI
|
#endif // USE_IR_HVAC_MITSUBISHI
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC_LG
|
#ifdef USE_IR_HVAC_LG
|
||||||
/*******************
|
/*-------------------------------------------------------------------------------------------*\
|
||||||
LG
|
* LG
|
||||||
********************/
|
\*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
const uint8_t HVAC_LG_DATALEN = 7;
|
const uint8_t HVAC_LG_DATALEN = 7;
|
||||||
|
|
||||||
|
@ -600,19 +598,18 @@ uint8_t IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Powe
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: LG_Code %d"), LG_Code);
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: LG_Code %d"), LG_Code);
|
||||||
|
|
||||||
// Send LG IR Code
|
// Send LG IR Code
|
||||||
// noInterrupts();
|
|
||||||
irsend_active = true;
|
|
||||||
irsend->sendLG(LG_Code, 28);
|
irsend->sendLG(LG_Code, 28);
|
||||||
// interrupts();
|
|
||||||
|
|
||||||
return IE_NO_ERROR;
|
return IE_NO_ERROR;
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC_LG
|
#endif // USE_IR_HVAC_LG
|
||||||
|
|
||||||
#ifdef USE_IR_HVAC_FUJITSU
|
#ifdef USE_IR_HVAC_FUJITSU
|
||||||
/*******************
|
/*-------------------------------------------------------------------------------------------*\
|
||||||
Fujitsu
|
* Fujitsu
|
||||||
********************/
|
\*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <ir_Fujitsu.h>
|
||||||
|
|
||||||
uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
|
@ -622,8 +619,6 @@ uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
|
||||||
|
|
||||||
IRFujitsuAC ac(pin[GPIO_IRSEND]);
|
IRFujitsuAC ac(pin[GPIO_IRSEND]);
|
||||||
|
|
||||||
irsend_active = true;
|
|
||||||
|
|
||||||
if (0 == HVAC_Power) {
|
if (0 == HVAC_Power) {
|
||||||
ac.off();
|
ac.off();
|
||||||
ac.send();
|
ac.send();
|
||||||
|
@ -665,331 +660,341 @@ uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC_FUJITSU
|
#endif // USE_IR_HVAC_FUJITSU
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t IrRemoteCmndIrHvacJson(void)
|
||||||
|
{
|
||||||
|
// IrHvac { "Vendor": "<Toshiba|Mitsubishi>", "Power": <0|1>, "Mode": "<Hot|Cold|Dry|Auto>", "FanSpeed": "<1|2|3|4|5|Auto|Silence>", "Temp": <17..30> }
|
||||||
|
const char *HVAC_Mode;
|
||||||
|
const char *HVAC_FanMode;
|
||||||
|
const char *HVAC_Vendor;
|
||||||
|
int HVAC_Temp = 21;
|
||||||
|
bool HVAC_Power = true;
|
||||||
|
|
||||||
|
char dataBufUc[XdrvMailbox.data_len];
|
||||||
|
UpperCase(dataBufUc, XdrvMailbox.data);
|
||||||
|
RemoveSpace(dataBufUc);
|
||||||
|
if (strlen(dataBufUc) < 8) {
|
||||||
|
return IE_INVALID_JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticJsonBuffer<164> jsonBufer;
|
||||||
|
JsonObject &root = jsonBufer.parseObject(dataBufUc);
|
||||||
|
if (!root.success()) {
|
||||||
|
return IE_INVALID_JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
HVAC_Vendor = root[D_JSON_IRHVAC_VENDOR];
|
||||||
|
HVAC_Power = root[D_JSON_IRHVAC_POWER];
|
||||||
|
HVAC_Mode = root[D_JSON_IRHVAC_MODE];
|
||||||
|
HVAC_FanMode = root[D_JSON_IRHVAC_FANSPEED];
|
||||||
|
HVAC_Temp = root[D_JSON_IRHVAC_TEMP];
|
||||||
|
|
||||||
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"), HVAC_Vendor, HVAC_Power, HVAC_Mode, HVAC_FanMode, HVAC_Temp);
|
||||||
|
|
||||||
|
char vendor[20];
|
||||||
|
int vendor_code = GetCommandCode(vendor, sizeof(vendor), HVAC_Vendor, kIrHvacVendors);
|
||||||
|
irsend_active = true;
|
||||||
|
switch (vendor_code) {
|
||||||
|
#ifdef USE_IR_HVAC_TOSHIBA
|
||||||
|
case VNDR_TOSHIBA:
|
||||||
|
return IrHvacToshiba(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_HVAC_MITSUBISHI
|
||||||
|
case VNDR_MITSUBISHI:
|
||||||
|
return IrHvacMitsubishi(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_HVAC_LG
|
||||||
|
case VNDR_LG:
|
||||||
|
return IrHvacLG(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_HVAC_FUJITSU
|
||||||
|
case VNDR_FUJITSU:
|
||||||
|
return IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_HVAC_MIDEA
|
||||||
|
case VNDR_MIDEA:
|
||||||
|
return IrHvacMidea(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
irsend_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IE_SYNTAX_IRHVAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmndIrHvac(void)
|
||||||
|
{
|
||||||
|
uint8_t error = IE_SYNTAX_IRHVAC;
|
||||||
|
|
||||||
|
if (XdrvMailbox.data_len) {
|
||||||
|
error = IrRemoteCmndIrHvacJson();
|
||||||
|
}
|
||||||
|
IrRemoteCmndResponse(error);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Commands
|
* Commands
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
/*
|
uint32_t IrRemoteCmndIrSendRaw(void)
|
||||||
* ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(3) + 40 = 96
|
|
||||||
IRsend:
|
|
||||||
{ "protocol": "RC5", "bits": 12, "data":"0xC86" }
|
|
||||||
{ "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
|
||||||
IRhvac:
|
|
||||||
{ "Vendor": "<Toshiba|Mitsubishi>", "Power": <0|1>, "Mode": "<Hot|Cold|Dry|Auto>", "FanSpeed": "<1|2|3|4|5|Auto|Silence>", "Temp": <17..30> }
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool IrSendCommand(void)
|
|
||||||
{
|
{
|
||||||
char command [CMDSZ];
|
// IRsend <freq>,<rawdata>,<rawdata> ...
|
||||||
bool serviced = true;
|
// or
|
||||||
uint8_t error = IE_NO_ERROR;
|
// IRsend raw,<freq>,<zero space>,<bit stream> (one space = zero space *2)
|
||||||
|
// IRsend raw,<freq>,<zero space>,<zero space multiplier becoming one space>,<bit stream>
|
||||||
|
// IRsend raw,<freq>,<zero space>,<one space>,<bit stream>
|
||||||
|
// IRsend raw,<freq>,<header mark>,<header space>,<bit mark>,<zero space>,<one space>,<bit stream>
|
||||||
|
|
||||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kIrRemoteCommands);
|
char *p;
|
||||||
if (-1 == command_code) {
|
char *str = strtok_r(XdrvMailbox.data, ", ", &p);
|
||||||
serviced = false; // Unknown command
|
if (p == nullptr) {
|
||||||
|
return IE_INVALID_RAWDATA;
|
||||||
}
|
}
|
||||||
else if (CMND_IRSEND == command_code) {
|
|
||||||
if (XdrvMailbox.data_len) {
|
|
||||||
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
|
||||||
|
|
||||||
if (strstr(XdrvMailbox.data, "{") == nullptr) { // If no JSON it must be rawdata
|
uint16_t freq = atoi(str);
|
||||||
// IRsend <freq>,<rawdata>,<rawdata> ...
|
if (!freq && (*str != '0')) { // First parameter is any string
|
||||||
// or
|
uint16_t count = 0;
|
||||||
// IRsend raw,<freq>,<zero space>,<bit stream> (one space = zero space *2)
|
char *q = p;
|
||||||
// IRsend raw,<freq>,<zero space>,<zero space multiplier becoming one space>,<bit stream>
|
for (; *q; count += (*q++ == ','));
|
||||||
// IRsend raw,<freq>,<zero space>,<one space>,<bit stream>
|
if (count < 2) {
|
||||||
// IRsend raw,<freq>,<header mark>,<header space>,<bit mark>,<zero space>,<one space>,<bit stream>
|
return IE_INVALID_RAWDATA;
|
||||||
char *p;
|
} // Parameters must be at least 3
|
||||||
char *str = strtok_r(XdrvMailbox.data, ", ", &p);
|
|
||||||
if (p == nullptr) {
|
uint16_t parm[count];
|
||||||
error = IE_INVALID_RAWDATA;
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
parm[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0);
|
||||||
|
if (!parm[i]) {
|
||||||
|
if (!i) {
|
||||||
|
parm[0] = 38000; // Frequency default to 38kHz
|
||||||
} else {
|
} else {
|
||||||
uint16_t freq = atoi(str);
|
return IE_INVALID_RAWDATA; // Other parameters may not be 0
|
||||||
if (!freq && (*str != '0')) { // First parameter is any string
|
|
||||||
uint16_t count = 0;
|
|
||||||
char *q = p;
|
|
||||||
for (; *q; count += (*q++ == ','));
|
|
||||||
if (count < 2) { // Parameters must be at least 3
|
|
||||||
error = IE_INVALID_RAWDATA;
|
|
||||||
} else {
|
|
||||||
uint16_t parm[count];
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
parm[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0);
|
|
||||||
if (!parm[i]) {
|
|
||||||
if (!i) {
|
|
||||||
parm[0] = 38000; // Frequency default to 38kHz
|
|
||||||
} else {
|
|
||||||
error = IE_INVALID_RAWDATA; // Other parameters may not be 0
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IE_NO_ERROR == error) {
|
|
||||||
uint16_t i = 0;
|
|
||||||
if (count < 4) {
|
|
||||||
// IRsend raw,0,889,000000100110000001001
|
|
||||||
uint16_t mark = parm[1] *2; // Protocol where 0 = t, 1 = 2t (RC5)
|
|
||||||
if (3 == count) {
|
|
||||||
if (parm[2] < parm[1]) {
|
|
||||||
// IRsend raw,0,889,2,000000100110000001001
|
|
||||||
mark = parm[1] * parm[2]; // Protocol where 0 = t1, 1 = t1*t2 (Could be RC5)
|
|
||||||
} else {
|
|
||||||
// IRsend raw,0,889,1778,000000100110000001001
|
|
||||||
mark = parm[2]; // Protocol where 0 = t1, 1 = t2 (Could be RC5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint16_t raw_array[strlen(p)]; // Bits
|
|
||||||
for (; *p; *p++) {
|
|
||||||
if (*p == '0') {
|
|
||||||
raw_array[i++] = parm[1]; // Space
|
|
||||||
}
|
|
||||||
else if (*p == '1') {
|
|
||||||
raw_array[i++] = mark; // Mark
|
|
||||||
}
|
|
||||||
}
|
|
||||||
irsend_active = true;
|
|
||||||
irsend->sendRaw(raw_array, i, parm[0]);
|
|
||||||
}
|
|
||||||
else if (6 == count) { // NEC Protocol
|
|
||||||
// IRsend raw,0,8620,4260,544,411,1496,010101101000111011001110000000001100110000000001100000000000000010001100
|
|
||||||
uint16_t raw_array[strlen(p)*2+3]; // Header + bits + end
|
|
||||||
raw_array[i++] = parm[1]; // Header mark
|
|
||||||
raw_array[i++] = parm[2]; // Header space
|
|
||||||
for (; *p; *p++) {
|
|
||||||
if (*p == '0') {
|
|
||||||
raw_array[i++] = parm[3]; // Bit mark
|
|
||||||
raw_array[i++] = parm[4]; // Zero space
|
|
||||||
}
|
|
||||||
else if (*p == '1') {
|
|
||||||
raw_array[i++] = parm[3]; // Bit mark
|
|
||||||
raw_array[i++] = parm[5]; // One space
|
|
||||||
}
|
|
||||||
}
|
|
||||||
raw_array[i++] = parm[3]; // Trailing mark
|
|
||||||
irsend_active = true;
|
|
||||||
irsend->sendRaw(raw_array, i, parm[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error = IE_INVALID_RAWDATA; // Invalid number of parameters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!freq) { freq = 38000; } // Default to 38kHz
|
|
||||||
uint16_t count = 0;
|
|
||||||
char *q = p;
|
|
||||||
for (; *q; count += (*q++ == ','));
|
|
||||||
if (0 == count) {
|
|
||||||
error = IE_INVALID_RAWDATA;
|
|
||||||
} else { // At least two raw data values
|
|
||||||
// IRsend 0,896,876,900,888,894,876,1790,874,872,1810,1736,948,872,880,872,936,872,1792,900,888,1734
|
|
||||||
count++;
|
|
||||||
if (count < 200) {
|
|
||||||
uint16_t raw_array[count]; // It's safe to use stack for up to 200 packets (limited by mqtt_data length)
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
raw_array[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); // Allow decimal (20496) and hexadecimal (0x5010) input
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: stack count %d"), count);
|
|
||||||
|
|
||||||
irsend_active = true;
|
|
||||||
irsend->sendRaw(raw_array, count, freq);
|
|
||||||
} else {
|
|
||||||
uint16_t *raw_array = reinterpret_cast<uint16_t*>(malloc(count * sizeof(uint16_t)));
|
|
||||||
if (raw_array == nullptr) {
|
|
||||||
error = IE_INVALID_RAWDATA;
|
|
||||||
} else {
|
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
|
||||||
raw_array[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); // Allow decimal (20496) and hexadecimal (0x5010) input
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: heap count %d"), count);
|
|
||||||
|
|
||||||
irsend_active = true;
|
|
||||||
irsend->sendRaw(raw_array, count, freq);
|
|
||||||
free(raw_array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
char dataBufUc[XdrvMailbox.data_len];
|
|
||||||
UpperCase(dataBufUc, XdrvMailbox.data);
|
|
||||||
RemoveSpace(dataBufUc);
|
|
||||||
if (strlen(dataBufUc) < 8) {
|
|
||||||
error = IE_INVALID_JSON;
|
|
||||||
} else {
|
|
||||||
StaticJsonBuffer<140> jsonBuf;
|
|
||||||
JsonObject &root = jsonBuf.parseObject(dataBufUc);
|
|
||||||
if (!root.success()) {
|
|
||||||
error = IE_INVALID_JSON;
|
|
||||||
} else {
|
|
||||||
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
|
||||||
// IRsend { "protocol": "NEC", "bits": 32, "data":"0x02FDFE80", "repeat": 2 }
|
|
||||||
char parm_uc[10];
|
|
||||||
const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))];
|
|
||||||
uint16_t bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))];
|
|
||||||
uint64_t data = strtoull(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], nullptr, 0);
|
|
||||||
uint16_t repeat = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_REPEAT))];
|
|
||||||
if (protocol && bits) {
|
|
||||||
char protocol_text[20];
|
|
||||||
int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols);
|
|
||||||
|
|
||||||
char dvalue[64];
|
|
||||||
char hvalue[64];
|
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %s (%s), repeat %d, protocol_code %d"),
|
|
||||||
protocol_text, protocol, bits, ulltoa(data, dvalue, 10), IrUint64toHex(data, hvalue, bits), repeat, protocol_code);
|
|
||||||
|
|
||||||
irsend_active = true;
|
|
||||||
switch (protocol_code) { // Equals IRremoteESP8266.h enum decode_type_t
|
|
||||||
#ifdef USE_IR_SEND_RC5
|
|
||||||
case RC5:
|
|
||||||
irsend->sendRC5(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_RC6
|
|
||||||
case RC6:
|
|
||||||
irsend->sendRC6(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_NEC
|
|
||||||
case NEC:
|
|
||||||
irsend->sendNEC(data, (bits > NEC_BITS) ? NEC_BITS : bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_SONY
|
|
||||||
case SONY:
|
|
||||||
irsend->sendSony(data, (bits > SONY_20_BITS) ? SONY_20_BITS : bits, repeat > kSonyMinRepeat ? repeat : kSonyMinRepeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_PANASONIC
|
|
||||||
case PANASONIC:
|
|
||||||
irsend->sendPanasonic64(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_JVC
|
|
||||||
case JVC:
|
|
||||||
irsend->sendJVC(data, (bits > JVC_BITS) ? JVC_BITS : bits, repeat > 1 ? repeat : 1); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_SAMSUNG
|
|
||||||
case SAMSUNG:
|
|
||||||
irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_WHYNTER
|
|
||||||
case WHYNTER:
|
|
||||||
irsend->sendWhynter(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_AIWA
|
|
||||||
case AIWA_RC_T501:
|
|
||||||
irsend->sendAiwaRCT501(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_LG
|
|
||||||
case LG:
|
|
||||||
irsend->sendLG(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_SANYO
|
|
||||||
case SANYO:
|
|
||||||
irsend->sendSanyoLC7461(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_MITSUBISHI
|
|
||||||
case MITSUBISHI:
|
|
||||||
irsend->sendMitsubishi(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_DISH
|
|
||||||
case DISH:
|
|
||||||
irsend->sendDISH(data, (bits > DISH_BITS) ? DISH_BITS : bits, repeat > kDishMinRepeat ? repeat : kDishMinRepeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_SHARP
|
|
||||||
case SHARP:
|
|
||||||
irsend->sendSharpRaw(data, bits, repeat); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_SEND_PIONEER
|
|
||||||
case IR_PIONEER:
|
|
||||||
irsend->sendPioneer(data, bits, repeat); break;
|
|
||||||
#endif // USE_IR_SEND_PIONEER
|
|
||||||
default:
|
|
||||||
irsend_active = false;
|
|
||||||
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_PROTOCOL_NOT_SUPPORTED);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error = IE_SYNTAX_IRSEND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
error = IE_SYNTAX_IRSEND;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#ifdef USE_IR_HVAC
|
|
||||||
else if (CMND_IRHVAC == command_code) {
|
|
||||||
const char *HVAC_Mode;
|
|
||||||
const char *HVAC_FanMode;
|
|
||||||
const char *HVAC_Vendor;
|
|
||||||
int HVAC_Temp = 21;
|
|
||||||
bool HVAC_Power = true;
|
|
||||||
|
|
||||||
if (XdrvMailbox.data_len) {
|
uint16_t i = 0;
|
||||||
char dataBufUc[XdrvMailbox.data_len];
|
if (count < 4) {
|
||||||
UpperCase(dataBufUc, XdrvMailbox.data);
|
// IRsend raw,0,889,000000100110000001001
|
||||||
RemoveSpace(dataBufUc);
|
uint16_t mark = parm[1] *2; // Protocol where 0 = t, 1 = 2t (RC5)
|
||||||
if (strlen(dataBufUc) < 8) {
|
if (3 == count) {
|
||||||
error = IE_INVALID_JSON;
|
if (parm[2] < parm[1]) {
|
||||||
} else {
|
// IRsend raw,0,889,2,000000100110000001001
|
||||||
StaticJsonBuffer<164> jsonBufer;
|
mark = parm[1] * parm[2]; // Protocol where 0 = t1, 1 = t1*t2 (Could be RC5)
|
||||||
JsonObject &root = jsonBufer.parseObject(dataBufUc);
|
|
||||||
if (!root.success()) {
|
|
||||||
error = IE_INVALID_JSON;
|
|
||||||
} else {
|
} else {
|
||||||
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
// IRsend raw,0,889,1778,000000100110000001001
|
||||||
HVAC_Vendor = root[D_JSON_IRHVAC_VENDOR];
|
mark = parm[2]; // Protocol where 0 = t1, 1 = t2 (Could be RC5)
|
||||||
HVAC_Power = root[D_JSON_IRHVAC_POWER];
|
|
||||||
HVAC_Mode = root[D_JSON_IRHVAC_MODE];
|
|
||||||
HVAC_FanMode = root[D_JSON_IRHVAC_FANSPEED];
|
|
||||||
HVAC_Temp = root[D_JSON_IRHVAC_TEMP];
|
|
||||||
|
|
||||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"), HVAC_Vendor, HVAC_Power, HVAC_Mode, HVAC_FanMode, HVAC_Temp);
|
|
||||||
|
|
||||||
char vendor[20];
|
|
||||||
int vendor_code = GetCommandCode(vendor, sizeof(vendor), HVAC_Vendor, kIrHvacVendors);
|
|
||||||
switch (vendor_code) {
|
|
||||||
#ifdef USE_IR_HVAC_TOSHIBA
|
|
||||||
case VNDR_TOSHIBA:
|
|
||||||
error = IrHvacToshiba(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_HVAC_MITSUBISHI
|
|
||||||
case VNDR_MITSUBISHI:
|
|
||||||
error = IrHvacMitsubishi(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_HVAC_LG
|
|
||||||
case VNDR_LG:
|
|
||||||
error = IrHvacLG(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_HVAC_FUJITSU
|
|
||||||
case VNDR_FUJITSU:
|
|
||||||
error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_IR_HVAC_MIDEA
|
|
||||||
case VNDR_MIDEA:
|
|
||||||
error = IrHvacMidea(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
error = IE_SYNTAX_IRHVAC;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint16_t raw_array[strlen(p)]; // Bits
|
||||||
|
for (; *p; *p++) {
|
||||||
|
if (*p == '0') {
|
||||||
|
raw_array[i++] = parm[1]; // Space
|
||||||
|
}
|
||||||
|
else if (*p == '1') {
|
||||||
|
raw_array[i++] = mark; // Mark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
irsend_active = true;
|
||||||
|
irsend->sendRaw(raw_array, i, parm[0]);
|
||||||
|
}
|
||||||
|
else if (6 == count) { // NEC Protocol
|
||||||
|
// IRsend raw,0,8620,4260,544,411,1496,010101101000111011001110000000001100110000000001100000000000000010001100
|
||||||
|
uint16_t raw_array[strlen(p)*2+3]; // Header + bits + end
|
||||||
|
raw_array[i++] = parm[1]; // Header mark
|
||||||
|
raw_array[i++] = parm[2]; // Header space
|
||||||
|
for (; *p; *p++) {
|
||||||
|
if (*p == '0') {
|
||||||
|
raw_array[i++] = parm[3]; // Bit mark
|
||||||
|
raw_array[i++] = parm[4]; // Zero space
|
||||||
|
}
|
||||||
|
else if (*p == '1') {
|
||||||
|
raw_array[i++] = parm[3]; // Bit mark
|
||||||
|
raw_array[i++] = parm[5]; // One space
|
||||||
|
}
|
||||||
|
}
|
||||||
|
raw_array[i++] = parm[3]; // Trailing mark
|
||||||
|
irsend_active = true;
|
||||||
|
irsend->sendRaw(raw_array, i, parm[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error = IE_SYNTAX_IRHVAC;
|
return IE_INVALID_RAWDATA; // Invalid number of parameters
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!freq) { freq = 38000; } // Default to 38kHz
|
||||||
|
uint16_t count = 0;
|
||||||
|
char *q = p;
|
||||||
|
for (; *q; count += (*q++ == ','));
|
||||||
|
if (0 == count) {
|
||||||
|
return IE_INVALID_RAWDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRsend 0,896,876,900,888,894,876,1790,874,872,1810,1736,948,872,880,872,936,872,1792,900,888,1734
|
||||||
|
count++;
|
||||||
|
if (count < 200) {
|
||||||
|
uint16_t raw_array[count]; // It's safe to use stack for up to 200 packets (limited by mqtt_data length)
|
||||||
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
raw_array[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); // Allow decimal (20496) and hexadecimal (0x5010) input
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: stack count %d"), count);
|
||||||
|
|
||||||
|
irsend_active = true;
|
||||||
|
irsend->sendRaw(raw_array, count, freq);
|
||||||
|
} else {
|
||||||
|
uint16_t *raw_array = reinterpret_cast<uint16_t*>(malloc(count * sizeof(uint16_t)));
|
||||||
|
if (raw_array == nullptr) {
|
||||||
|
return IE_INVALID_RAWDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
raw_array[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); // Allow decimal (20496) and hexadecimal (0x5010) input
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: heap count %d"), count);
|
||||||
|
|
||||||
|
irsend_active = true;
|
||||||
|
irsend->sendRaw(raw_array, count, freq);
|
||||||
|
free(raw_array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC
|
|
||||||
else serviced = false; // Unknown command
|
|
||||||
|
|
||||||
|
return IE_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t IrRemoteCmndIrSendJson(void)
|
||||||
|
{
|
||||||
|
// ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(3) + 40 = 96
|
||||||
|
// IRsend { "protocol": "RC5", "bits": 12, "data":"0xC86" }
|
||||||
|
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
||||||
|
|
||||||
|
char dataBufUc[XdrvMailbox.data_len];
|
||||||
|
UpperCase(dataBufUc, XdrvMailbox.data);
|
||||||
|
RemoveSpace(dataBufUc);
|
||||||
|
if (strlen(dataBufUc) < 8) {
|
||||||
|
return IE_INVALID_JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticJsonBuffer<140> jsonBuf;
|
||||||
|
JsonObject &root = jsonBuf.parseObject(dataBufUc);
|
||||||
|
if (!root.success()) {
|
||||||
|
return IE_INVALID_JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
|
||||||
|
// IRsend { "protocol": "NEC", "bits": 32, "data":"0x02FDFE80", "repeat": 2 }
|
||||||
|
char parm_uc[10];
|
||||||
|
const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))];
|
||||||
|
uint16_t bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))];
|
||||||
|
uint64_t data = strtoull(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], nullptr, 0);
|
||||||
|
uint16_t repeat = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_REPEAT))];
|
||||||
|
if (!(protocol && bits)) {
|
||||||
|
return IE_SYNTAX_IRSEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
char protocol_text[20];
|
||||||
|
int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols);
|
||||||
|
|
||||||
|
char dvalue[64];
|
||||||
|
char hvalue[64];
|
||||||
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %s (%s), repeat %d, protocol_code %d"),
|
||||||
|
protocol_text, protocol, bits, ulltoa(data, dvalue, 10), IrUint64toHex(data, hvalue, bits), repeat, protocol_code);
|
||||||
|
|
||||||
|
irsend_active = true;
|
||||||
|
switch (protocol_code) { // Equals IRremoteESP8266.h enum decode_type_t
|
||||||
|
#ifdef USE_IR_SEND_RC5
|
||||||
|
case RC5:
|
||||||
|
irsend->sendRC5(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_RC6
|
||||||
|
case RC6:
|
||||||
|
irsend->sendRC6(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_NEC
|
||||||
|
case NEC:
|
||||||
|
irsend->sendNEC(data, (bits > NEC_BITS) ? NEC_BITS : bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_SONY
|
||||||
|
case SONY:
|
||||||
|
irsend->sendSony(data, (bits > SONY_20_BITS) ? SONY_20_BITS : bits, repeat > kSonyMinRepeat ? repeat : kSonyMinRepeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_PANASONIC
|
||||||
|
case PANASONIC:
|
||||||
|
irsend->sendPanasonic64(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_JVC
|
||||||
|
case JVC:
|
||||||
|
irsend->sendJVC(data, (bits > JVC_BITS) ? JVC_BITS : bits, repeat > 1 ? repeat : 1); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_SAMSUNG
|
||||||
|
case SAMSUNG:
|
||||||
|
irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_WHYNTER
|
||||||
|
case WHYNTER:
|
||||||
|
irsend->sendWhynter(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_AIWA
|
||||||
|
case AIWA_RC_T501:
|
||||||
|
irsend->sendAiwaRCT501(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_LG
|
||||||
|
case LG:
|
||||||
|
irsend->sendLG(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_SANYO
|
||||||
|
case SANYO:
|
||||||
|
irsend->sendSanyoLC7461(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_MITSUBISHI
|
||||||
|
case MITSUBISHI:
|
||||||
|
irsend->sendMitsubishi(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_DISH
|
||||||
|
case DISH:
|
||||||
|
irsend->sendDISH(data, (bits > DISH_BITS) ? DISH_BITS : bits, repeat > kDishMinRepeat ? repeat : kDishMinRepeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_SHARP
|
||||||
|
case SHARP:
|
||||||
|
irsend->sendSharpRaw(data, bits, repeat); break;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_IR_SEND_PIONEER
|
||||||
|
case IR_PIONEER:
|
||||||
|
irsend->sendPioneer(data, bits, repeat); break;
|
||||||
|
#endif // USE_IR_SEND_PIONEER
|
||||||
|
default:
|
||||||
|
irsend_active = false;
|
||||||
|
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, D_JSON_PROTOCOL_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IE_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmndIrSend(void)
|
||||||
|
{
|
||||||
|
uint8_t error = IE_SYNTAX_IRSEND;
|
||||||
|
|
||||||
|
if (XdrvMailbox.data_len) {
|
||||||
|
// error = (strstr(XdrvMailbox.data, "{") == nullptr) ? IrRemoteCmndIrSendRaw() : IrRemoteCmndIrSendJson();
|
||||||
|
if (strstr(XdrvMailbox.data, "{") == nullptr) {
|
||||||
|
error = IrRemoteCmndIrSendRaw();
|
||||||
|
} else {
|
||||||
|
error = IrRemoteCmndIrSendJson();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IrRemoteCmndResponse(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrRemoteCmndResponse(uint32_t error)
|
||||||
|
{
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case IE_INVALID_RAWDATA:
|
case IE_INVALID_RAWDATA:
|
||||||
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_RAWDATA);
|
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, D_JSON_INVALID_RAWDATA);
|
||||||
break;
|
break;
|
||||||
case IE_INVALID_JSON:
|
case IE_INVALID_JSON:
|
||||||
Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
|
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, D_JSON_INVALID_JSON);
|
||||||
break;
|
break;
|
||||||
case IE_SYNTAX_IRSEND:
|
case IE_SYNTAX_IRSEND:
|
||||||
Response_P(PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
|
Response_P(PSTR("{\"" D_CMND_IRSEND "\":\"" D_JSON_NO " " D_JSON_IR_PROTOCOL ", " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA "\"}"));
|
||||||
|
@ -999,9 +1004,9 @@ bool IrSendCommand(void)
|
||||||
Response_P(PSTR("{\"" D_CMND_IRHVAC "\":\"" D_JSON_WRONG " " D_JSON_IRHVAC_VENDOR ", " D_JSON_IRHVAC_MODE " " D_JSON_OR " " D_JSON_IRHVAC_FANSPEED "\"}"));
|
Response_P(PSTR("{\"" D_CMND_IRHVAC "\":\"" D_JSON_WRONG " " D_JSON_IRHVAC_VENDOR ", " D_JSON_IRHVAC_MODE " " D_JSON_OR " " D_JSON_IRHVAC_FANSPEED "\"}"));
|
||||||
break;
|
break;
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
|
default: // IE_NO_ERROR
|
||||||
|
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return serviced;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
|
@ -1034,7 +1039,7 @@ bool Xdrv05(uint8_t function)
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
if (pin[GPIO_IRSEND] < 99) {
|
if (pin[GPIO_IRSEND] < 99) {
|
||||||
result = IrSendCommand();
|
result = DecodeCommand(kIrRemoteCommands, IrRemoteCommand);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue