From 862f4bc0d3698fa0996fea53a1a4a19ff45a819c Mon Sep 17 00:00:00 2001 From: Andrey Klimov Date: Wed, 18 Sep 2019 00:38:15 +0300 Subject: [PATCH] Air conditioner driver (Haier) - working now Small cold restart LED color restore issue fixed command enlarged to 8 bit --- lighthub/inputs.cpp | 6 +- lighthub/item.cpp | 46 ++++++++----- lighthub/item.h | 17 +++-- lighthub/modules/out_ac.cpp | 130 +++++++++++++++++------------------- 4 files changed, 103 insertions(+), 96 deletions(-) diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index 5626e56..45b9553 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -231,7 +231,7 @@ void Input::counterPoll() { if (mqttClient.connected() && !ethernetIdleCount) mqttClient.publish(addrstr, valstr); setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT); - debugSerial<type == aJson_Int){ - if (!n) return itemArg->valueint; else return -1; + if (!n) return itemArg->valueint; else return 0;//-1; } if ((itemArg->type == aJson_Array) && ( n < aJson.getArraySize(itemArg))) return aJson.getArrayItem(itemArg, n)->valueint; - else return -2; + else return 0;//-2; } /* @@ -273,13 +278,13 @@ int Item::getVal(short n) //Return Val from Value array long int Item::getVal() //Return Val if val is int or first elem of Value array { - if (!itemVal) return -1; + if (!itemVal) return 0;//-1; if (itemVal->type == aJson_Int) return itemVal->valueint; else if (itemVal->type == aJson_Array) { aJsonObject *t = aJson.getArrayItem(itemVal, 0); if (t) return t->valueint; - else return -3; - } else return -2; + else return 0;//-3; + } else return 0;//-2; } /* @@ -577,7 +582,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode case CMD_AUTO: case CMD_HEAT: - if (itemType==CH_RGBW && getCmd() == CMD_ON /*&& getEnableCMD(500) */) { + if (itemType==CH_RGBW && getCmd() == CMD_ON && send /*&& getEnableCMD(500) */) { debugSerial< 0) //Stored smthng + if (st.aslong ) //Stored smthng switch (itemType) { case CH_GROUP: @@ -749,6 +754,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode #ifdef _dmxout case CH_DIMMER: //Dimmed light + if (iaddr>0) DmxWrite(iaddr, map(Par[0], 0, 100, 0, 255)); break; case CH_RGBW: //Colour RGBW @@ -757,7 +763,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode //50..100 RGB { int k; - if (Par[1]<50) { // Using white + if (Par[1]<50 && iaddr>0) { // Using white DmxWrite(iaddr + 3, map((50 - Par[1]) * Par[2], 0, 5000, 0, 255)); int rgbvLevel = map (Par[1],0,50,0,255*2); rgbValue = map(Par[2], 0, 100, 0, rgbvLevel); @@ -768,12 +774,13 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode { //rgbValue = map(Par[2], 0, 100, 0, 255); rgbSaturation = map(Par[1], 50, 100, 100, 255); - DmxWrite(iaddr + 3, 0); + if (iaddr>0) DmxWrite(iaddr + 3, 0); } //DmxWrite(iaddr + 3, k = map((100 - Par[1]) * Par[2], 0, 10000, 0, 255)); //debugSerial<0) { CRGB rgb = CHSV(map(Par[0], 0, 365, 0, 255), rgbSaturation, rgbValue); DmxWrite(iaddr, rgb.r); @@ -782,11 +789,14 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode break; } case CH_WHITE: + if (iaddr>0) + { DmxWrite(iaddr, 0); DmxWrite(iaddr + 1, 0); DmxWrite(iaddr + 2, 0); DmxWrite(iaddr + 3, map(Par[2], 0, 100, 0, 255)); break; + } #endif #ifdef _modbus @@ -808,7 +818,9 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode } //if } //case break; - case CH_RELAY: { + case CH_RELAY: + if (iaddr) + { int k; short inverse = 0; @@ -829,7 +841,9 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode ///thermoSet(name,cmd,Par1); all activities done - update temp & cmd break; - case CH_PWM: { + case CH_PWM: + if (iaddr) + { int k; short inverse = 0; diff --git a/lighthub/item.h b/lighthub/item.h index 80626ed..7374ac9 100644 --- a/lighthub/item.h +++ b/lighthub/item.h @@ -73,15 +73,18 @@ e-mail anklimov@gmail.com #define CMD_FAN 0xd #define CMD_DRY 0xe #define CMD_SET 0xf -#define CMD_CURTEMP 0xf -#define CMD_MASK 0xf -#define FLAG_MASK 0xf0 +#define CMD_HIGH 0x10 +#define CMD_MED 0x11 +#define CMD_LOW 0x12 +//#define CMD_CURTEMP 0xf +#define CMD_MASK 0xff +#define FLAG_MASK 0x0f00 -#define SEND_COMMAND 16 -#define SEND_PARAMETERS 32 -#define SEND_RETRY 64 -#define SEND_DEFFERED 128 +#define SEND_COMMAND 0x100 +#define SEND_PARAMETERS 0x200 +#define SEND_RETRY 0x400 +#define SEND_DEFFERED 0x800 //#define CMD_REPORT 32 diff --git a/lighthub/modules/out_ac.cpp b/lighthub/modules/out_ac.cpp index c263aad..3059f7b 100644 --- a/lighthub/modules/out_ac.cpp +++ b/lighthub/modules/out_ac.cpp @@ -26,18 +26,22 @@ byte qstn[] = {255,255,10,0,0,0,0,0,1,1,77,1,90}; // Команда опроса byte data[37] = {}; //Массив данных byte on[] = {255,255,10,0,0,0,0,0,1,1,77,2,91}; // Включение кондиционера byte off[] = {255,255,10,0,0,0,0,0,1,1,77,3,92}; // Выключение кондиционера -// byte lock[] = {255,255,10,0,0,0,0,0,1,3,0,0,14}; // Блокировка пульта +byte lock[] = {255,255,10,0,0,0,0,0,1,3,0,0,14}; // Блокировка пульта //Extended subItem set const char LOCK_P[] PROGMEM = "lock"; const char QUIET_P[] PROGMEM = "queit"; const char SWING_P[] PROGMEM = "swing"; const char RAW_P[] PROGMEM = "raw"; +//const char IDLE_P[] PROGMEM = "IDLE"; extern char HEAT_P[] PROGMEM; extern char COOL_P[] PROGMEM; extern char AUTO_P[] PROGMEM; extern char FAN_ONLY_P[] PROGMEM; extern char DRY_P[] PROGMEM; +extern char HIGH_P[] PROGMEM; +extern char MED_P[] PROGMEM; +extern char LOW_P[] PROGMEM; void out_AC::InsertData(byte data[], size_t size){ @@ -80,20 +84,33 @@ void out_AC::InsertData(byte data[], size_t size){ else publishTopic(item->itemArr->name, "OFF" , "/quiet"); - if (power == 3 || power == 2) - publishTopic(item->itemArr->name, "on","/compressor"); + if (power & 0x02) //Compressor on + publishTopic(item->itemArr->name, "ON","/compressor"); else - publishTopic(item->itemArr->name, "off","/compressor"); + publishTopic(item->itemArr->name, "OFF","/compressor"); publishTopic(item->itemArr->name, (long) swing,"/swing"); - publishTopic(item->itemArr->name, (long) fan_spd,"/fan"); + //publishTopic(item->itemArr->name, (long) fan_spd,"/fan"); ///////////////////////////////// -/* - if (swing == 0x00){ - publishTopic(item->itemArr->name, "off","swing"); + if (fan_spd == 0x00){ + publishTopic(item->itemArr->name, "high","/fan"); } + if (fan_spd == 0x01){ + publishTopic(item->itemArr->name, "medium","/fan"); + } + if (fan_spd == 0x02){ + publishTopic(item->itemArr->name, "low","/fan"); + } + if (fan_spd == 0x03){ + publishTopic(item->itemArr->name, "auto","/fan"); + } + + if (swing == 0x00) + publishTopic(item->itemArr->name, "OFF","/swing"); + else publishTopic(item->itemArr->name, "ON","/swing"); + /* if (swing == 0x01){ publishTopic(item->itemArr->name, "ud","swing"); } @@ -102,21 +119,7 @@ void out_AC::InsertData(byte data[], size_t size){ } if (swing == 0x03){ publishTopic(item->itemArr->name, "all","swing"); - } - ///////////////////////////////// - if (fan_spd == 0x00){ - publishTopic(item->itemArr->name, "max","fan"); - } - if (fan_spd == 0x01){ - publishTopic(item->itemArr->name, "mid","fan"); - } - if (fan_spd == 0x02){ - publishTopic(item->itemArr->name, "min","fan"); - } - if (fan_spd == 0x03){ - publishTopic(item->itemArr->name, "auto","fan"); - } - */ + }*/ ///////////////////////////////// publishTopic(item->itemArr->name,(long)set_tmp,"/set"); @@ -213,8 +216,6 @@ return (power & 1); int out_AC::Poll() { - //debugSerial<<"."; - long now = millis(); if (now - prevPolling > INTERVAL_AC_POLLING) { prevPolling = now; @@ -266,7 +267,7 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC break; case CMD_OFF: case CMD_HALT: - data[B_POWER] = 0; + data[B_POWER] &= ~1; SendData(off, sizeof(off)/sizeof(byte)); return 1; break; @@ -297,7 +298,23 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC break; case S_FAN: - data[B_FAN_SPD] = Parameters[0]; + switch (cmd) + { + case CMD_AUTO: + data[B_FAN_SPD] = 3; + break; + case CMD_HIGH: + data[B_FAN_SPD] = 0; + break; + case CMD_MED: + data[B_FAN_SPD] = 1; + break; + case CMD_LOW: + data[B_FAN_SPD] = 2; + break; + default: + if (n) data[B_FAN_SPD] = Parameters[0]; + } break; case S_MODE: @@ -317,7 +334,17 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC break; case S_SWING: - data[B_SWING] = Parameters[0]; + switch (cmd) + { + case CMD_ON: + data[B_LOCK_REM] = 3; + break; + case CMD_OFF: + data[B_LOCK_REM] = 0; + break; + default: + if (n) data[B_SWING] = Parameters[0]; + } break; case S_QUIET: @@ -345,12 +372,8 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC hexbyte[0] = buf[i] ; hexbyte[1] = buf[i+1] ; data[i/2] = (toHex(hexbyte[0]) << 4) | toHex(hexbyte[1]); - - - AC_Serial.write(data, 37); AC_Serial.flush(); - publishTopic("RAW", buf); } */ @@ -364,21 +387,7 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC /* ////////// - if (strTopic == "/myhome/in/Conditioner/Fan_Speed"){ - if (strPayload == "max"){ - data[B_FAN_SPD] = 0; - } - if (strPayload == "mid"){ - data[B_FAN_SPD] = 1; - } - if (strPayload == "min"){ - data[B_FAN_SPD] = 2; - } - if (strPayload == "auto"){ - data[B_FAN_SPD] = 3; - } - } - //////// + if (strTopic == "/myhome/in/Conditioner/Swing"){ if (strPayload == "off"){ data[B_SWING] = 0; @@ -394,30 +403,9 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC } } //////// - if (strTopic == "/myhome/in/Conditioner/Lock_Remote"){ - if (strPayload == "true"){ - data[B_LOCK_REM] = 80; - } - if (strPayload == "false"){ - data[B_LOCK_REM] = 0; - } - } - //////// - if (strTopic == "/myhome/in/Conditioner/Power"){ - if (strPayload == "off" || strPayload == "false" || strPayload == "0"){ - SendData(off, sizeof(off)/sizeof(byte)); - return; - } - if (strPayload == "on" || strPayload == "true" || strPayload == "1"){ - SendData(on, sizeof(on)/sizeof(byte)); - return; - } - if (strPayload == "quiet"){ - data[B_POWER] = 9; - } - } + */ - //////// + //if (strTopic == "/myhome/in/Conditioner/RAW") data[B_CMD] = 0; @@ -425,6 +413,8 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC data[10] = 77; data[11] = 95; SendData(data, sizeof(data)/sizeof(byte)); + InsertData(data, sizeof(data)/sizeof(byte)); + return 1; }