group scheduling reworked

This commit is contained in:
2025-04-28 22:26:36 +03:00
parent c2c863b8bd
commit 65c07a1881
2 changed files with 42 additions and 69 deletions

View File

@@ -805,7 +805,7 @@ st.setSuffix(suffixCode);
} }
} }
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken); if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
return Ctrl(st,subItem,true,authorized); return Ctrl(st,subItem,0,authorized);
} //Void command } //Void command
break; break;
@@ -838,14 +838,14 @@ st.setSuffix(suffixCode);
Par0.Cmd(cmd); Par0.Cmd(cmd);
Par0.setSuffix(suffixCode); Par0.setSuffix(suffixCode);
if (remoteID) return remoteCtrl(Par0,remoteID,subItem,authToken); if (remoteID) return remoteCtrl(Par0,remoteID,subItem,authToken);
return Ctrl(Par0, subItem,true,authorized); return Ctrl(Par0, subItem,0,authorized);
} }
default: //some known command default: //some known command
{ {
int32_t intParam = getIntFromStr((char **) &payload); int32_t intParam = getIntFromStr((char **) &payload);
if (intParam) st.Int(intParam); if (intParam) st.Int(intParam);
if (remoteID) return remoteCtrl(st,remoteID,NULL,authToken); if (remoteID) return remoteCtrl(st,remoteID,NULL,authToken);
return Ctrl(st,NULL, true, authorized); return Ctrl(st,NULL, 0, authorized);
} }
} //ctrl } //ctrl
return 0; return 0;
@@ -874,7 +874,7 @@ int Item::remoteCtrl(itemCmd cmd, int remoteID, char* subItem, char * authToken)
// Recursive function with small stack consumption // Recursive function with small stack consumption
// if cmd defined - execute Ctrl for any group members recursively // if cmd defined - execute Ctrl for any group members recursively
// else performs Activity check for group members and return true if any member is active // else performs Activity check for group members and return true if any member is active
bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool authorized) bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool authorized, uint8_t ctrlFlags)
{ if (!itemArr || itemArr->type!=aJson_Array) return false; { if (!itemArr || itemArr->type!=aJson_Array) return false;
// Iterate across array of names // Iterate across array of names
aJsonObject *i = itemArr->child; aJsonObject *i = itemArr->child;
@@ -888,14 +888,12 @@ bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool aut
if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item
{ {
Item it(nextItem); Item it(nextItem);
if (cmd && it.isValid()) it.Ctrl(*cmd,subItem,false,authorized); //Execute (non recursive) if (cmd && it.isValid() ) it.Ctrl(*cmd,subItem,CTRL_DISABLE_RECURSION | ctrlFlags, authorized); //Execute (non recursive)
//Retrieve itemType //Retrieve itemType
//aJsonObject * itemtype = aJson.getArrayItem(nextItem,0);
//if (itemtype && itemtype->type == aJson_Int && itemtype->valueint == CH_GROUP)
if (it.itemType == CH_GROUP) if (it.itemType == CH_GROUP)
{ //is Group { //is Group
aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1); aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1);
short res = digGroup(itemSubArray,cmd,subItem,authorized); short res = digGroup(itemSubArray,cmd,subItem,authorized, ctrlFlags);
if (!cmd && res) if (!cmd && res)
{ {
configLocked--; configLocked--;
@@ -932,25 +930,25 @@ aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
return 0; return 0;
} }
int Item::scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized) int Item::scheduleOppositeCommand(itemCmd cmd,short isActiveNow,bool authorized)
{ {
itemCmd nextCmd=cmd; itemCmd nextCmd=cmd;
switch (cmd.getCmd()){ switch (cmd.getCmd()){
case CMD_XON: case CMD_XON:
if (isActiveNow && !isScheduled()) return 0; if ((isActiveNow == 1) && !isScheduled()) return 0;
nextCmd.Cmd(CMD_XOFF); nextCmd.Cmd(CMD_XOFF);
break; break;
case CMD_XOFF: case CMD_XOFF:
if (!isActiveNow && !isScheduled()) return 0; if ((isActiveNow == 0) && !isScheduled()) return 0;
nextCmd.Cmd(CMD_XON); nextCmd.Cmd(CMD_XON);
break; break;
case CMD_ON: case CMD_ON:
if (isActiveNow && !isScheduled()) return 0; if ((isActiveNow == 1) && !isScheduled()) return 0;
nextCmd.Cmd(CMD_OFF); nextCmd.Cmd(CMD_OFF);
break; break;
case CMD_OFF: case CMD_OFF:
if (!isActiveNow && !isScheduled()) return 0; if ((isActiveNow == 0) && !isScheduled()) return 0;
nextCmd.Cmd(CMD_ON); nextCmd.Cmd(CMD_ON);
break; break;
case CMD_ENABLE: case CMD_ENABLE:
@@ -970,11 +968,11 @@ int Item::scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized)
nextCmd.Cmd(CMD_FREEZE); nextCmd.Cmd(CMD_FREEZE);
break; break;
case CMD_HALT: case CMD_HALT:
if (!isActiveNow && !isScheduled()) return 0; if ((isActiveNow == 0) && !isScheduled()) return 0;
nextCmd.Cmd(CMD_RESTORE); nextCmd.Cmd(CMD_RESTORE);
break; break;
case CMD_RESTORE: case CMD_RESTORE:
if (isActiveNow && !isScheduled()) return 0; if ((isActiveNow == 1) && !isScheduled()) return 0;
nextCmd.Cmd(CMD_HALT); nextCmd.Cmd(CMD_HALT);
break; break;
case CMD_TOGGLE: nextCmd.Cmd(CMD_TOGGLE); case CMD_TOGGLE: nextCmd.Cmd(CMD_TOGGLE);
@@ -1003,12 +1001,12 @@ int Item::scheduleCommand(itemCmd cmd,bool authorized)
timestampObj->type = (authorized?aJson_Reserved:aJson_Int); timestampObj->type = (authorized?aJson_Reserved:aJson_Int);
timestampObj->subtype=(cmd.getCmd() & 0xF); timestampObj->subtype=(cmd.getCmd() & 0xF);
debugSerial<<F( "Armed for ")<< cmd.getInt() << F(" ms :")<<timestampObj->valueint<<endl; debugSerial<<F( "CTRL: Armed ")<<itemArr->name <<F(" for ")<< cmd.getInt() << F(" ms")<<endl;
} }
else else
{ {
timestampObj->subtype=0; timestampObj->subtype=0;
debugSerial<<F( " Disarmed")<<endl; debugSerial<<F( "CTRL: ")<<itemArr->name << F( " Disarmed")<<endl;
} }
return 1; return 1;
} }
@@ -1024,7 +1022,7 @@ int Item::scheduleCommand(itemCmd cmd,bool authorized)
// -4 invalid argument // -4 invalid argument
// -5 unauthorized // -5 unauthorized
// -6 disabled // -6 disabled
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized) int Item::Ctrl(itemCmd cmd, char* subItem, uint8_t flags, bool authorized)
{ {
int fr = freeRam(); int fr = freeRam();
if (fr < minimalMemory) if (fr < minimalMemory)
@@ -1092,6 +1090,13 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
return scheduleCommand(cmd,authorized); return scheduleCommand(cmd,authorized);
} }
/// ///
if (((flags & CTRL_SCHEDULED_CALL_RECURSION) == CTRL_SCHEDULED_CALL_RECURSION && itemType != CH_GROUP))
{
debugSerial<<F("Skipping scheduled group exec")<<endl;
return -7;
}
///
int8_t chActive = -1; int8_t chActive = -1;
bool toExecute = false; bool toExecute = false;
bool scale100 = false; bool scale100 = false;
@@ -1259,7 +1264,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
errorSerial<<F("CTRL: Not enough memory for group operation")<<endl; errorSerial<<F("CTRL: Not enough memory for group operation")<<endl;
return -1; return -1;
} }
if (allowRecursion && itemArg->type == aJson_Array && operation) if (!(flags & CTRL_DISABLE_RECURSION) && itemArg->type == aJson_Array && operation)
{ {
if ((suffixCode==S_CMD) && ((cmd.getCmd() == CMD_ENABLE) || (cmd.getCmd() == CMD_DISABLE))) if ((suffixCode==S_CMD) && ((cmd.getCmd() == CMD_ENABLE) || (cmd.getCmd() == CMD_DISABLE)))
{ {
@@ -1286,14 +1291,14 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
} }
else else
{ {
chActive=(isActive()>0); //chActive=(isActive()>0);
if ((suffixCode!=S_CMD) || (cmd.getCmd() != CMD_XON) || !getFlag(FLAG_DISABLED)) if ((suffixCode!=S_CMD) || (cmd.getCmd() != CMD_XON) || !getFlag(FLAG_DISABLED))
{ {
digGroup(itemArg,&cmd,subItem,authorized); digGroup(itemArg,&cmd,subItem,authorized,flags);
if ((suffixCode==S_CMD) && cmd.isValue()) if ((suffixCode==S_CMD) && cmd.isValue())
{ {
scheduleOppositeCommand(originalCmd,chActive,authorized); scheduleOppositeCommand(originalCmd,-1/*chActive*/,authorized);
scheduledOppositeCommand = true; scheduledOppositeCommand = true;
} }
if (subItem && !subitemCmd) status2Send |= FLAG_SEND_IMMEDIATE; if (subItem && !subitemCmd) status2Send |= FLAG_SEND_IMMEDIATE;
@@ -1310,7 +1315,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
case CMD_RESTORE: // individual for group members case CMD_RESTORE: // individual for group members
switch (t = getCmd()) { switch (t = getCmd()) {
case CMD_HALT: //previous command was HALT ? case CMD_HALT: //previous command was HALT ?
///if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
debugSerial << F("CTRL: Restored from:") << t << endl; debugSerial << F("CTRL: Restored from:") << t << endl;
cmd.loadItemDef(this); cmd.loadItemDef(this);
cmd.Cmd(CMD_ON); //turning on cmd.Cmd(CMD_ON); //turning on
@@ -1324,7 +1328,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
case CMD_XOFF: // individual for group members case CMD_XOFF: // individual for group members
switch (t = getCmd()) { switch (t = getCmd()) {
case CMD_XON: //previous command was CMD_XON ? case CMD_XON: //previous command was CMD_XON ?
///if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
debugSerial << F("CTRL: Turned off from:") << t << endl; debugSerial << F("CTRL: Turned off from:") << t << endl;
cmd.Cmd(CMD_OFF); //turning Off cmd.Cmd(CMD_OFF); //turning Off
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
@@ -1340,10 +1343,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
if (!getFlag(FLAG_DISABLED)) if (!getFlag(FLAG_DISABLED))
{ {
if (chActive == -1) chActive=(isActive()>0); if (chActive == -1) chActive=(isActive()>0);
///if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
if (!chActive) //if channel was'nt active before CMD_XON if (!chActive) //if channel was'nt active before CMD_XON
{ {
@@ -1368,7 +1367,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
break; break;
case CMD_HALT: case CMD_HALT:
if (chActive == -1) chActive=(isActive()>0); if (chActive == -1) chActive=(isActive()>0);
///if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
if (chActive) //if channel was active before CMD_HALT /// HERE bug - if cmd == On but 0 = active if (chActive) //if channel was active before CMD_HALT /// HERE bug - if cmd == On but 0 = active
{ {
cmd.Cmd(CMD_OFF); cmd.Cmd(CMD_OFF);
@@ -1420,7 +1419,10 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
///// return 0; ///// return 0;
} }
} }
bool oppositeCommandToBeSchedulled = (suffixCode==S_CMD) && allowRecursion && cmd.isValue();
/// bool oppositeCommandToBeSchedulled = (suffixCode==S_CMD) && allowRecursion && cmd.isValue();
bool oppositeCommandToBeSchedulled = (suffixCode==S_CMD) && cmd.isValue();
// Commands for NON GROUP // Commands for NON GROUP
//threating Restore, XOFF (special conditional commands)/ convert to ON, OFF and SET values //threating Restore, XOFF (special conditional commands)/ convert to ON, OFF and SET values
switch (cmd.getCmd()) { switch (cmd.getCmd()) {
@@ -1428,9 +1430,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
case CMD_RESTORE: // individual for group members case CMD_RESTORE: // individual for group members
switch (t = getCmd()) { switch (t = getCmd()) {
case CMD_HALT: //previous command was HALT ? case CMD_HALT: //previous command was HALT ?
// if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
debugSerial << F("CTRL: Restored from:") << t << endl; debugSerial << F("CTRL: Restored from:") << t << endl;
cmd.loadItemDef(this); cmd.loadItemDef(this);
toExecute=true; toExecute=true;
@@ -1446,8 +1445,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
case CMD_XOFF: // individual for group members case CMD_XOFF: // individual for group members
switch (t = getCmd()) { switch (t = getCmd()) {
case CMD_XON: //previous command was CMD_XON ? case CMD_XON: //previous command was CMD_XON ?
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
debugSerial << F("CTRL: Turned off from:") << t << endl; debugSerial << F("CTRL: Turned off from:") << t << endl;
toExecute=true; toExecute=true;
cmd.Cmd(CMD_OFF); //turning Off cmd.Cmd(CMD_OFF); //turning Off
@@ -1463,9 +1460,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
case CMD_XON: case CMD_XON:
if (!getFlag(FLAG_DISABLED)) if (!getFlag(FLAG_DISABLED))
{ {
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
if (!chActive) //if channel was'nt active before CMD_XON if (!chActive) //if channel was'nt active before CMD_XON
{ {
@@ -1490,8 +1484,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
break; break;
case CMD_HALT: case CMD_HALT:
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
if (chActive) //if channel was active before CMD_HALT if (chActive) //if channel was active before CMD_HALT
{ {
cmd.Cmd(CMD_OFF); cmd.Cmd(CMD_OFF);
@@ -1514,18 +1506,11 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
} }
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
toExecute=true; toExecute=true;
break; break;
case CMD_ON: case CMD_ON:
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
{ {
toExecute=true; toExecute=true;
@@ -1562,30 +1547,16 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
break; break;
case CMD_ENABLE: case CMD_ENABLE:
case CMD_DISABLE:
//clearFlag(FLAG_DISABLED); //saveItem have this //clearFlag(FLAG_DISABLED); //saveItem have this
status2Send |= FLAG_FLAGS; status2Send |= FLAG_FLAGS;
toExecute=true; toExecute=true;
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
//if (allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
break;
case CMD_DISABLE:
//setFlag(FLAG_DISABLED); //saveItem have this
status2Send |= FLAG_FLAGS;
toExecute=true;
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
break; break;
case CMD_UNFREEZE: case CMD_UNFREEZE:
//clearFlag(FLAG_DISABLED); //saveItem have this //clearFlag(FLAG_DISABLED); //saveItem have this
status2Send = FLAG_FLAGS; status2Send = FLAG_FLAGS;
toExecute=true; toExecute=true;
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
break; break;
case CMD_FREEZE: case CMD_FREEZE:
@@ -1593,9 +1564,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
status2Send = FLAG_FLAGS; status2Send = FLAG_FLAGS;
command2Set = 0; command2Set = 0;
toExecute=true; toExecute=true;
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
// scheduleOppositeCommand(cmd,chActive,authorized);
break; break;
default: default:
@@ -1675,6 +1643,7 @@ if ((!driver || driver->isAllowed(cmd))
case CMD_HALT: case CMD_HALT:
case CMD_XOFF: case CMD_XOFF:
digitalWrite(iaddr, k = (inverse) ? HIGH : LOW); digitalWrite(iaddr, k = (inverse) ? HIGH : LOW);
break;
default: default:
k = -1; k = -1;
} }
@@ -1897,7 +1866,7 @@ if (timestampObj)
return -1; return -1;
} }
timestampObj->subtype=0; timestampObj->subtype=0;
Ctrl(itemCmd(ST_VOID,cmd),NULL,true,authorized); Ctrl(itemCmd(ST_VOID,cmd),NULL,CTRL_DISABLE_NON_GRP,authorized);
//timestampObj->subtype=0; //// //timestampObj->subtype=0; ////
} }
} }

View File

@@ -75,6 +75,10 @@ const suffixstr suffix_P[] PROGMEM =
#define POLLING_INT 3 #define POLLING_INT 3
#define POLLING_1S 4 #define POLLING_1S 4
//CTRL Execution flags
#define CTRL_DISABLE_RECURSION 1
#define CTRL_DISABLE_NON_GRP 2
#define CTRL_SCHEDULED_CALL_RECURSION (CTRL_DISABLE_RECURSION | CTRL_DISABLE_NON_GRP)
#define I_TYPE 0 //Type of item #define I_TYPE 0 //Type of item
#define I_ARG 1 //Chanel-type depended argument or array of arguments (pin, address etc) #define I_ARG 1 //Chanel-type depended argument or array of arguments (pin, address etc)
@@ -118,7 +122,7 @@ class Item
boolean Setup(); boolean Setup();
void Stop(); void Stop();
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL); //int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
int Ctrl(itemCmd cmd, char* subItem=NULL, bool allowRecursion = true, bool authorized=false); int Ctrl(itemCmd cmd, char* subItem=NULL, uint8_t flags = 0, bool authorized=false);
int Ctrl(char * payload, char * subItem=NULL, int remoteID = 0); int Ctrl(char * payload, char * subItem=NULL, int remoteID = 0);
int remoteCtrl(itemCmd cmd, int remoteID, char* subItem=NULL, char * authToken=NULL); int remoteCtrl(itemCmd cmd, int remoteID, char* subItem=NULL, char * authToken=NULL);
int getArg(short n=0); int getArg(short n=0);
@@ -148,13 +152,13 @@ class Item
inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));}; inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));}; inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
int scheduleCommand(itemCmd cmd, bool authorized); int scheduleCommand(itemCmd cmd, bool authorized);
int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized); int scheduleOppositeCommand(itemCmd cmd,short isActiveNow,bool authorized);
int isScheduled(); int isScheduled();
char * getSubItemStrById(uint8_t subItem); char * getSubItemStrById(uint8_t subItem);
uint8_t getSubitemId(char * subItem); uint8_t getSubitemId(char * subItem);
protected: protected:
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false); bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false, uint8_t ctrlFlags = 0);
long int limitSetValue(); long int limitSetValue();
int VacomSetFan (itemCmd st); int VacomSetFan (itemCmd st);
int VacomSetHeat(itemCmd st); int VacomSetHeat(itemCmd st);