mirror of https://github.com/arendst/Tasmota.git
Merge pull request #6917 from s-hadinger/ir_light
Remove IR protocols from standard Tasmota
This commit is contained in:
commit
df5fb16235
|
@ -276,13 +276,13 @@
|
|||
// Tasmota supported protocols (less protocols is less code size)
|
||||
#define DECODE_HASH true // Semi-unique code for unknown messages
|
||||
|
||||
#define SEND_RAW true
|
||||
#define SEND_RAW false
|
||||
|
||||
#define DECODE_NEC true
|
||||
#define SEND_NEC true
|
||||
|
||||
#define DECODE_SHERWOOD false // Doesn't exist. Actually is DECODE_NEC
|
||||
#define SEND_SHERWOOD true
|
||||
#define SEND_SHERWOOD false
|
||||
|
||||
#define DECODE_RC5 true
|
||||
#define SEND_RC5 true
|
||||
|
@ -291,187 +291,187 @@
|
|||
#define SEND_RC6 true
|
||||
|
||||
#define DECODE_RCMM false
|
||||
#define SEND_RCMM true
|
||||
#define SEND_RCMM false
|
||||
|
||||
#define DECODE_SONY true
|
||||
#define SEND_SONY true
|
||||
#define DECODE_SONY false
|
||||
#define SEND_SONY false
|
||||
|
||||
#define DECODE_PANASONIC true
|
||||
#define SEND_PANASONIC true
|
||||
#define DECODE_PANASONIC false
|
||||
#define SEND_PANASONIC false
|
||||
|
||||
#define DECODE_JVC true
|
||||
#define SEND_JVC true
|
||||
#define DECODE_JVC false
|
||||
#define SEND_JVC false
|
||||
|
||||
#define DECODE_SAMSUNG true
|
||||
#define SEND_SAMSUNG true
|
||||
#define DECODE_SAMSUNG false
|
||||
#define SEND_SAMSUNG false
|
||||
|
||||
#define DECODE_SAMSUNG36 false
|
||||
#define SEND_SAMSUNG36 true
|
||||
#define SEND_SAMSUNG36 false
|
||||
|
||||
#define DECODE_SAMSUNG_AC false
|
||||
#define SEND_SAMSUNG_AC true
|
||||
#define SEND_SAMSUNG_AC false
|
||||
|
||||
#define DECODE_WHYNTER false
|
||||
#define SEND_WHYNTER true
|
||||
#define SEND_WHYNTER false
|
||||
|
||||
#define DECODE_AIWA_RC_T501 false
|
||||
#define SEND_AIWA_RC_T501 true
|
||||
#define SEND_AIWA_RC_T501 false
|
||||
|
||||
#define DECODE_LG true
|
||||
#define SEND_LG true
|
||||
#define DECODE_LG false
|
||||
#define SEND_LG false
|
||||
|
||||
#define DECODE_SANYO false
|
||||
#define SEND_SANYO true
|
||||
#define SEND_SANYO false
|
||||
|
||||
#define DECODE_MITSUBISHI false
|
||||
#define SEND_MITSUBISHI true
|
||||
#define SEND_MITSUBISHI false
|
||||
|
||||
#define DECODE_MITSUBISHI2 false
|
||||
#define SEND_MITSUBISHI2 true
|
||||
#define SEND_MITSUBISHI2 false
|
||||
|
||||
#define DECODE_DISH false
|
||||
#define SEND_DISH true
|
||||
#define SEND_DISH false
|
||||
|
||||
#define DECODE_SHARP false
|
||||
#define SEND_SHARP true
|
||||
#define SEND_SHARP false
|
||||
|
||||
#define DECODE_SHARP_AC false
|
||||
#define SEND_SHARP_AC true
|
||||
#define SEND_SHARP_AC false
|
||||
|
||||
#define DECODE_DENON false
|
||||
#define SEND_DENON true
|
||||
#define SEND_DENON false
|
||||
|
||||
#define DECODE_KELVINATOR false
|
||||
#define SEND_KELVINATOR true
|
||||
#define SEND_KELVINATOR false
|
||||
|
||||
#define DECODE_MITSUBISHI_AC false // Beta.
|
||||
#define SEND_MITSUBISHI_AC true
|
||||
#define SEND_MITSUBISHI_AC false
|
||||
|
||||
#define DECODE_FUJITSU_AC false
|
||||
#define SEND_FUJITSU_AC true
|
||||
#define SEND_FUJITSU_AC false
|
||||
|
||||
#define DECODE_INAX false
|
||||
#define SEND_INAX true
|
||||
#define SEND_INAX false
|
||||
|
||||
#define DECODE_DAIKIN false
|
||||
#define SEND_DAIKIN true
|
||||
#define SEND_DAIKIN false
|
||||
|
||||
#define DECODE_COOLIX false
|
||||
#define SEND_COOLIX true
|
||||
#define SEND_COOLIX false
|
||||
|
||||
#define DECODE_GLOBALCACHE false // Not written.
|
||||
#define SEND_GLOBALCACHE true
|
||||
#define SEND_GLOBALCACHE false
|
||||
|
||||
#define DECODE_GOODWEATHER false
|
||||
#define SEND_GOODWEATHER true
|
||||
#define SEND_GOODWEATHER false
|
||||
|
||||
#define DECODE_GREE false
|
||||
#define SEND_GREE true
|
||||
#define SEND_GREE false
|
||||
|
||||
#define DECODE_PRONTO false // Not written.
|
||||
#define SEND_PRONTO true
|
||||
#define SEND_PRONTO false
|
||||
|
||||
#define DECODE_ARGO false // Experimental
|
||||
#define SEND_ARGO true
|
||||
#define SEND_ARGO false
|
||||
|
||||
#define DECODE_TROTEC false
|
||||
#define SEND_TROTEC true
|
||||
#define SEND_TROTEC false
|
||||
|
||||
#define DECODE_NIKAI false
|
||||
#define SEND_NIKAI true
|
||||
#define SEND_NIKAI false
|
||||
|
||||
#define DECODE_TOSHIBA_AC false
|
||||
#define SEND_TOSHIBA_AC true
|
||||
#define SEND_TOSHIBA_AC false
|
||||
|
||||
#define DECODE_MAGIQUEST false
|
||||
#define SEND_MAGIQUEST true
|
||||
#define SEND_MAGIQUEST false
|
||||
|
||||
#define DECODE_MIDEA false
|
||||
#define SEND_MIDEA true
|
||||
#define SEND_MIDEA false
|
||||
|
||||
#define DECODE_LASERTAG false
|
||||
#define SEND_LASERTAG true
|
||||
#define SEND_LASERTAG false
|
||||
|
||||
#define DECODE_CARRIER_AC false
|
||||
#define SEND_CARRIER_AC true
|
||||
#define SEND_CARRIER_AC false
|
||||
|
||||
#define DECODE_HAIER_AC false
|
||||
#define SEND_HAIER_AC true
|
||||
#define SEND_HAIER_AC false
|
||||
|
||||
#define DECODE_HITACHI_AC false
|
||||
#define SEND_HITACHI_AC true
|
||||
#define SEND_HITACHI_AC false
|
||||
|
||||
#define DECODE_HITACHI_AC1 false
|
||||
#define SEND_HITACHI_AC1 true
|
||||
#define SEND_HITACHI_AC1 false
|
||||
|
||||
#define DECODE_HITACHI_AC2 false
|
||||
#define SEND_HITACHI_AC2 true
|
||||
#define SEND_HITACHI_AC2 false
|
||||
|
||||
#define DECODE_GICABLE false
|
||||
#define SEND_GICABLE true
|
||||
#define SEND_GICABLE false
|
||||
|
||||
#define DECODE_HAIER_AC_YRW02 false
|
||||
#define SEND_HAIER_AC_YRW02 true
|
||||
#define SEND_HAIER_AC_YRW02 false
|
||||
|
||||
#define DECODE_WHIRLPOOL_AC false
|
||||
#define SEND_WHIRLPOOL_AC true
|
||||
#define SEND_WHIRLPOOL_AC false
|
||||
|
||||
#define DECODE_LUTRON false
|
||||
#define SEND_LUTRON true
|
||||
#define SEND_LUTRON false
|
||||
|
||||
#define DECODE_ELECTRA_AC false
|
||||
#define SEND_ELECTRA_AC true
|
||||
#define SEND_ELECTRA_AC false
|
||||
|
||||
#define DECODE_PANASONIC_AC false
|
||||
#define SEND_PANASONIC_AC true
|
||||
#define SEND_PANASONIC_AC false
|
||||
|
||||
#define DECODE_MWM false
|
||||
#define SEND_MWM true
|
||||
#define SEND_MWM false
|
||||
|
||||
#define DECODE_PIONEER false
|
||||
#define SEND_PIONEER true
|
||||
#define SEND_PIONEER false
|
||||
|
||||
#define DECODE_DAIKIN2 false
|
||||
#define SEND_DAIKIN2 true
|
||||
#define SEND_DAIKIN2 false
|
||||
|
||||
#define DECODE_VESTEL_AC false
|
||||
#define SEND_VESTEL_AC true
|
||||
#define SEND_VESTEL_AC false
|
||||
|
||||
#define DECODE_TECO false
|
||||
#define SEND_TECO true
|
||||
#define SEND_TECO false
|
||||
|
||||
#define DECODE_TCL112AC false
|
||||
#define SEND_TCL112AC true
|
||||
#define SEND_TCL112AC false
|
||||
|
||||
#define DECODE_LEGOPF false
|
||||
#define SEND_LEGOPF true
|
||||
#define SEND_LEGOPF false
|
||||
|
||||
#define DECODE_MITSUBISHIHEAVY false
|
||||
#define SEND_MITSUBISHIHEAVY true
|
||||
#define SEND_MITSUBISHIHEAVY false
|
||||
|
||||
#define DECODE_DAIKIN216 false
|
||||
#define SEND_DAIKIN216 true
|
||||
#define SEND_DAIKIN216 false
|
||||
|
||||
#define DECODE_DAIKIN160 false
|
||||
#define SEND_DAIKIN160 true
|
||||
#define SEND_DAIKIN160 false
|
||||
|
||||
#define DECODE_NEOCLIMA false
|
||||
#define SEND_NEOCLIMA true
|
||||
#define SEND_NEOCLIMA false
|
||||
|
||||
#define DECODE_DAIKIN176 false
|
||||
#define SEND_DAIKIN176 true
|
||||
#define SEND_DAIKIN176 false
|
||||
|
||||
#define DECODE_DAIKIN128 false
|
||||
#define SEND_DAIKIN128 true
|
||||
#define SEND_DAIKIN128 false
|
||||
|
||||
#define DECODE_AMCOR false
|
||||
#define SEND_AMCOR true
|
||||
#define SEND_AMCOR false
|
||||
|
||||
#define DECODE_DAIKIN152 false
|
||||
#define SEND_DAIKIN152 true
|
||||
#define SEND_DAIKIN152 false
|
||||
|
||||
#define DECODE_HITACHI_AC424 false
|
||||
#define SEND_HITACHI_AC424 true
|
||||
#define SEND_HITACHI_AC424 false
|
||||
|
||||
#endif // defined(FIRMWARE_IR) || defined(FIRMWARE_IR_CUSTOM) // full IR protocols
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Change supported MCP230xx I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
|
||||
* Add Keep last channels values when Color command end with '=' (#6799)
|
||||
* Add support for I2C sensor TLS2591 Light Intensity sensor (#6873)
|
||||
* Change Kept only NEC/RC5/RC6/HASH IR protocols in standard Tasmota, all other protocols require Tasmota-IR, saving 4K
|
||||
*
|
||||
* 7.0.0.3 20191103
|
||||
* Add command I2cDriver for I2C driver runtime control using document I2CDEVICES.md
|
||||
|
|
|
@ -509,28 +509,9 @@
|
|||
|
||||
// -- IR Remote features - subset of IR protocols --------------------------
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k3 code, 0k3 mem, 48 iram)
|
||||
// #define USE_IR_SEND_AIWA // Support IRsend Aiwa protocol
|
||||
#define USE_IR_SEND_DISH // Support IRsend Dish protocol
|
||||
#define USE_IR_SEND_JVC // Support IRsend JVC protocol
|
||||
// #define USE_IR_SEND_LG // Support IRsend LG protocol
|
||||
// #define USE_IR_SEND_MITSUBISHI // Support IRsend Mitsubishi protocol
|
||||
#define USE_IR_SEND_NEC // Support IRsend NEC protocol
|
||||
#define USE_IR_SEND_PANASONIC // Support IRsend Panasonic protocol
|
||||
#define USE_IR_SEND_PIONEER // Support IRsend Pioneer protocol
|
||||
#define USE_IR_SEND_RC5 // Support IRsend Philips RC5 protocol
|
||||
#define USE_IR_SEND_RC6 // Support IRsend Philips RC6 protocol
|
||||
#define USE_IR_SEND_SAMSUNG // Support IRsend Samsung protocol
|
||||
// #define USE_IR_SEND_SANYO // Support IRsend Sanyo protocol
|
||||
// #define USE_IR_SEND_SHARP // Support IRsend Sharp protocol
|
||||
#define USE_IR_SEND_SONY // Support IRsend Sony protocol
|
||||
// #define USE_IR_SEND_WHYNTER // Support IRsend Whynter protocol
|
||||
|
||||
// #define USE_IR_HVAC // Support for HVAC systems using IR (+3k5 code)
|
||||
#define USE_IR_HVAC_TOSHIBA // Support IRhvac Toshiba protocol
|
||||
#define USE_IR_HVAC_MITSUBISHI // Support IRhvac Mitsubischi protocol
|
||||
#define USE_IR_HVAC_LG // Support IRhvac LG protocol
|
||||
#define USE_IR_HVAC_FUJITSU // Support IRhvac Fujitsu protocol
|
||||
// #define USE_IR_HVAC_MIDEA // Support IRhvac Midea/Komeco protocol
|
||||
|
||||
#define USE_IR_RECEIVE // Support for IR receiver (+7k2 code, 264 iram)
|
||||
#define IR_RCV_BUFFER_SIZE 100 // Max number of packets allowed in capture buffer (default 100 (*2 bytes ram))
|
||||
|
|
|
@ -194,7 +194,6 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
|
|||
#define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI
|
||||
//#define USE_MAX31865 // Add support for MAX31865 RTD sensors using softSPI
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
#define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
|
||||
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
||||
|
||||
//#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP
|
||||
|
|
|
@ -28,32 +28,14 @@
|
|||
|
||||
enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_SYNTAX_IRHVAC };
|
||||
|
||||
const char kIrRemoteCommands[] PROGMEM = "|" // No prefix
|
||||
#ifdef USE_IR_HVAC
|
||||
D_CMND_IRHVAC "|"
|
||||
#endif
|
||||
D_CMND_IRSEND ;
|
||||
const char kIrRemoteCommands[] PROGMEM = "|" D_CMND_IRSEND ;
|
||||
|
||||
void (* const IrRemoteCommand[])(void) PROGMEM = {
|
||||
#ifdef USE_IR_HVAC
|
||||
&CmndIrHvac,
|
||||
#endif
|
||||
&CmndIrSend };
|
||||
void (* const IrRemoteCommand[])(void) PROGMEM = { &CmndIrSend };
|
||||
|
||||
// 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
|
||||
enum IrVendors { IR_BASE = MAX_STANDARD_IR,
|
||||
#ifdef USE_IR_SEND_PIONEER
|
||||
IR_PIONEER,
|
||||
#endif // USE_IR_SEND_PIONEER
|
||||
};
|
||||
const char kIrRemoteProtocols[] PROGMEM =
|
||||
"UNKNOWN|RC5|RC6|NEC|SONY|PANASONIC|JVC|SAMSUNG|WHYNTER|AIWA_RC_T501|LG|SANYO|MITSUBISHI|DISH|SHARP"
|
||||
// now allow for other codes beyond the first series;
|
||||
#ifdef USE_IR_SEND_PIONEER
|
||||
"|PIONEER"
|
||||
#endif // USE_IR_SEND_PIONEER
|
||||
;
|
||||
enum IrVendors { IR_BASE = MAX_STANDARD_IR };
|
||||
const char kIrRemoteProtocols[] PROGMEM = "UNKNOWN|RC5|RC6|NEC";
|
||||
|
||||
/*********************************************************************************************\
|
||||
* IR Send
|
||||
|
@ -188,698 +170,10 @@ void IrReceiveCheck(void)
|
|||
}
|
||||
#endif // USE_IR_RECEIVE
|
||||
|
||||
|
||||
#ifdef USE_IR_HVAC
|
||||
/*********************************************************************************************\
|
||||
* 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
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Toshiba
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
const uint16_t HVAC_TOSHIBA_HDR_MARK = 4400;
|
||||
const uint16_t HVAC_TOSHIBA_HDR_SPACE = 4300;
|
||||
const uint16_t HVAC_TOSHIBA_BIT_MARK = 543;
|
||||
const uint16_t HVAC_TOSHIBA_ONE_SPACE = 1623;
|
||||
const uint16_t HVAC_MISTUBISHI_ZERO_SPACE = 472;
|
||||
const uint16_t HVAC_TOSHIBA_RPT_MARK = 440;
|
||||
const uint16_t HVAC_TOSHIBA_RPT_SPACE = 7048; // Above original iremote limit
|
||||
const uint8_t HVAC_TOSHIBA_DATALEN = 9;
|
||||
|
||||
uint8_t IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||
{
|
||||
uint16_t rawdata[2 + 2 * 8 * HVAC_TOSHIBA_DATALEN + 2];
|
||||
uint8_t data[HVAC_TOSHIBA_DATALEN] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
char *p;
|
||||
uint8_t mode;
|
||||
|
||||
if (HVAC_Mode == nullptr) {
|
||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||
}
|
||||
else {
|
||||
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
data[6] = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
||||
|
||||
if (!HVAC_Power) {
|
||||
data[6] = (uint8_t)0x07; // Turn OFF HVAC
|
||||
}
|
||||
|
||||
if (HVAC_FanMode == nullptr) {
|
||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||
}
|
||||
else {
|
||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
mode = p - kFanSpeedOptions + 1;
|
||||
if ((1 == mode) || (7 == mode)) {
|
||||
mode = 0;
|
||||
}
|
||||
mode = mode << 5; // AUTO = 0x00, SPEED = 0x40, 0x60, 0x80, 0xA0, 0xC0, SILENT = 0x00
|
||||
data[6] = data[6] | mode;
|
||||
|
||||
uint8_t Temp;
|
||||
if (HVAC_Temp > 30) {
|
||||
Temp = 30;
|
||||
}
|
||||
else if (HVAC_Temp < 17) {
|
||||
Temp = 17;
|
||||
}
|
||||
else {
|
||||
Temp = HVAC_Temp;
|
||||
}
|
||||
data[5] = (uint8_t)(Temp - 17) << 4;
|
||||
|
||||
data[HVAC_TOSHIBA_DATALEN - 1] = 0;
|
||||
for (uint32_t x = 0; x < HVAC_TOSHIBA_DATALEN - 1; x++) {
|
||||
data[HVAC_TOSHIBA_DATALEN - 1] = (uint8_t)data[x] ^ data[HVAC_TOSHIBA_DATALEN - 1]; // CRC is a simple bits addition
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
uint8_t mask = 1;
|
||||
|
||||
//header
|
||||
rawdata[i++] = HVAC_TOSHIBA_HDR_MARK;
|
||||
rawdata[i++] = HVAC_TOSHIBA_HDR_SPACE;
|
||||
|
||||
//data
|
||||
for (uint32_t b = 0; b < HVAC_TOSHIBA_DATALEN; b++) {
|
||||
for (mask = B10000000; mask > 0; mask >>= 1) { //iterate through bit mask
|
||||
if (data[b] & mask) { // Bit ONE
|
||||
rawdata[i++] = HVAC_TOSHIBA_BIT_MARK;
|
||||
rawdata[i++] = HVAC_TOSHIBA_ONE_SPACE;
|
||||
}
|
||||
else { // Bit ZERO
|
||||
rawdata[i++] = HVAC_TOSHIBA_BIT_MARK;
|
||||
rawdata[i++] = HVAC_MISTUBISHI_ZERO_SPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//trailer
|
||||
rawdata[i++] = HVAC_TOSHIBA_RPT_MARK;
|
||||
rawdata[i++] = HVAC_TOSHIBA_RPT_SPACE;
|
||||
|
||||
// noInterrupts();
|
||||
irsend->sendRaw(rawdata, i, 38);
|
||||
irsend->sendRaw(rawdata, i, 38);
|
||||
// interrupts();
|
||||
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
#endif // USE_IR_HVAC_TOSHIBA
|
||||
|
||||
#ifdef USE_IR_HVAC_MIDEA
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Midea / Komeco
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
// http://veillard.com/embedded/midea.html
|
||||
// https://github.com/sheinz/esp-midea-ir/blob/master/midea-ir.c
|
||||
|
||||
const uint16_t HVAC_MIDEA_HDR_MARK = 4420; // 8T high
|
||||
const uint16_t HVAC_MIDEA_HDR_SPACE = 4420; // 8T low
|
||||
const uint16_t HVAC_MIDEA_BIT_MARK = 553; // 1T
|
||||
const uint16_t HVAC_MIDEA_ONE_SPACE = 1660; // 3T low
|
||||
const uint16_t HVAC_MIDEA_ZERO_SPACE = 553; // 1T high
|
||||
const uint16_t HVAC_MIDEA_RPT_MARK = 553; // 1T
|
||||
const uint16_t HVAC_MIDEA_RPT_SPACE = 5530; // 10T
|
||||
const uint8_t HVAC_MIDEA_DATALEN = 3;
|
||||
|
||||
uint8_t IrHvacMidea(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||
{
|
||||
uint16_t rawdata[2 + 2 * 2 * 8 * HVAC_MIDEA_DATALEN + 2]; // START + 2* (2 * 3 BYTES) + STOP
|
||||
uint8_t data[HVAC_MIDEA_DATALEN] = {0xB2, 0x00, 0x00};
|
||||
|
||||
char *p;
|
||||
uint8_t mode;
|
||||
|
||||
if (!HVAC_Power) { // Turn OFF HVAC
|
||||
data[1] = 0x7B;
|
||||
data[2] = 0xE0;
|
||||
} else {
|
||||
// FAN
|
||||
if (HVAC_FanMode == nullptr) {
|
||||
p = (char*)kFanSpeedOptions; // default auto
|
||||
}
|
||||
else {
|
||||
p = (char*)HVAC_FanMode;
|
||||
}
|
||||
|
||||
switch(p[0]) {
|
||||
case '1': data[1] = 0xBF; break; // off
|
||||
case '2': data[1] = 0x9F; break; // low
|
||||
case '3': data[1] = 0x5F; break; // med
|
||||
case '4': data[1] = 0x3F; break; // high
|
||||
case '5': data[1] = 0x1F; break; // auto
|
||||
case 'A': data[1] = 0x1F; break; // auto
|
||||
default: return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
|
||||
// TEMPERATURE
|
||||
uint8_t Temp;
|
||||
if (HVAC_Temp > 30) {
|
||||
Temp = 30;
|
||||
}
|
||||
else if (HVAC_Temp < 17) {
|
||||
Temp = 17;
|
||||
}
|
||||
else {
|
||||
Temp = HVAC_Temp-17;
|
||||
}
|
||||
if (10 == Temp) { // Temp is encoded as gray code; except 27 and 28. Go figure...
|
||||
data[2] = 0x90;
|
||||
} else if (11 == Temp) {
|
||||
data[2] = 0x80;
|
||||
} else {
|
||||
Temp = (Temp >> 1) ^Temp;
|
||||
data[2] = (Temp << 4);
|
||||
}
|
||||
|
||||
// MODE
|
||||
if (HVAC_Mode == nullptr) {
|
||||
p = (char*)kHvacModeOptions + 3; // default to auto
|
||||
}
|
||||
else {
|
||||
p = (char*)HVAC_Mode;
|
||||
}
|
||||
switch(toupper(p[0])) {
|
||||
case 'D': data[2] = 0xE4; break; // for fan Temp must be 0XE
|
||||
case 'C': data[2] = 0x0 | data[2]; break;
|
||||
case 'A': data[2] = 0x8 | data[2]; data[1] = 0x1F; break; // for auto Fan must be 0x1
|
||||
case 'H': data[2] = 0xC | data[2]; break;
|
||||
default: return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
uint8_t mask = 1;
|
||||
|
||||
//header
|
||||
rawdata[i++] = HVAC_MIDEA_HDR_MARK;
|
||||
rawdata[i++] = HVAC_MIDEA_HDR_SPACE;
|
||||
|
||||
//data
|
||||
for (int b = 0; b < HVAC_MIDEA_DATALEN; b++) { // Send value
|
||||
for (mask = B10000000; mask > 0; mask >>= 1) {
|
||||
if (data[b] & mask) { // Bit ONE
|
||||
rawdata[i++] = HVAC_MIDEA_BIT_MARK;
|
||||
rawdata[i++] = HVAC_MIDEA_ONE_SPACE;
|
||||
}
|
||||
else { // Bit ZERO
|
||||
rawdata[i++] = HVAC_MIDEA_BIT_MARK;
|
||||
rawdata[i++] = HVAC_MIDEA_ZERO_SPACE;
|
||||
}
|
||||
}
|
||||
for (mask = B10000000; mask > 0; mask >>= 1) { // Send complement
|
||||
if (data[b] & mask) { // Bit ONE
|
||||
rawdata[i++] = HVAC_MIDEA_BIT_MARK;
|
||||
rawdata[i++] = HVAC_MIDEA_ZERO_SPACE;
|
||||
}
|
||||
else { // Bit ZERO
|
||||
rawdata[i++] = HVAC_MIDEA_BIT_MARK;
|
||||
rawdata[i++] = HVAC_MIDEA_ONE_SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//trailer
|
||||
rawdata[i++] = HVAC_MIDEA_RPT_MARK;
|
||||
rawdata[i++] = HVAC_MIDEA_RPT_SPACE;
|
||||
|
||||
// this takes ~180 ms :
|
||||
irsend->sendRaw(rawdata, i, 38);
|
||||
irsend->sendRaw(rawdata, i, 38);
|
||||
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
#endif // USE_IR_HVAC_MIDEA
|
||||
|
||||
#ifdef USE_IR_HVAC_MITSUBISHI
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Mitsubishi
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include <ir_Mitsubishi.h>
|
||||
|
||||
uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||
{
|
||||
char *p;
|
||||
uint8_t mode;
|
||||
|
||||
IRMitsubishiAC mitsubir(pin[GPIO_IRSEND]);
|
||||
|
||||
mitsubir.stateReset();
|
||||
|
||||
if (HVAC_Mode == nullptr) {
|
||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||
}
|
||||
else {
|
||||
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
mode = (p - kHvacModeOptions + 1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
|
||||
mitsubir.setMode(mode);
|
||||
|
||||
mitsubir.setPower(HVAC_Power);
|
||||
|
||||
if (HVAC_FanMode == nullptr) {
|
||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||
}
|
||||
else {
|
||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
mode = p - kFanSpeedOptions; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
|
||||
mitsubir.setFan(mode);
|
||||
|
||||
mitsubir.setTemp(HVAC_Temp);
|
||||
mitsubir.setVane(MITSUBISHI_AC_VANE_AUTO);
|
||||
mitsubir.send();
|
||||
|
||||
// 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());
|
||||
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
#endif // USE_IR_HVAC_MITSUBISHI
|
||||
|
||||
#ifdef USE_IR_HVAC_LG
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* LG
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
const uint8_t HVAC_LG_DATALEN = 7;
|
||||
|
||||
uint8_t IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||
{
|
||||
uint32_t LG_Code;
|
||||
uint8_t data[HVAC_LG_DATALEN];
|
||||
static bool hvacOn = false;
|
||||
char *p;
|
||||
uint8_t mode;
|
||||
uint8_t Temp;
|
||||
|
||||
// Constant data
|
||||
data[0] = 0x08;
|
||||
data[1] = 0x08;
|
||||
data[2] = 0x00;
|
||||
|
||||
if (!HVAC_Power) {
|
||||
data[2] = (uint8_t)0x0C; // Turn OFF HVAC, code 0x88C0051
|
||||
data[3] = (uint8_t)0x00;
|
||||
data[4] = (uint8_t)0x00;
|
||||
data[5] = (uint8_t)0x05;
|
||||
data[6] = (uint8_t)0x01;
|
||||
hvacOn = false;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// Set code for HVAC Mode - data[3]
|
||||
if (HVAC_Mode == nullptr) {
|
||||
p = (char *)kHvacModeOptions; // default HVAC_HOT
|
||||
}
|
||||
else {
|
||||
p = strchr(kHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
mode = (p - kHvacModeOptions) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
||||
switch (mode) {
|
||||
case 0: // AUTO
|
||||
data[3] = 11;
|
||||
break;
|
||||
case 1: // COOL
|
||||
data[3] = 8;
|
||||
break;
|
||||
case 2: // DRY
|
||||
data[3] = 9;
|
||||
break;
|
||||
case 3: // HOT
|
||||
data[3] = 12;
|
||||
break;
|
||||
}
|
||||
if (!hvacOn) {
|
||||
data[3] = data[3] & 7; // reset bit3
|
||||
hvacOn = true;
|
||||
}
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: HvacMode %s, ModeVal %d, Code %d"), p, mode, data[3]);
|
||||
|
||||
// Set code for HVAC temperature - data[4]
|
||||
if (HVAC_Temp > 30) {
|
||||
Temp = 30;
|
||||
}
|
||||
else if (HVAC_Temp < 18) {
|
||||
Temp = 18;
|
||||
}
|
||||
else {
|
||||
Temp = HVAC_Temp;
|
||||
}
|
||||
data[4] = (uint8_t)(Temp - 15);
|
||||
|
||||
// Set code for HVAC fan mode - data[5]
|
||||
if (HVAC_FanMode == nullptr) {
|
||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||
}
|
||||
else {
|
||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
mode = p - kFanSpeedOptions;
|
||||
if ((mode == 0) || (mode > 3)) {
|
||||
data[5] = 5; // Auto = 0x05
|
||||
}
|
||||
else {
|
||||
data[5] = (mode * 2) - 2; // Low = 0x00, Mid = 0x02, High = 0x04
|
||||
}
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: FanMode %s, ModeVal %d, Code %d"), p, mode, data[5]);
|
||||
|
||||
// Set CRC code - data[6]
|
||||
data[6] = (data[3] + data[4] + data[5]) & 0x0f; // CRC
|
||||
|
||||
}
|
||||
// Build LG IR code
|
||||
LG_Code = data[0] << 4;
|
||||
for (uint32_t i = 1; i < 6; i++) {
|
||||
LG_Code = (LG_Code + data[i]) << 4;
|
||||
}
|
||||
LG_Code = LG_Code + data[6];
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRHVAC: LG_Code %d"), LG_Code);
|
||||
|
||||
// Send LG IR Code
|
||||
irsend->sendLG(LG_Code, 28);
|
||||
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
#endif // USE_IR_HVAC_LG
|
||||
|
||||
#ifdef USE_IR_HVAC_FUJITSU
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Fujitsu
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include <ir_Fujitsu.h>
|
||||
|
||||
uint8_t IrHvacFujitsu(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||
{
|
||||
const char kFujitsuHvacModeOptions[] = "HDCAF";
|
||||
|
||||
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("FUJITSU: mode:%s, fan:%s, power:%u, temp:%u"), HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
|
||||
|
||||
IRFujitsuAC ac(pin[GPIO_IRSEND]);
|
||||
|
||||
if (0 == HVAC_Power) {
|
||||
ac.off();
|
||||
ac.send();
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
|
||||
uint8_t modes[5] = {FUJITSU_AC_MODE_HEAT, FUJITSU_AC_MODE_DRY, FUJITSU_AC_MODE_COOL, FUJITSU_AC_MODE_AUTO, FUJITSU_AC_MODE_FAN};
|
||||
uint8_t fanModes[7] = {FUJITSU_AC_FAN_AUTO, FUJITSU_AC_FAN_LOW, FUJITSU_AC_FAN_MED, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_HIGH, FUJITSU_AC_FAN_QUIET};
|
||||
ac.setCmd(FUJITSU_AC_CMD_TURN_ON);
|
||||
ac.setSwing(FUJITSU_AC_SWING_VERT);
|
||||
|
||||
char *p;
|
||||
if (nullptr == HVAC_Mode) {
|
||||
p = (char *)kFujitsuHvacModeOptions;
|
||||
}
|
||||
else {
|
||||
p = strchr(kFujitsuHvacModeOptions, toupper(HVAC_Mode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
ac.setMode(modes[p - kFujitsuHvacModeOptions]);
|
||||
|
||||
if (HVAC_FanMode == nullptr) {
|
||||
p = (char *)kFanSpeedOptions; // default FAN_SPEED_AUTO
|
||||
}
|
||||
else {
|
||||
p = strchr(kFanSpeedOptions, toupper(HVAC_FanMode[0]));
|
||||
}
|
||||
if (!p) {
|
||||
return IE_SYNTAX_IRHVAC;
|
||||
}
|
||||
ac.setFanSpeed(fanModes[p - kFanSpeedOptions]);
|
||||
|
||||
ac.setTemp(HVAC_Temp);
|
||||
ac.send();
|
||||
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
#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;
|
||||
char parm_uc[12];
|
||||
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[UpperCase_P(parm_uc, PSTR(D_JSON_IRHVAC_VENDOR))];
|
||||
HVAC_Power = root[UpperCase_P(parm_uc, PSTR(D_JSON_IRHVAC_POWER))];
|
||||
HVAC_Mode = root[UpperCase_P(parm_uc, PSTR(D_JSON_IRHVAC_MODE))];
|
||||
HVAC_FanMode = root[UpperCase_P(parm_uc, PSTR(D_JSON_IRHVAC_FANSPEED))];
|
||||
HVAC_Temp = root[UpperCase_P(parm_uc, PSTR(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
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
||||
uint32_t IrRemoteCmndIrSendRaw(void)
|
||||
{
|
||||
// IRsend <freq>,<rawdata>,<rawdata> ...
|
||||
// or
|
||||
// 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>
|
||||
|
||||
char *p;
|
||||
char *str = strtok_r(XdrvMailbox.data, ", ", &p);
|
||||
if (p == nullptr) {
|
||||
return IE_INVALID_RAWDATA;
|
||||
}
|
||||
|
||||
// repeat
|
||||
uint16_t repeat = XdrvMailbox.index > 0 ? XdrvMailbox.index - 1 : 0;
|
||||
|
||||
uint16_t freq = atoi(str);
|
||||
if (!freq && (*str != '0')) { // First parameter is any string
|
||||
uint16_t count = 0;
|
||||
char *q = p;
|
||||
for (; *q; count += (*q++ == ','));
|
||||
if (count < 2) {
|
||||
return IE_INVALID_RAWDATA;
|
||||
} // Parameters must be at least 3
|
||||
|
||||
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 {
|
||||
return IE_INVALID_RAWDATA; // Other parameters may not be 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
for (uint32_t r = 0; r <= repeat; r++) {
|
||||
irsend->sendRaw(raw_array, i, parm[0]);
|
||||
if (r < repeat) { // if it's not the last message
|
||||
irsend->space(40000); // since we don't know the inter-message gap, place an arbitrary 40ms gap
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
uint32_t inter_message_32 = (parm[1] + parm[2]) * 3; // compute an inter-message gap (32 bits)
|
||||
uint16_t inter_message = (inter_message_32 > 65000) ? 65000 : inter_message_32; // avoid 16 bits overflow
|
||||
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;
|
||||
for (uint32_t r = 0; r <= repeat; r++) {
|
||||
irsend->sendRaw(raw_array, i, parm[0]);
|
||||
if (r < repeat) { // if it's not the last message
|
||||
irsend->space(inter_message); // since we don't know the inter-message gap, place an arbitrary 40ms gap
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
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;
|
||||
for (uint32_t r = 0; r <= repeat; r++) {
|
||||
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;
|
||||
for (uint32_t r = 0; r <= repeat; r++) {
|
||||
irsend->sendRaw(raw_array, count, freq);
|
||||
}
|
||||
free(raw_array);
|
||||
}
|
||||
}
|
||||
|
||||
return IE_NO_ERROR;
|
||||
}
|
||||
|
||||
uint32_t IrRemoteCmndIrSendJson(void)
|
||||
{
|
||||
// ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(3) + 40 = 96
|
||||
|
@ -936,54 +230,6 @@ uint32_t IrRemoteCmndIrSendJson(void)
|
|||
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;
|
||||
ResponseCmndChar(D_JSON_PROTOCOL_NOT_SUPPORTED);
|
||||
|
@ -999,7 +245,7 @@ void CmndIrSend(void)
|
|||
if (XdrvMailbox.data_len) {
|
||||
// error = (strstr(XdrvMailbox.data, "{") == nullptr) ? IrRemoteCmndIrSendRaw() : IrRemoteCmndIrSendJson();
|
||||
if (strstr(XdrvMailbox.data, "{") == nullptr) {
|
||||
error = IrRemoteCmndIrSendRaw();
|
||||
error = IE_INVALID_JSON;
|
||||
} else {
|
||||
error = IrRemoteCmndIrSendJson();
|
||||
}
|
||||
|
@ -1019,11 +265,6 @@ void IrRemoteCmndResponse(uint32_t error)
|
|||
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 "\"}"));
|
||||
break;
|
||||
#ifdef USE_IR_HVAC
|
||||
case IE_SYNTAX_IRHVAC:
|
||||
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;
|
||||
#endif // USE_IR_HVAC
|
||||
default: // IE_NO_ERROR
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue