mirror of https://github.com/arendst/Tasmota.git
Add support for optional IRHVAC Midea/Komeco protocol
Add support for optional IRHVAC Midea/Komeco protocol (#3227)
This commit is contained in:
parent
0e7cef7426
commit
ce13c0cf8f
|
@ -4,6 +4,7 @@
|
||||||
* Add support for a buzzer
|
* Add support for a buzzer
|
||||||
* Add command SetOption67 0/1 to disable or enable a buzzer as used in iFan03
|
* 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 IRSend long press ('repeat' feature from IRRemoteESP8266) (#6074)
|
||||||
|
* Add support for optional IRHVAC Midea/Komeco protocol (#3227)
|
||||||
*
|
*
|
||||||
* 6.6.0.1 20190708
|
* 6.6.0.1 20190708
|
||||||
* Fix Domoticz battery level set to 100 if define USE_ADC_VCC is not used (#6033)
|
* Fix Domoticz battery level set to 100 if define USE_ADC_VCC is not used (#6033)
|
||||||
|
|
|
@ -449,6 +449,7 @@
|
||||||
#define USE_IR_HVAC_MITSUBISHI // Support IRhvac Mitsubischi protocol
|
#define USE_IR_HVAC_MITSUBISHI // Support IRhvac Mitsubischi protocol
|
||||||
#define USE_IR_HVAC_LG // Support IRhvac LG protocol
|
#define USE_IR_HVAC_LG // Support IRhvac LG protocol
|
||||||
#define USE_IR_HVAC_FUJITSU // Support IRhvac Fujitsu 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 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))
|
#define IR_RCV_BUFFER_SIZE 100 // Max number of packets allowed in capture buffer (default 100 (*2 bytes ram))
|
||||||
|
|
|
@ -40,21 +40,10 @@ const char kIrRemoteProtocols[] PROGMEM =
|
||||||
#include <ir_Mitsubishi.h>
|
#include <ir_Mitsubishi.h>
|
||||||
#include <ir_Fujitsu.h>
|
#include <ir_Fujitsu.h>
|
||||||
|
|
||||||
enum IrHvacVendors { VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU };
|
enum IrHvacVendors {
|
||||||
const char kIrHvacVendors[] PROGMEM = "Toshiba|Mitsubishi|LG|Fujitsu" ;
|
VNDR_TOSHIBA, VNDR_MITSUBISHI, VNDR_LG, VNDR_FUJITSU, VNDR_MIDEA };
|
||||||
|
const char kIrHvacVendors[] PROGMEM =
|
||||||
// HVAC TOSHIBA_
|
"Toshiba|Mitsubishi|LG|Fujitsu|Midea" ;
|
||||||
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;
|
|
||||||
|
|
||||||
IRMitsubishiAC *mitsubir = nullptr;
|
IRMitsubishiAC *mitsubir = nullptr;
|
||||||
|
|
||||||
|
@ -212,6 +201,15 @@ void IrReceiveCheck(void)
|
||||||
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)
|
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];
|
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
|
#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
|
#ifdef USE_IR_HVAC_MITSUBISHI
|
||||||
/*******************
|
/*******************
|
||||||
MITSUBISHI
|
MITSUBISHI
|
||||||
|
@ -357,6 +484,8 @@ uint8_t IrHvacMitsubishi(const char *HVAC_Mode, const char *HVAC_FanMode, bool H
|
||||||
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)
|
uint8_t IrHvacLG(const char *HVAC_Mode, const char *HVAC_FanMode, bool HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
uint32_t LG_Code;
|
uint32_t LG_Code;
|
||||||
|
@ -822,6 +951,10 @@ bool IrSendCommand(void)
|
||||||
#ifdef USE_IR_HVAC_FUJITSU
|
#ifdef USE_IR_HVAC_FUJITSU
|
||||||
case VNDR_FUJITSU:
|
case VNDR_FUJITSU:
|
||||||
error = IrHvacFujitsu(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); break;
|
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
|
#endif
|
||||||
default:
|
default:
|
||||||
error = IE_SYNTAX_IRHVAC;
|
error = IE_SYNTAX_IRHVAC;
|
||||||
|
|
Loading…
Reference in New Issue