Add support for optional IRHVAC Midea/Komeco protocol

Add support for optional IRHVAC Midea/Komeco protocol (#3227)
This commit is contained in:
Theo Arends 2019-07-21 18:06:13 +02:00
parent 0e7cef7426
commit ce13c0cf8f
3 changed files with 150 additions and 15 deletions

View File

@ -4,6 +4,7 @@
* Add support for a buzzer
* Add command SetOption67 0/1 to disable or enable a buzzer as used in iFan03
* Add support IRSend long press ('repeat' feature from IRRemoteESP8266) (#6074)
* Add support for optional IRHVAC Midea/Komeco protocol (#3227)
*
* 6.6.0.1 20190708
* Fix Domoticz battery level set to 100 if define USE_ADC_VCC is not used (#6033)

View File

@ -449,6 +449,7 @@
#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))

View File

@ -40,21 +40,10 @@ const char kIrRemoteProtocols[] PROGMEM =
#include <ir_Mitsubishi.h>
#include <ir_Fujitsu.h>
enum IrHvacVendors { VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU };
const char kIrHvacVendors[] PROGMEM = "Toshiba|Mitsubishi|LG|Fujitsu" ;
// HVAC 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;
// HVAC LG
const uint8_t HVAC_LG_DATALEN = 7;
enum IrHvacVendors {
VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU, VNDR_MIDEA };
const char kIrHvacVendors[] PROGMEM =
"Toshiba|Mitsubishi|LG|Fujitsu|Midea" ;
IRMitsubishiAC *mitsubir = nullptr;
@ -212,6 +201,15 @@ void IrReceiveCheck(void)
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];
@ -303,6 +301,135 @@ uint8_t IrHvacToshiba(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC
}
#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;
// noInterrupts();
// this takes ~180 ms :
irsend->sendRaw(rawdata, i, 38);
irsend->sendRaw(rawdata, i, 38);
// interrupts();
return IE_NO_ERROR;
}
#endif // USE_IR_HVAC_MIDEA
#ifdef USE_IR_HVAC_MITSUBISHI
/*******************
MITSUBISHI
@ -357,6 +484,8 @@ uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool H
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;
@ -822,6 +951,10 @@ bool IrSendCommand(void)
#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;