Air conditioner driver (Haier) - working now

Small cold restart LED color restore issue fixed
command enlarged to 8 bit
This commit is contained in:
2019-09-18 00:38:15 +03:00
parent 9a0cff1f63
commit 862f4bc0d3
4 changed files with 103 additions and 96 deletions

View File

@@ -231,7 +231,7 @@ void Input::counterPoll() {
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
mqttClient.publish(addrstr, valstr); mqttClient.publish(addrstr, valstr);
setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT); setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT);
debugSerial<<F(" NextPollMillis=")<<nextPollTime(); // debugSerial<<F(" NextPollMillis=")<<nextPollTime();
} }
else else
debugSerial<<F(" No emit data!"); debugSerial<<F(" No emit data!");
@@ -400,7 +400,7 @@ void Input::dht22Poll() {
mqttClient.publish(addrstr, valstr); mqttClient.publish(addrstr, valstr);
setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT); setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT);
debugSerial << F(" NextPollMillis=") << nextPollTime() << endl; // debugSerial << F(" NextPollMillis=") << nextPollTime() << endl;
} else } else
setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT / 3); setNextPollTime(millis() + DHT_POLL_DELAY_DEFAULT / 3);
} }
@@ -619,7 +619,7 @@ bool Input::publishDataToDomoticz(int pollTimeIncrement, aJsonObject *emit, cons
mqttClient.publish(emit->valuestring, valstr); mqttClient.publish(emit->valuestring, valstr);
if (pollTimeIncrement) if (pollTimeIncrement)
setNextPollTime(millis() + pollTimeIncrement); setNextPollTime(millis() + pollTimeIncrement);
debugSerial << F(" NextPollMillis=") << nextPollTime() << endl; // debugSerial << F(" NextPollMillis=") << nextPollTime() << endl;
#endif #endif
return true; return true;

View File

@@ -54,7 +54,9 @@ char COOL_P[] PROGMEM = "COOL";
char AUTO_P[] PROGMEM = "AUTO"; char AUTO_P[] PROGMEM = "AUTO";
char FAN_ONLY_P[] PROGMEM = "FAN_ONLY"; char FAN_ONLY_P[] PROGMEM = "FAN_ONLY";
char DRY_P[] PROGMEM = "DRY"; char DRY_P[] PROGMEM = "DRY";
char HIGH_P[] PROGMEM = "HIGH";
char MED_P[] PROGMEM = "MEDIUM";
char LOW_P[] PROGMEM = "LOW";
// SubTopics // SubTopics
const char SET_P[] PROGMEM = "set"; const char SET_P[] PROGMEM = "set";
const char CMD_P[] PROGMEM = "cmd"; const char CMD_P[] PROGMEM = "cmd";
@@ -102,6 +104,9 @@ int txt2cmd(char *payload) {
else if (strcmp_P(payload, FALSE_P) == 0) cmd = CMD_OFF; else if (strcmp_P(payload, FALSE_P) == 0) cmd = CMD_OFF;
else if (strcmp_P(payload, INCREASE_P) == 0) cmd = CMD_UP; else if (strcmp_P(payload, INCREASE_P) == 0) cmd = CMD_UP;
else if (strcmp_P(payload, DECREASE_P) == 0) cmd = CMD_DN; else if (strcmp_P(payload, DECREASE_P) == 0) cmd = CMD_DN;
else if (strcmp_P(payload, HIGH_P) == 0) cmd = CMD_HIGH;
else if (strcmp_P(payload, MED_P) == 0) cmd = CMD_MED;
else if (strcmp_P(payload, LOW_P) == 0) cmd = CMD_LOW;
else if (*payload == '{') cmd = CMD_JSON; else if (*payload == '{') cmd = CMD_JSON;
else if (*payload == '#') cmd = CMD_RGB; else if (*payload == '#') cmd = CMD_RGB;
else if (strncmp_P(payload, HSV_P, strlen (HSV_P)) == 0) cmd = CMD_HSV; else if (strncmp_P(payload, HSV_P, strlen (HSV_P)) == 0) cmd = CMD_HSV;
@@ -153,14 +158,14 @@ void Item::Parse() {
#ifndef SPILED_DISABLE #ifndef SPILED_DISABLE
case CH_SPILED: case CH_SPILED:
driver = new out_SPILed (this); driver = new out_SPILed (this);
debugSerial<<F("SPILED driver created")<<endl; // debugSerial<<F("SPILED driver created")<<endl;
break; break;
#endif #endif
#ifndef AC_DISABLE #ifndef AC_DISABLE
case CH_AC: case CH_AC:
driver = new out_AC (this); driver = new out_AC (this);
debugSerial<<F("AC driver created")<<endl; // debugSerial<<F("AC driver created")<<endl;
break; break;
#endif #endif
default: ; default: ;
@@ -186,7 +191,7 @@ Item::~Item()
if (driver) if (driver)
{ {
delete driver; delete driver;
debugSerial<<F("Driver destroyed")<<endl; // debugSerial<<F("Driver destroyed")<<endl;
} }
} }
@@ -250,12 +255,12 @@ void Item::clearFlag (short flag)
int Item::getArg(short n) //Return arg int or first array element if Arg is array int Item::getArg(short n) //Return arg int or first array element if Arg is array
{ {
if (!itemArg) return -1; if (!itemArg) return 0;//-1;
if (itemArg->type == aJson_Int){ if (itemArg->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; 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 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; if (itemVal->type == aJson_Int) return itemVal->valueint;
else if (itemVal->type == aJson_Array) { else if (itemVal->type == aJson_Array) {
aJsonObject *t = aJson.getArrayItem(itemVal, 0); aJsonObject *t = aJson.getArrayItem(itemVal, 0);
if (t) return t->valueint; if (t) return t->valueint;
else return -3; else return 0;//-3;
} else return -2; } 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_AUTO:
case CMD_HEAT: case CMD_HEAT:
if (itemType==CH_RGBW && getCmd() == CMD_ON /*&& getEnableCMD(500) */) { if (itemType==CH_RGBW && getCmd() == CMD_ON && send /*&& getEnableCMD(500) */) {
debugSerial<<F("Force White\n"); debugSerial<<F("Force White\n");
itemType = CH_WHITE; itemType = CH_WHITE;
Par[1] = 0; //Zero saturation Par[1] = 0; //Zero saturation
@@ -616,7 +621,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
setVal(st.aslong); setVal(st.aslong);
} }
if (st.aslong > 0) //Stored smthng if (st.aslong ) //Stored smthng
switch (itemType) { switch (itemType) {
case CH_GROUP: case CH_GROUP:
@@ -749,6 +754,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
#ifdef _dmxout #ifdef _dmxout
case CH_DIMMER: //Dimmed light case CH_DIMMER: //Dimmed light
if (iaddr>0)
DmxWrite(iaddr, map(Par[0], 0, 100, 0, 255)); DmxWrite(iaddr, map(Par[0], 0, 100, 0, 255));
break; break;
case CH_RGBW: //Colour RGBW 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 //50..100 RGB
{ {
int k; 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)); DmxWrite(iaddr + 3, map((50 - Par[1]) * Par[2], 0, 5000, 0, 255));
int rgbvLevel = map (Par[1],0,50,0,255*2); int rgbvLevel = map (Par[1],0,50,0,255*2);
rgbValue = map(Par[2], 0, 100, 0, rgbvLevel); 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); //rgbValue = map(Par[2], 0, 100, 0, 255);
rgbSaturation = map(Par[1], 50, 100, 100, 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)); //DmxWrite(iaddr + 3, k = map((100 - Par[1]) * Par[2], 0, 10000, 0, 255));
//debugSerial<<F("W:")<<k<<endl; //debugSerial<<F("W:")<<k<<endl;
} }
case CH_RGB: // RGB case CH_RGB: // RGB
if (iaddr>0)
{ {
CRGB rgb = CHSV(map(Par[0], 0, 365, 0, 255), rgbSaturation, rgbValue); CRGB rgb = CHSV(map(Par[0], 0, 365, 0, 255), rgbSaturation, rgbValue);
DmxWrite(iaddr, rgb.r); DmxWrite(iaddr, rgb.r);
@@ -782,11 +789,14 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
break; break;
} }
case CH_WHITE: case CH_WHITE:
if (iaddr>0)
{
DmxWrite(iaddr, 0); DmxWrite(iaddr, 0);
DmxWrite(iaddr + 1, 0); DmxWrite(iaddr + 1, 0);
DmxWrite(iaddr + 2, 0); DmxWrite(iaddr + 2, 0);
DmxWrite(iaddr + 3, map(Par[2], 0, 100, 0, 255)); DmxWrite(iaddr + 3, map(Par[2], 0, 100, 0, 255));
break; break;
}
#endif #endif
#ifdef _modbus #ifdef _modbus
@@ -808,7 +818,9 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
} //if } //if
} //case } //case
break; break;
case CH_RELAY: { case CH_RELAY:
if (iaddr)
{
int k; int k;
short inverse = 0; 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 ///thermoSet(name,cmd,Par1); all activities done - update temp & cmd
break; break;
case CH_PWM: { case CH_PWM:
if (iaddr)
{
int k; int k;
short inverse = 0; short inverse = 0;

View File

@@ -73,15 +73,18 @@ e-mail anklimov@gmail.com
#define CMD_FAN 0xd #define CMD_FAN 0xd
#define CMD_DRY 0xe #define CMD_DRY 0xe
#define CMD_SET 0xf #define CMD_SET 0xf
#define CMD_CURTEMP 0xf #define CMD_HIGH 0x10
#define CMD_MASK 0xf #define CMD_MED 0x11
#define FLAG_MASK 0xf0 #define CMD_LOW 0x12
//#define CMD_CURTEMP 0xf
#define CMD_MASK 0xff
#define FLAG_MASK 0x0f00
#define SEND_COMMAND 16 #define SEND_COMMAND 0x100
#define SEND_PARAMETERS 32 #define SEND_PARAMETERS 0x200
#define SEND_RETRY 64 #define SEND_RETRY 0x400
#define SEND_DEFFERED 128 #define SEND_DEFFERED 0x800
//#define CMD_REPORT 32 //#define CMD_REPORT 32

View File

@@ -26,18 +26,22 @@ byte qstn[] = {255,255,10,0,0,0,0,0,1,1,77,1,90}; // Команда опроса
byte data[37] = {}; //Массив данных byte data[37] = {}; //Массив данных
byte on[] = {255,255,10,0,0,0,0,0,1,1,77,2,91}; // Включение кондиционера 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 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 //Extended subItem set
const char LOCK_P[] PROGMEM = "lock"; const char LOCK_P[] PROGMEM = "lock";
const char QUIET_P[] PROGMEM = "queit"; const char QUIET_P[] PROGMEM = "queit";
const char SWING_P[] PROGMEM = "swing"; const char SWING_P[] PROGMEM = "swing";
const char RAW_P[] PROGMEM = "raw"; const char RAW_P[] PROGMEM = "raw";
//const char IDLE_P[] PROGMEM = "IDLE";
extern char HEAT_P[] PROGMEM; extern char HEAT_P[] PROGMEM;
extern char COOL_P[] PROGMEM; extern char COOL_P[] PROGMEM;
extern char AUTO_P[] PROGMEM; extern char AUTO_P[] PROGMEM;
extern char FAN_ONLY_P[] PROGMEM; extern char FAN_ONLY_P[] PROGMEM;
extern char DRY_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){ 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"); else publishTopic(item->itemArr->name, "OFF" , "/quiet");
if (power == 3 || power == 2) if (power & 0x02) //Compressor on
publishTopic(item->itemArr->name, "on","/compressor"); publishTopic(item->itemArr->name, "ON","/compressor");
else 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) swing,"/swing");
publishTopic(item->itemArr->name, (long) fan_spd,"/fan"); //publishTopic(item->itemArr->name, (long) fan_spd,"/fan");
///////////////////////////////// /////////////////////////////////
/* if (fan_spd == 0x00){
if (swing == 0x00){ publishTopic(item->itemArr->name, "high","/fan");
publishTopic(item->itemArr->name, "off","swing");
} }
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){ if (swing == 0x01){
publishTopic(item->itemArr->name, "ud","swing"); publishTopic(item->itemArr->name, "ud","swing");
} }
@@ -102,21 +119,7 @@ void out_AC::InsertData(byte data[], size_t size){
} }
if (swing == 0x03){ if (swing == 0x03){
publishTopic(item->itemArr->name, "all","swing"); 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"); publishTopic(item->itemArr->name,(long)set_tmp,"/set");
@@ -213,8 +216,6 @@ return (power & 1);
int out_AC::Poll() int out_AC::Poll()
{ {
//debugSerial<<".";
long now = millis(); long now = millis();
if (now - prevPolling > INTERVAL_AC_POLLING) { if (now - prevPolling > INTERVAL_AC_POLLING) {
prevPolling = now; prevPolling = now;
@@ -266,7 +267,7 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC
break; break;
case CMD_OFF: case CMD_OFF:
case CMD_HALT: case CMD_HALT:
data[B_POWER] = 0; data[B_POWER] &= ~1;
SendData(off, sizeof(off)/sizeof(byte)); SendData(off, sizeof(off)/sizeof(byte));
return 1; return 1;
break; break;
@@ -297,7 +298,23 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC
break; break;
case S_FAN: 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; break;
case S_MODE: case S_MODE:
@@ -317,7 +334,17 @@ int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixC
break; break;
case S_SWING: 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; break;
case S_QUIET: 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[0] = buf[i] ;
hexbyte[1] = buf[i+1] ; hexbyte[1] = buf[i+1] ;
data[i/2] = (toHex(hexbyte[0]) << 4) | toHex(hexbyte[1]); data[i/2] = (toHex(hexbyte[0]) << 4) | toHex(hexbyte[1]);
AC_Serial.write(data, 37); AC_Serial.write(data, 37);
AC_Serial.flush(); AC_Serial.flush();
publishTopic("RAW", buf); 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 (strTopic == "/myhome/in/Conditioner/Swing"){
if (strPayload == "off"){ if (strPayload == "off"){
data[B_SWING] = 0; 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") //if (strTopic == "/myhome/in/Conditioner/RAW")
data[B_CMD] = 0; 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[10] = 77;
data[11] = 95; data[11] = 95;
SendData(data, sizeof(data)/sizeof(byte)); SendData(data, sizeof(data)/sizeof(byte));
InsertData(data, sizeof(data)/sizeof(byte));
return 1; return 1;
} }