AirCon, OpenHab, Relay status fixed& interop

This commit is contained in:
2022-01-29 03:33:29 +03:00
parent d76867063e
commit fc8b04ac9b
8 changed files with 97 additions and 45 deletions

View File

@@ -9,6 +9,7 @@ int abstractOut::isActive()
{ {
case CMD_OFF: case CMD_OFF:
case CMD_HALT: case CMD_HALT:
case CMD_VOID:
return 0; return 0;
break; break;
default: default:

View File

@@ -12,7 +12,7 @@ public:
virtual int isActive(); virtual int isActive();
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);}; virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
virtual int getChanType(){return 0;} 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; int Setup() override;
protected: protected:
Item * item; Item * item;

View File

@@ -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; //debugSerial<<F(" Store ")<<F(" Val=")<<par<<endl;
itemVal->valueint = par; itemVal->valueint = par;
itemVal->type = aJson_Int; 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) 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; //debugSerial<<F(" Store ")<<F(" Val=")<<par<<endl;
itemVal->valuefloat = par; itemVal->valuefloat = par;
itemVal->type = aJson_Float; 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) 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; 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; itemVal->subtype = par & 0xF;
} }
@@ -959,7 +960,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
} }
status2Send |= SEND_IMMEDIATE; 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; ; if (cmd.isValue() || cmd.loadItem(this,SEND_PARAMETERS)) status2Send |= SEND_PARAMETERS; ;
} // end GROUP } // end GROUP
@@ -1055,12 +1056,24 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
break; break;
case CMD_OFF: 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 if (getCmd() == CMD_HALT) return -3; //Halted, ignore OFF
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
toExecute=true; toExecute=true;
break; break;
case CMD_ON: case CMD_ON:
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
{
toExecute=true;
break;
}
if (chActive) if (chActive)
{ {
debugSerial<<F("ON:Already Active\n"); debugSerial<<F("ON:Already Active\n");
@@ -1072,6 +1085,11 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
case CMD_HEAT: case CMD_HEAT:
case CMD_FAN: case CMD_FAN:
case CMD_DRY: 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 if (!cmd.isValue()) cmd.loadItemDef(this); // if no_suffix - both, command ON and value provided
status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE; status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE;
@@ -1380,13 +1398,15 @@ int Item::SendStatus(int sendFlags) {
st.debugOut(); st.debugOut();
if (sendFlags & SEND_COMMAND) if (sendFlags & SEND_COMMAND)
{ {
// Preparing Command payload ////////////// // Preparing legacy Command payload //////////////
switch (st.getCmd()) { switch (st.getCmd()) {
case CMD_ON: case CMD_ON:
case CMD_XON: case CMD_XON:
case CMD_AUTO: case CMD_AUTO:
case CMD_HEAT: case CMD_HEAT:
case CMD_COOL: case CMD_COOL:
case CMD_DRY:
case CMD_FAN:
strcpy_P(cmdstr, ON_P); strcpy_P(cmdstr, ON_P);
break; break;
case CMD_OFF: case CMD_OFF:
@@ -1404,26 +1424,22 @@ int Item::SendStatus(int sendFlags) {
} }
} }
//debugSerial<<"C"<<cmdstr<<endl;
// publish to MQTT - OpenHab Legacy style to // publish to MQTT - OpenHab Legacy style to
// myhome/s_out/item - mix: value and command // 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) if (mqttClient.connected() && !ethernetIdleCount && !subItem)
{ {
setTopic(addrstr,sizeof(addrstr),T_OUT); setTopic(addrstr,sizeof(addrstr),T_OUT);
strncat(addrstr, itemArr->name, sizeof(addrstr)-1); 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); mqttClient.publish(addrstr, valstr, true);
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl; debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
} }
@@ -1439,8 +1455,7 @@ int Item::SendStatus(int sendFlags) {
setFlag(sendFlags); setFlag(sendFlags);
return 0; return 0;
} }
}
// publush to MQTT - New style to // publush to MQTT - New style to
// myhome/s_out/item/cmd // myhome/s_out/item/cmd
@@ -1503,6 +1518,12 @@ int Item::SendStatus(int sendFlags) {
break; break;
case CMD_COOL: case CMD_COOL:
strcpy_P(cmdstr, COOL_P); 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; break;
case CMD_ON: case CMD_ON:
case CMD_XON: case CMD_XON:
@@ -1704,6 +1725,15 @@ int Item::VacomSetFan(itemCmd st) {
int val=st.getPercents(); int val=st.getPercents();
int cmd=st.getCmd(); int cmd=st.getCmd();
if (st.isCommand())
switch (st.getSuffix()){
case S_CMD:
case S_NOTFOUND:
break;
default:
return -1;
}
switch (cmd){ switch (cmd){
case CMD_OFF: case CMD_OFF:
case CMD_HALT: case CMD_HALT:

View File

@@ -106,12 +106,13 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
case CH_DIMMER: case CH_DIMMER:
case CH_MOTOR: case CH_MOTOR:
case CH_PWM: case CH_PWM:
case CH_RELAY:
case CH_VC: case CH_VC:
case CH_MODBUS: case CH_MODBUS:
//case CH_GROUP: //case CH_GROUP:
return ST_PERCENTS255; return ST_PERCENTS255;
break; break;
case CH_RELAY:
return ST_VOID;
default: default:
return ST_VOID; return ST_VOID;
} }
@@ -616,6 +617,12 @@ bool itemCmd::isCommand()
return (cmd.cmdCode); return (cmd.cmdCode);
} }
bool itemCmd::isChannelCommand()
{
if (cmd.suffixCode==S_NOTFOUND || cmd.suffixCode==S_CMD )
return (cmd.cmdCode);
else return 0;
}
bool itemCmd::isValue() bool itemCmd::isValue()
{ {
return (cmd.itemArgType); return (cmd.itemArgType);

View File

@@ -209,6 +209,7 @@ public:
char * toString(char * Buffer, int bufLen, int sendFlags = SEND_COMMAND | SEND_PARAMETERS, bool scale100 = false); char * toString(char * Buffer, int bufLen, int sendFlags = SEND_COMMAND | SEND_PARAMETERS, bool scale100 = false);
bool isCommand(); bool isCommand();
bool isChannelCommand();
bool isValue(); bool isValue();
bool isColor(); bool isColor();

View File

@@ -956,7 +956,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
// if (_once) {DMXput(); _once=0;} // if (_once) {DMXput(); _once=0;}
lanStatus = RETAINING_COLLECTING;//4; lanStatus = RETAINING_COLLECTING;//4;
timerLanCheckTime = millis();// + 5000; timerLanCheckTime = millis();// + 5000;
infoSerial<<F("Awaiting for retained topics"); infoSerial<<F("Awaiting for retained topics")<<endl;
} else } else
{ {
errorSerial<<F("failed, rc=")<<mqttClient.state()<<F(" try again in 5 seconds")<<endl; errorSerial<<F("failed, rc=")<<mqttClient.state()<<F(" try again in 5 seconds")<<endl;

View File

@@ -190,21 +190,21 @@ void SendData(byte req[], size_t size){
AC_Serial.write(req, size - 1); AC_Serial.write(req, size - 1);
AC_Serial.write(getCRC(req, size-1)); AC_Serial.write(getCRC(req, size-1));
//AC_Serial.flush(); //AC_Serial.flush();
/*
Serial.print("<<"); debugSerial.print("AirCon<<");
for (int i=0; i < size-1; i++) for (int i=0; i < size-1; i++)
{ {
if (req[i] < 10){ if (req[i] < 10){
Serial.print("0"); debugSerial.print("0");
Serial.print(req[i], HEX); debugSerial.print(req[i], HEX);
} }
else else
{ {
Serial.print(req[i], HEX); debugSerial.print(req[i], HEX);
} }
} }
Serial.println(); debugSerial.println();
*/
} }
inline unsigned char toHex( char ch ){ 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(short cmd, short n, int * Parameters, int suffixCode, char* subItem)
int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute) 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(); int suffixCode = cmd.getSuffix();
// Some additional Subitems // Some additional Subitems
if (strcmp_P(subItem, LOCK_P) == 0) suffixCode = S_LOCK; 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, QUIET_P) == 0) suffixCode = S_QUIET;
else if (strcmp_P(subItem, RAW_P) == 0) suffixCode = S_RAW; 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; //data[B_POWER] = power;
// debugSerial<<F("."); // debugSerial<<F(".");
@@ -294,7 +297,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
break; break;
case S_CMD: case S_CMD:
s_mode[0]='\0'; // s_mode[0]='\0';
switch (cmd.getCmd()) switch (cmd.getCmd())
{ {
case CMD_ON: case CMD_ON:
@@ -302,7 +305,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] |= 1; data[B_POWER] |= 1;
SendData(on, sizeof(on)/sizeof(byte)); SendData(on, sizeof(on)/sizeof(byte));
publishTopic(item->itemArr->name,"ON","/cmd"); // publishTopic(item->itemArr->name,"ON","/cmd");
return 1; return 1;
break; break;
case CMD_OFF: case CMD_OFF:
@@ -310,73 +313,78 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] &= ~1; data[B_POWER] &= ~1;
SendData(off, sizeof(off)/sizeof(byte)); SendData(off, sizeof(off)/sizeof(byte));
publishTopic(item->itemArr->name,"OFF","/cmd"); // publishTopic(item->itemArr->name,"OFF","/cmd");
return 1; return 1;
break; break;
case CMD_AUTO: case CMD_AUTO:
data[B_MODE] = 0; data[B_MODE] = 0;
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] |= 1; data[B_POWER] |= 1;
strcpy_P(s_mode,AUTO_P); // strcpy_P(s_mode,AUTO_P);
break; break;
case CMD_COOL: case CMD_COOL:
data[B_MODE] = 1; data[B_MODE] = 1;
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] |= 1; data[B_POWER] |= 1;
strcpy_P(s_mode,COOL_P); // strcpy_P(s_mode,COOL_P);
break; break;
case CMD_HEAT: case CMD_HEAT:
data[B_MODE] = 2; data[B_MODE] = 2;
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] |= 1; data[B_POWER] |= 1;
strcpy_P(s_mode,HEAT_P); // strcpy_P(s_mode,HEAT_P);
break; break;
case CMD_DRY: case CMD_DRY:
data[B_MODE] = 4; data[B_MODE] = 4;
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] |= 1; data[B_POWER] |= 1;
strcpy_P(s_mode,DRY_P); // strcpy_P(s_mode,DRY_P);
break; break;
case CMD_FAN: case CMD_FAN:
data[B_MODE] = 3; data[B_MODE] = 3;
debugSerial<<"fan\n"; // debugSerial<<"fan\n";
data[B_POWER] = power; data[B_POWER] = power;
data[B_POWER] |= 1; 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; break;
case CMD_UNKNOWN: case CMD_UNKNOWN:
return -1; return -1;
break; break;
} }
publishTopic(item->itemArr->name,s_mode,"/cmd"); // debugSerial<<F("Mode:")<<s_mode<<endl;
// publishTopic(item->itemArr->name,s_mode,"/cmd");
break; break;
case S_FAN: case S_FAN:
s_mode[0]='\0'; s_speed[0]='\0';
switch (cmd.getCmd()) switch (cmd.getCmd())
{ {
case CMD_AUTO: case CMD_AUTO:
data[B_FAN_SPD] = 3; data[B_FAN_SPD] = 3;
strcpy_P(s_mode,AUTO_P); strcpy_P(s_speed,AUTO_P);
break; break;
case CMD_HIGH: case CMD_HIGH:
data[B_FAN_SPD] = 0; data[B_FAN_SPD] = 0;
strcpy_P(s_mode,HIGH_P); strcpy_P(s_speed,HIGH_P);
break; break;
case CMD_MED: case CMD_MED:
data[B_FAN_SPD] = 1; data[B_FAN_SPD] = 1;
strcpy_P(s_mode,MED_P); strcpy_P(s_speed,MED_P);
break; break;
case CMD_LOW: case CMD_LOW:
data[B_FAN_SPD] = 2; data[B_FAN_SPD] = 2;
strcpy_P(s_mode,LOW_P); strcpy_P(s_speed,LOW_P);
break; break;
default: default:
//if (n) data[B_FAN_SPD] = Parameters[0]; //if (n) data[B_FAN_SPD] = Parameters[0];
data[B_FAN_SPD] = cmd.getInt(); data[B_FAN_SPD] = cmd.getInt();
//TODO - mapping digits to speed //TODO - mapping digits to speed
} }
publishTopic(item->itemArr->name,s_mode,"/fan"); publishTopic(item->itemArr->name,s_speed,"/fan");
break; break;
case S_MODE: case S_MODE:
@@ -401,14 +409,17 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
{ {
case CMD_ON: case CMD_ON:
data[B_LOCK_REM] = 3; data[B_LOCK_REM] = 3;
publishTopic(item->itemArr->name,"ON","/swing");
break; break;
case CMD_OFF: case CMD_OFF:
data[B_LOCK_REM] = 0; data[B_LOCK_REM] = 0;
publishTopic(item->itemArr->name,"OFF","/swing");
break; break;
default: default:
//if (n) data[B_SWING] = Parameters[0]; //if (n) data[B_SWING] = Parameters[0];
data[B_SWING] = cmd.getInt(); data[B_SWING] = cmd.getInt();
} }
break; break;
case S_QUIET: case S_QUIET:
@@ -476,12 +487,13 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
data[9] = 1; data[9] = 1;
data[10] = 77; data[10] = 77;
data[11] = 95; data[11] = 95;
AC_Serial.flush();
SendData(data, sizeof(data)/sizeof(byte)); SendData(data, sizeof(data)/sizeof(byte));
//InsertData(data, sizeof(data)/sizeof(byte)); //InsertData(data, sizeof(data)/sizeof(byte));
//AC_Serial.flush();
return 1; return 1;
} }
int out_AC::getChanType() {return CH_THERMO;}
#endif #endif

View File

@@ -30,6 +30,7 @@ public:
int Stop() override; int Stop() override;
int Status() override; int Status() override;
int isActive() override; int isActive() override;
int getChanType() override;
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;}; int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override; int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;