mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
AirCon, OpenHab, Relay status fixed& interop
This commit is contained in:
@@ -9,6 +9,7 @@ int abstractOut::isActive()
|
||||
{
|
||||
case CMD_OFF:
|
||||
case CMD_HALT:
|
||||
case CMD_VOID:
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -12,7 +12,7 @@ public:
|
||||
virtual int isActive();
|
||||
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
||||
virtual int getChanType(){return 0;}
|
||||
virtual int getDefaultStorageType(){return ST_PERCENTS255;} /// Remove?? Now getChanType used instead
|
||||
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
||||
int Setup() override;
|
||||
protected:
|
||||
Item * item;
|
||||
|
||||
@@ -417,6 +417,7 @@ void Item::setVal(long int par) // Only store if VAL is int (autogenerated or c
|
||||
//debugSerial<<F(" Store ")<<F(" Val=")<<par<<endl;
|
||||
itemVal->valueint = par;
|
||||
itemVal->type = aJson_Int;
|
||||
if (itemVal->subtype==ST_TENS) itemVal->subtype=ST_INT32;
|
||||
}
|
||||
|
||||
void Item::setFloatVal(float par) // Only store if VAL is int (autogenerated or config-defined)
|
||||
@@ -425,12 +426,12 @@ void Item::setFloatVal(float par) // Only store if VAL is int (autogenerated or
|
||||
//debugSerial<<F(" Store ")<<F(" Val=")<<par<<endl;
|
||||
itemVal->valuefloat = par;
|
||||
itemVal->type = aJson_Float;
|
||||
if (itemVal->subtype==ST_TENS) itemVal->subtype=ST_FLOAT;
|
||||
}
|
||||
|
||||
void Item::setSubtype(uint8_t par) // Only store if VAL is int (autogenerated or config-defined)
|
||||
{
|
||||
if (!itemVal || (itemVal->type != aJson_Int && itemVal->type != aJson_Float && itemVal->type != aJson_NULL)) return;
|
||||
//debugSerial<<F(" Store ")<<F(" Val=")<<par<<endl;
|
||||
itemVal->subtype = par & 0xF;
|
||||
}
|
||||
|
||||
@@ -959,7 +960,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
}
|
||||
|
||||
status2Send |= SEND_IMMEDIATE;
|
||||
if (cmd.isCommand()) status2Send |= SEND_COMMAND;
|
||||
if (cmd.isChannelCommand()) status2Send |= SEND_COMMAND;
|
||||
if (cmd.isValue() || cmd.loadItem(this,SEND_PARAMETERS)) status2Send |= SEND_PARAMETERS; ;
|
||||
} // end GROUP
|
||||
|
||||
@@ -1055,12 +1056,24 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
break;
|
||||
|
||||
case CMD_OFF:
|
||||
if (!cmd.isChannelCommand() ) //Command for driver, not for whole channel
|
||||
{
|
||||
toExecute=true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (getCmd() == CMD_HALT) return -3; //Halted, ignore OFF
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
toExecute=true;
|
||||
break;
|
||||
|
||||
case CMD_ON:
|
||||
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
||||
{
|
||||
toExecute=true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chActive)
|
||||
{
|
||||
debugSerial<<F("ON:Already Active\n");
|
||||
@@ -1072,6 +1085,11 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
case CMD_HEAT:
|
||||
case CMD_FAN:
|
||||
case CMD_DRY:
|
||||
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
||||
{
|
||||
toExecute=true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cmd.isValue()) cmd.loadItemDef(this); // if no_suffix - both, command ON and value provided
|
||||
status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE;
|
||||
@@ -1380,13 +1398,15 @@ int Item::SendStatus(int sendFlags) {
|
||||
st.debugOut();
|
||||
if (sendFlags & SEND_COMMAND)
|
||||
{
|
||||
// Preparing Command payload //////////////
|
||||
// Preparing legacy Command payload //////////////
|
||||
switch (st.getCmd()) {
|
||||
case CMD_ON:
|
||||
case CMD_XON:
|
||||
case CMD_AUTO:
|
||||
case CMD_HEAT:
|
||||
case CMD_COOL:
|
||||
case CMD_DRY:
|
||||
case CMD_FAN:
|
||||
strcpy_P(cmdstr, ON_P);
|
||||
break;
|
||||
case CMD_OFF:
|
||||
@@ -1404,26 +1424,22 @@ int Item::SendStatus(int sendFlags) {
|
||||
}
|
||||
}
|
||||
|
||||
//debugSerial<<"C"<<cmdstr<<endl;
|
||||
// publish to MQTT - OpenHab Legacy style to
|
||||
// myhome/s_out/item - mix: value and command
|
||||
// send only for OH bus supported types
|
||||
|
||||
switch (st.getArgType())
|
||||
{
|
||||
case ST_PERCENTS255:
|
||||
case ST_HSV255:
|
||||
case ST_FLOAT_CELSIUS:
|
||||
|
||||
|
||||
if (mqttClient.connected() && !ethernetIdleCount && !subItem)
|
||||
{
|
||||
|
||||
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
||||
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,true);
|
||||
|
||||
|
||||
if (sendFlags & SEND_PARAMETERS && st.getCmd() != CMD_OFF && st.getCmd() != CMD_HALT)
|
||||
if (sendFlags & SEND_PARAMETERS && st.getCmd() != CMD_OFF && st.getCmd() != CMD_HALT &&
|
||||
// send only for OH bus supported types
|
||||
(st.getArgType() == ST_PERCENTS255 || st.getArgType() == ST_HSV255 || st.getArgType() == ST_FLOAT_CELSIUS))
|
||||
{
|
||||
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,true);
|
||||
mqttClient.publish(addrstr, valstr, true);
|
||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
||||
}
|
||||
@@ -1439,8 +1455,7 @@ int Item::SendStatus(int sendFlags) {
|
||||
setFlag(sendFlags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// publush to MQTT - New style to
|
||||
// myhome/s_out/item/cmd
|
||||
@@ -1503,6 +1518,12 @@ int Item::SendStatus(int sendFlags) {
|
||||
break;
|
||||
case CMD_COOL:
|
||||
strcpy_P(cmdstr, COOL_P);
|
||||
break;
|
||||
case CMD_DRY:
|
||||
strcpy_P(cmdstr, DRY_P);
|
||||
break;
|
||||
case CMD_FAN:
|
||||
strcpy_P(cmdstr, FAN_ONLY_P);
|
||||
break;
|
||||
case CMD_ON:
|
||||
case CMD_XON:
|
||||
@@ -1704,6 +1725,15 @@ int Item::VacomSetFan(itemCmd st) {
|
||||
int val=st.getPercents();
|
||||
int cmd=st.getCmd();
|
||||
|
||||
if (st.isCommand())
|
||||
switch (st.getSuffix()){
|
||||
case S_CMD:
|
||||
case S_NOTFOUND:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cmd){
|
||||
case CMD_OFF:
|
||||
case CMD_HALT:
|
||||
|
||||
@@ -106,12 +106,13 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
|
||||
case CH_DIMMER:
|
||||
case CH_MOTOR:
|
||||
case CH_PWM:
|
||||
case CH_RELAY:
|
||||
case CH_VC:
|
||||
case CH_MODBUS:
|
||||
//case CH_GROUP:
|
||||
return ST_PERCENTS255;
|
||||
break;
|
||||
case CH_RELAY:
|
||||
return ST_VOID;
|
||||
default:
|
||||
return ST_VOID;
|
||||
}
|
||||
@@ -616,6 +617,12 @@ bool itemCmd::isCommand()
|
||||
return (cmd.cmdCode);
|
||||
}
|
||||
|
||||
bool itemCmd::isChannelCommand()
|
||||
{
|
||||
if (cmd.suffixCode==S_NOTFOUND || cmd.suffixCode==S_CMD )
|
||||
return (cmd.cmdCode);
|
||||
else return 0;
|
||||
}
|
||||
bool itemCmd::isValue()
|
||||
{
|
||||
return (cmd.itemArgType);
|
||||
|
||||
@@ -209,6 +209,7 @@ public:
|
||||
char * toString(char * Buffer, int bufLen, int sendFlags = SEND_COMMAND | SEND_PARAMETERS, bool scale100 = false);
|
||||
|
||||
bool isCommand();
|
||||
bool isChannelCommand();
|
||||
bool isValue();
|
||||
bool isColor();
|
||||
|
||||
|
||||
@@ -956,7 +956,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
|
||||
// if (_once) {DMXput(); _once=0;}
|
||||
lanStatus = RETAINING_COLLECTING;//4;
|
||||
timerLanCheckTime = millis();// + 5000;
|
||||
infoSerial<<F("Awaiting for retained topics");
|
||||
infoSerial<<F("Awaiting for retained topics")<<endl;
|
||||
} else
|
||||
{
|
||||
errorSerial<<F("failed, rc=")<<mqttClient.state()<<F(" try again in 5 seconds")<<endl;
|
||||
|
||||
@@ -190,21 +190,21 @@ void SendData(byte req[], size_t size){
|
||||
AC_Serial.write(req, size - 1);
|
||||
AC_Serial.write(getCRC(req, size-1));
|
||||
//AC_Serial.flush();
|
||||
/*
|
||||
Serial.print("<<");
|
||||
|
||||
debugSerial.print("AirCon<<");
|
||||
for (int i=0; i < size-1; i++)
|
||||
{
|
||||
if (req[i] < 10){
|
||||
Serial.print("0");
|
||||
Serial.print(req[i], HEX);
|
||||
debugSerial.print("0");
|
||||
debugSerial.print(req[i], HEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(req[i], HEX);
|
||||
debugSerial.print(req[i], HEX);
|
||||
}
|
||||
}
|
||||
Serial.println();
|
||||
*/
|
||||
debugSerial.println();
|
||||
|
||||
}
|
||||
|
||||
inline unsigned char toHex( char ch ){
|
||||
@@ -268,7 +268,10 @@ return INTERVAL_SLOW_POLLING;
|
||||
|
||||
//int out_AC::Ctrl(short cmd, short n, int * Parameters, int suffixCode, char* subItem)
|
||||
int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
{char s_mode[10];
|
||||
{
|
||||
//char s_mode[10];
|
||||
char s_speed[10];
|
||||
|
||||
int suffixCode = cmd.getSuffix();
|
||||
// Some additional Subitems
|
||||
if (strcmp_P(subItem, LOCK_P) == 0) suffixCode = S_LOCK;
|
||||
@@ -276,7 +279,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
else if (strcmp_P(subItem, QUIET_P) == 0) suffixCode = S_QUIET;
|
||||
else if (strcmp_P(subItem, RAW_P) == 0) suffixCode = S_RAW;
|
||||
|
||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||
if (cmd.isCommand() && !suffixCode && !subItem) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||
|
||||
//data[B_POWER] = power;
|
||||
// debugSerial<<F(".");
|
||||
@@ -294,7 +297,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
break;
|
||||
|
||||
case S_CMD:
|
||||
s_mode[0]='\0';
|
||||
// s_mode[0]='\0';
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
@@ -302,7 +305,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
SendData(on, sizeof(on)/sizeof(byte));
|
||||
publishTopic(item->itemArr->name,"ON","/cmd");
|
||||
// publishTopic(item->itemArr->name,"ON","/cmd");
|
||||
return 1;
|
||||
break;
|
||||
case CMD_OFF:
|
||||
@@ -310,73 +313,78 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] &= ~1;
|
||||
SendData(off, sizeof(off)/sizeof(byte));
|
||||
publishTopic(item->itemArr->name,"OFF","/cmd");
|
||||
// publishTopic(item->itemArr->name,"OFF","/cmd");
|
||||
return 1;
|
||||
break;
|
||||
case CMD_AUTO:
|
||||
data[B_MODE] = 0;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
strcpy_P(s_mode,AUTO_P);
|
||||
// strcpy_P(s_mode,AUTO_P);
|
||||
break;
|
||||
case CMD_COOL:
|
||||
data[B_MODE] = 1;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
strcpy_P(s_mode,COOL_P);
|
||||
// strcpy_P(s_mode,COOL_P);
|
||||
break;
|
||||
case CMD_HEAT:
|
||||
data[B_MODE] = 2;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
strcpy_P(s_mode,HEAT_P);
|
||||
// strcpy_P(s_mode,HEAT_P);
|
||||
break;
|
||||
case CMD_DRY:
|
||||
data[B_MODE] = 4;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
strcpy_P(s_mode,DRY_P);
|
||||
// strcpy_P(s_mode,DRY_P);
|
||||
break;
|
||||
case CMD_FAN:
|
||||
data[B_MODE] = 3;
|
||||
debugSerial<<"fan\n";
|
||||
// debugSerial<<"fan\n";
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
strcpy_P(s_mode,FAN_ONLY_P);
|
||||
if (data[B_FAN_SPD] == 3)
|
||||
{
|
||||
data[B_FAN_SPD] = 2; //Auto - fan speed in Ventilation mode not working
|
||||
}
|
||||
// strcpy_P(s_mode,FAN_ONLY_P);
|
||||
break;
|
||||
case CMD_UNKNOWN:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
publishTopic(item->itemArr->name,s_mode,"/cmd");
|
||||
// debugSerial<<F("Mode:")<<s_mode<<endl;
|
||||
// publishTopic(item->itemArr->name,s_mode,"/cmd");
|
||||
break;
|
||||
|
||||
case S_FAN:
|
||||
s_mode[0]='\0';
|
||||
s_speed[0]='\0';
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_AUTO:
|
||||
data[B_FAN_SPD] = 3;
|
||||
strcpy_P(s_mode,AUTO_P);
|
||||
strcpy_P(s_speed,AUTO_P);
|
||||
break;
|
||||
case CMD_HIGH:
|
||||
data[B_FAN_SPD] = 0;
|
||||
strcpy_P(s_mode,HIGH_P);
|
||||
strcpy_P(s_speed,HIGH_P);
|
||||
break;
|
||||
case CMD_MED:
|
||||
data[B_FAN_SPD] = 1;
|
||||
strcpy_P(s_mode,MED_P);
|
||||
strcpy_P(s_speed,MED_P);
|
||||
break;
|
||||
case CMD_LOW:
|
||||
data[B_FAN_SPD] = 2;
|
||||
strcpy_P(s_mode,LOW_P);
|
||||
strcpy_P(s_speed,LOW_P);
|
||||
break;
|
||||
default:
|
||||
//if (n) data[B_FAN_SPD] = Parameters[0];
|
||||
data[B_FAN_SPD] = cmd.getInt();
|
||||
//TODO - mapping digits to speed
|
||||
}
|
||||
publishTopic(item->itemArr->name,s_mode,"/fan");
|
||||
publishTopic(item->itemArr->name,s_speed,"/fan");
|
||||
break;
|
||||
|
||||
case S_MODE:
|
||||
@@ -401,14 +409,17 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
{
|
||||
case CMD_ON:
|
||||
data[B_LOCK_REM] = 3;
|
||||
publishTopic(item->itemArr->name,"ON","/swing");
|
||||
break;
|
||||
case CMD_OFF:
|
||||
data[B_LOCK_REM] = 0;
|
||||
publishTopic(item->itemArr->name,"OFF","/swing");
|
||||
break;
|
||||
default:
|
||||
//if (n) data[B_SWING] = Parameters[0];
|
||||
data[B_SWING] = cmd.getInt();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S_QUIET:
|
||||
@@ -476,12 +487,13 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
data[9] = 1;
|
||||
data[10] = 77;
|
||||
data[11] = 95;
|
||||
AC_Serial.flush();
|
||||
SendData(data, sizeof(data)/sizeof(byte));
|
||||
//InsertData(data, sizeof(data)/sizeof(byte));
|
||||
|
||||
//AC_Serial.flush();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int out_AC::getChanType() {return CH_THERMO;}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
int Stop() override;
|
||||
int Status() override;
|
||||
int isActive() override;
|
||||
int getChanType() override;
|
||||
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user