Multi-AC reworking, Mbus fix, RESET command for PID

This commit is contained in:
2026-03-07 23:19:46 +03:00
parent c5427251fc
commit b888f1a521
7 changed files with 284 additions and 110 deletions

View File

@@ -1141,6 +1141,11 @@ itemCmd itemCmd::Cmd(uint8_t i)
return *this; return *this;
} }
itemCmd itemCmd::Cmd(itemCmd i)
{
cmd.cmdCode=i.cmd.cmdCode;
return *this;
}
uint8_t itemCmd::getSuffix() uint8_t itemCmd::getSuffix()
{ {

View File

@@ -29,7 +29,7 @@ const cmdstr commands_P[] PROGMEM =
"ENABLE","DISABLE","UNFREEZE","FREEZE", "ENABLE","DISABLE","UNFREEZE","FREEZE",
"AUTO","FAN_ONLY", "AUTO","FAN_ONLY",
"HIGH","MEDIUM","LOW","HEAT_COOL", "HIGH","MEDIUM","LOW","HEAT_COOL",
"HEAT","COOL","DRY","RGB","HSV" "HEAT","COOL","DRY","RGB","HSV","RESET"
}; };
#define commandsNum sizeof(commands_P)/sizeof(cmdstr) #define commandsNum sizeof(commands_P)/sizeof(cmdstr)
@@ -94,6 +94,7 @@ const ch_type ch_type_P[] PROGMEM =
#define CMD_RGB 0x17 #define CMD_RGB 0x17
#define CMD_HSV 0x18 #define CMD_HSV 0x18
#define CMD_RESET 0x19
#define CMD_MASK 0xffUL #define CMD_MASK 0xffUL
#define FLAG_MASK 0x00ffff00UL #define FLAG_MASK 0x00ffff00UL
@@ -236,6 +237,7 @@ public:
itemCmd Tens(int32_t i); itemCmd Tens(int32_t i);
itemCmd Tens_raw(int32_t i); itemCmd Tens_raw(int32_t i);
itemCmd Cmd(uint8_t i); itemCmd Cmd(uint8_t i);
itemCmd Cmd(itemCmd i);
itemCmd HSV(uint16_t h, uint8_t s, uint8_t v); itemCmd HSV(uint16_t h, uint8_t s, uint8_t v);
itemCmd HSV255(uint16_t h, uint8_t s, uint8_t v); itemCmd HSV255(uint16_t h, uint8_t s, uint8_t v);
itemCmd HS(uint16_t h, uint8_t s); itemCmd HS(uint16_t h, uint8_t s);

View File

@@ -196,7 +196,7 @@ bool out_Modbus::getConfig()
if (store->parameters) if (store->parameters)
{ {
// Creating for parameters where prefetch required // Creating for parameters where prefetch required
debugSerial<<F("Adding prefetch regs:")<<endl; debugSerial<<F("MBUS:")<<F("Adding prefetch regs:")<<endl;
aJsonObject * i = store->parameters->child; aJsonObject * i = store->parameters->child;
while (i) while (i)
{ {
@@ -208,7 +208,7 @@ bool out_Modbus::getConfig()
i=i->next; i=i->next;
} }
debugSerial<<F("Adding referred regs:")<<endl; debugSerial<<F("MBUS:")<<F("Adding referred regs:")<<endl;
i = store->parameters->child; i = store->parameters->child;
// Creating for parameters used in references from another parameters // Creating for parameters used in references from another parameters
while (i) while (i)
@@ -229,7 +229,7 @@ bool out_Modbus::getConfig()
} }
i=i->next; i=i->next;
} }
debugSerial<<F("Adding regs with actions:")<<endl; debugSerial<<F("MBUS:")<<F("Adding regs with actions:")<<endl;
// Check - if action configured for object and create // Check - if action configured for object and create
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2); aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
if (itemParametersObj) if (itemParametersObj)
@@ -286,7 +286,7 @@ int out_Modbus::createLastMeasured(aJsonObject * execObj)
lastMeasured = aJson.getObjectItem(markObj,"@S"); lastMeasured = aJson.getObjectItem(markObj,"@S");
if (!lastMeasured) return false; if (!lastMeasured) return false;
lastMeasured->subtype |= MB_VALUE_OUTDATED; lastMeasured->subtype |= LM_VALUE_EMPTY;
return true; return true;
} }
@@ -316,6 +316,20 @@ if (lastMeasured && lastMeasured->type == aJson_Int) return lastMeasured;
return NULL; return NULL;
} }
void out_Modbus::setLastMeasured(aJsonObject * lastMeasured, int val)
{
//aJsonObject *lastMeasured = getLastMeasured (execObj);
if (lastMeasured)
{
lastMeasured->valueint = val;
//lastMeasured->subtype&=~LM_VALUE_OUTDATED;
//lastMeasured->subtype&=~LM_VALUE_EMPTY;
lastMeasured->subtype = 0;
}
}
/** /**
* @brief Инициализирует канал Modbus и загружает конфигурацию. * @brief Инициализирует канал Modbus и загружает конфигурацию.
* @return 1 при успехе, 0 при ошибке. * @return 1 при успехе, 0 при ошибке.
@@ -503,7 +517,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
mappedParam.Int((uint32_t)param); mappedParam.Int((uint32_t)param);
} }
traceSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from type ")<<parType<<F(":")<<paramObj->name<<endl; traceSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from type ")<<parType<<F(":")<<paramObj->name<<endl;
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object)) if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
{ {
@@ -587,11 +601,11 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
if (nestedMapObj && (nestedMapObj->type==aJson_Array || nestedMapObj->type==aJson_Object)) mappedParam=mappedParam.doReverseMapping(nestedMapObj); if (nestedMapObj && (nestedMapObj->type==aJson_Array || nestedMapObj->type==aJson_Object)) mappedParam=mappedParam.doReverseMapping(nestedMapObj);
traceSerial << F("MBUSD: NestedMapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl; traceSerial << F("MBUSD: NestedMapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
if (!(lastMeasured->subtype & MB_VALUE_OUTDATED)) if (!(lastMeasured->subtype & LM_VALUE_OUTDATED))
{ {
executeWithoutCheck=true; executeWithoutCheck=true;
submitRecurrentOut=true; submitRecurrentOut=true;
lastMeasured->subtype|= MB_VALUE_OUTDATED; lastMeasured->subtype|= LM_VALUE_OUTDATED;
} }
} }
@@ -627,22 +641,21 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
aJsonObject *lastMeasured = getLastMeasured(execObj); aJsonObject *lastMeasured = getLastMeasured(execObj);
if (lastMeasured) if (lastMeasured)
{ {
if (lastMeasured->valueint == param) if (lastMeasured->valueint == param && !(lastMeasured->subtype & LM_VALUE_EMPTY))
{ {
//if recurrent call but value was readed before //if recurrent call but value was readed before
if (!doExecution && !(lastMeasured->subtype & MB_VALUE_OUTDATED)) if (!doExecution && !(lastMeasured->subtype & LM_VALUE_OUTDATED))
{ {
*submitParam=true; //never used *submitParam=true; //never used
lastMeasured->subtype|=MB_VALUE_OUTDATED; lastMeasured->subtype|=LM_VALUE_OUTDATED;
return mappedParam; return mappedParam;
} }
*submitParam=false; //supress repeating execution for same val *submitParam=false; //supress repeating execution for same val
} }
else else
{ {
lastMeasured->valueint=param;
traceSerial<<"MBUS: Stored "<<param<<" to @S of "<<paramObj->name<<endl; traceSerial<<"MBUS: Stored "<<param<<" to @S of "<<paramObj->name<<endl;
lastMeasured->subtype&=~MB_VALUE_OUTDATED; setLastMeasured(lastMeasured,param);
} }
} }
// } // }
@@ -898,7 +911,7 @@ if (prefetchObj && (prefetchObj->type == aJson_Boolean) && prefetchObj->valueboo
debugSerial<<F("MBUS res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<outValue->valueint<<endl; debugSerial<<F("MBUS res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<outValue->valueint<<endl;
//If wrote - suppress action on poll //If wrote - suppress action on poll
if ((res ==0) && (outValue->type == aJson_Int) && lastMeasured && (lastMeasured->type == aJson_Int)) lastMeasured->valueint = outValue->valueint; if ((res ==0) && (outValue->type == aJson_Int) && lastMeasured && (lastMeasured->type == aJson_Int)) setLastMeasured(lastMeasured,outValue->valueint);
return ( res == 0); return ( res == 0);
@@ -1116,7 +1129,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
{ {
if (lastMeasured) if (lastMeasured)
{ {
if (lastMeasured->valueint == Value && !(lastMeasured->subtype & MB_VALUE_OUTDATED)) if (lastMeasured->valueint == Value && !(lastMeasured->subtype))
{ {
debugSerial<<"MBUS: Value2send equal retrieved"<<endl; debugSerial<<"MBUS: Value2send equal retrieved"<<endl;
return 1; return 1;

View File

@@ -23,10 +23,14 @@ public:
aJsonObject * parameters; aJsonObject * parameters;
}; };
//execObj subtype
#define MB_NEED_SEND 8 #define MB_NEED_SEND 8
#define MB_SEND_ERROR 4 #define MB_SEND_ERROR 4
#define MB_SEND_ATTEMPTS 3 #define MB_SEND_ATTEMPTS 3
#define MB_VALUE_OUTDATED 1
//lastMeasusement subtype
#define LM_VALUE_OUTDATED 1
#define LM_VALUE_EMPTY 2
class out_Modbus : public abstractOut { class out_Modbus : public abstractOut {
@@ -55,5 +59,6 @@ protected:
int createLastMeasured(aJsonObject * execObj); int createLastMeasured(aJsonObject * execObj);
aJsonObject * getLastMeasured(char * name); aJsonObject * getLastMeasured(char * name);
aJsonObject * getLastMeasured(aJsonObject * execObj); aJsonObject * getLastMeasured(aJsonObject * execObj);
void setLastMeasured(aJsonObject * execObj, int val);
}; };
#endif #endif

View File

@@ -70,7 +70,7 @@ if (gatesObj)
pidObj->valueint = (long int) new PID (&valObj->valuefloat, &poObj->valuefloat, &setObj->valuefloat, kP, kI, kD, direction); pidObj->valueint = (long int) new PID (&valObj->valuefloat, &poObj->valuefloat, &setObj->valuefloat, kP, kI, kD, direction);
((PID*) pidObj->valueint)->SetMode (AUTOMATIC); //((PID*) pidObj->valueint)->SetMode (AUTOMATIC);
((PID*) pidObj->valueint)->SetSampleTime(dT*1000.0); ((PID*) pidObj->valueint)->SetSampleTime(dT*1000.0);
debugSerial << F ("VENT: PID P=")<<kP<<" I="<<kI<<" D="<<kD<< endl; debugSerial << F ("VENT: PID P=")<<kP<<" I="<<kI<<" D="<<kD<< endl;
} }
@@ -103,8 +103,7 @@ if (gatesObj)
{ {
delete ((PID *) pidObj->valueint); delete ((PID *) pidObj->valueint);
pidObj->valueint = 0;//NULL; pidObj->valueint = 0;//NULL;
} }
} }
i=i->next; i=i->next;
} }
@@ -146,7 +145,6 @@ int out_Multivent::isActive()
//case CMD_OFF: //case CMD_OFF:
return 1; return 1;
break; break;
} }
} }
i=i->next; i=i->next;
@@ -157,7 +155,6 @@ int out_Multivent::isActive()
int out_Multivent::Poll(short cause) int out_Multivent::Poll(short cause)
{ {
if (!acObj || !gatesObj) return 0; if (!acObj || !gatesObj) return 0;
if (cause == POLLING_SLOW && item->getExt() && isTimeOver(item->getExt(),millisNZ(),60000L)) if (cause == POLLING_SLOW && item->getExt() && isTimeOver(item->getExt(),millisNZ(),60000L))
@@ -182,13 +179,15 @@ int out_Multivent::Poll(short cause)
int balance = 0; int balance = 0;
bool ventRequested = false; //At least 1 ch requested FAN mode bool ventRequested = false; //At least 1 ch requested FAN mode
bool autoRequested = false; //At least 1 ch requested AUTO mode bool autoRequested = false; //At least 1 ch requested AUTO mode
bool pidActive = false;
bool pidComputed = false;
while (i) while (i)
{ {
if (i->name && *i->name) if (i->name && *i->name)
{ {
int cmd = getIntFromJson(i,"cmd"); int cmd = getIntFromJson(i,"cmd");
float set = getIntFromJson(i,"set"); int set = getIntFromJson(i,"set");
float val = getIntFromJson(i,"val"); int val = getIntFromJson(i,"val");
int execCmd = 0; int execCmd = 0;
switch (cmd) switch (cmd)
@@ -213,7 +212,6 @@ int out_Multivent::Poll(short cause)
//setValToJson(i,"@C",cmd); //setValToJson(i,"@C",cmd);
execCmd = cmd; execCmd = cmd;
break; break;
} }
bool passiveMode = getIntFromJson(i,"@pasv",0); bool passiveMode = getIntFromJson(i,"@pasv",0);
@@ -221,8 +219,25 @@ int out_Multivent::Poll(short cause)
if (pidObj && pidObj->valueint) if (pidObj && pidObj->valueint)
{ {
PID * p = (PID *) pidObj->valueint; PID * p = (PID *) pidObj->valueint;
if ((execCmd == CMD_HEAT || execCmd == CMD_COOL) && p->GetMode() == AUTOMATIC) pidActive = true;
switch (actualMode)
{ //if air hot or cold - uses temp PID and block control by /fan
case CMD_HEAT:
p->SetMode(AUTOMATIC);
p->SetControllerDirection(DIRECT);
break;
case CMD_COOL:
p->SetMode(AUTOMATIC);
p->SetControllerDirection(REVERSE);
break;
default:
if (passiveMode || execCmd == CMD_AUTO || execCmd ==CMD_OFF) p->SetMode(MANUAL);
}
if (p->Compute()) if (p->Compute())
{ {
aJsonObject * poObj = aJson.getObjectItem(i,"po"); aJsonObject * poObj = aJson.getObjectItem(i,"po");
if (poObj && poObj->type == aJson_Float) if (poObj && poObj->type == aJson_Float)
{ {
@@ -232,61 +247,48 @@ int out_Multivent::Poll(short cause)
<<" P:"<<p->GetKp()<<" I:"<<p->GetKi()<<" D:"<<p->GetKd()<<((p->GetDirection())?" Rev ":" Dir ")<<((p->GetMode())?"A":"M"); <<" P:"<<p->GetKp()<<" I:"<<p->GetKi()<<" D:"<<p->GetKd()<<((p->GetDirection())?" Rev ":" Dir ")<<((p->GetMode())?"A":"M");
debugSerial<<endl; debugSerial<<endl;
if (passiveMode || execCmd == CMD_AUTO)
switch (execCmd)
{ {
case CMD_HEAT:
if (actualCmd==CMD_COOL) //close
fanCtrl(itemCmd().Percents255(0).setSuffix(S_FAN),i->name,true,true);
else
fanCtrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name,true,true);
balance+=poObj->valuefloat;
pidComputed = true;
break;
case CMD_COOL:
if (actualCmd==CMD_HEAT) //close
fanCtrl(itemCmd().Percents255(0).setSuffix(S_FAN),i->name,true,true);
else
fanCtrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name,true,true);
balance-=poObj->valuefloat;
pidComputed = true;
break;
default:
switch (actualMode) switch (actualMode)
{ {
case CMD_HEAT: case CMD_HEAT:
((PID *) pidObj->valueint)->SetControllerDirection(DIRECT); debugSerial<<F("VENT: HEAT PASS PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" out:")<< poObj->valuefloat <<endl;
debugSerial<<F("VENT: HEAT PASS PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" out:")<< poObj->valuefloat <<F(" set DIRECT mode")<<endl;
if (actualCmd!=CMD_OFF) fanCtrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name,true); if (actualCmd!=CMD_OFF || passiveMode) fanCtrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name,true,true);
if (poObj->valuefloat == 0.0 && autoRequested) {autoRequested = false; debugSerial<<"Vent: no more heat needed for "<<i->name<<endl;}
break; break;
case CMD_COOL: case CMD_COOL:
((PID *) pidObj->valueint)->SetControllerDirection(REVERSE); debugSerial<<F("VENT: COOL PASS PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" out:")<< poObj->valuefloat <<endl;
debugSerial<<F("VENT: COOL PASS PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" out:")<< poObj->valuefloat << F(" set REVERSE mode")<<endl;
if (actualCmd!=CMD_OFF) fanCtrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name,true); if (actualCmd!=CMD_OFF || passiveMode) fanCtrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name,true,true);
if (poObj->valuefloat == 0.0 && autoRequested) {autoRequested = false; debugSerial<<"Vent: no more cool needed for "<<i->name<<endl;}
break; break;
//case CMD_FAN: //no more hot or cold air case CMD_FAN: //no more hot or cold air
//if (autoRequested) debugSerial<<"VENT: Cancel automode request"<<endl; // ((PID *) pidObj->valueint)->SetMode(MANUAL);
//autoRequested = false;
//todo - delete auto request if AC is idle - stuck and not move to vent job
} }
} }
else switch (execCmd)
{
case CMD_HEAT:
((PID *) pidObj->valueint)->SetControllerDirection(DIRECT);
debugSerial<<F("VENT: PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set DIRECT mode")<<endl;
if (actualCmd==CMD_HEAT) Ctrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name);
//else?
balance+=poObj->valuefloat;
break;
case CMD_COOL:
//case CMD_FAN: // if PIB using for vent
//case CMD_ON: // AC temp unknown - assuming that PID used for vent
((PID *) pidObj->valueint)->SetControllerDirection(REVERSE);
debugSerial<<F("VENT: PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set REVERSE mode")<<endl;
if (actualCmd==CMD_COOL) Ctrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name);
//else ?
balance-=poObj->valuefloat;
break;
// if FAN_ONLY (AC report room temp regularry) - not use internal PID - let be on external control via /fan
case CMD_FAN:
// vent requested but air temp hot or cold
if (actualCmd == CMD_HEAT || actualCmd == CMD_COOL)
{
Ctrl(itemCmd().Percents255(0).setSuffix(S_FAN),i->name);
Ctrl(itemCmd().Cmd(CMD_FREEZE),i->name);
}
else Ctrl(itemCmd().Cmd(CMD_UNFREEZE),i->name);
}
} }
} }
} }
@@ -294,31 +296,30 @@ int out_Multivent::Poll(short cause)
} }
i=i->next; i=i->next;
}//while }//while
if (balance) debugSerial<<F("VENT: Chan balance=")<<balance<<F(" treshold:")<<boostTreshold<<endl; if (pidComputed)
{
debugSerial<<F("VENT: Chan balance=")<<balance<<F(" treshold:")<<boostTreshold<<endl;
if (balance>boostTreshold) sendACcmd (CMD_HEAT); if (balance>boostTreshold) setBoost(itemCmd().Cmd(CMD_HEAT).Int(30).setSuffix(S_SET));
else if (-balance>boostTreshold) sendACcmd (CMD_COOL); else if (-balance>boostTreshold) setBoost(itemCmd().Cmd(CMD_COOL).Int(18).setSuffix(S_SET));
else if (autoRequested) sendACcmd(CMD_AUTO); else
else if (ventRequested) sendACcmd(CMD_FAN); {
// else sendACcmd (CMD_OFF); pidActive = false;
}
}
if (!pidActive)
{
resetBoost();
if (autoRequested) sendACcmd(itemCmd().Cmd(CMD_AUTO));
else if (ventRequested) sendACcmd(itemCmd().Cmd(CMD_FAN));
}
return 1; return 1;
}; };
int out_Multivent::sendACcmd (int cmd)
{
if (!acObj) return 0;
int lastCmd = getIntFromJson(acObj,"@lastCmd");
int acCmd = getIntFromJson(acObj,"mode");
if (lastCmd && (acCmd != lastCmd)) {
//debugSerial<<"VENT: AC MODE changed manually to "<<item->getCmd()<<endl;
return 0;}
if (cmd == lastCmd) {
//debugSerial<<"VENT: AC MODE already same"<<endl;
return 0;}
executeCommand(acObj,-1,itemCmd().Cmd(cmd).setSuffix(S_CMD));
setValToJson(acObj,"@lastCmd",cmd);
return 1;
}
int out_Multivent::getChanType() int out_Multivent::getChanType()
{ {
@@ -436,47 +437,67 @@ switch (suffixCode)
return 1; return 1;
case S_FAN: case S_FAN:
if (cmd.isValue())
{
debugSerial << F("VENT:")<<F("AC fan: ")<< cmd.getCmd()<<endl;
setValToJson(acObj,"fan",cmd.getInt());
}
return 1; return 1;
case S_SET: case S_SET:
if (cmd.isValue())
{
debugSerial << F("VENT:")<<F("AC set: ")<< cmd.getCmd()<<endl;
setValToJson(acObj,"set",cmd.getFloat());
}
return 1; return 1;
case S_MODE: case S_MODE:
if (cmd.isCommand())
{
debugSerial << F("VENT:")<<F("AC mode: ")<< cmd.getCmd()<<endl; debugSerial << F("VENT:")<<F("AC mode: ")<< cmd.getCmd()<<endl;
setValToJson(acObj,"mode",cmd.getCmd()); setValToJson(acObj,"mode",cmd.getCmd());
}
return 1; return 1;
case S_CMD: case S_CMD:
debugSerial<<"VENT: Todo - handle cmd/HALT. cmd="<<cmd.getCmd()<<endl; debugSerial<<"VENT: Todo - handle cmd/HALT. cmd="<<cmd.getCmd()<<endl;
return 1; return 1;
case S_TEMP: //case S_TEMP: - temp corrupted by core
debugSerial << F("VENT:")<<F("AC air roomtemp: ")<< cmd.getFloat()<<endl; // debugSerial << F("VENT:")<<F("AC air roomtemp: ")<< cmd.getFloat()<<endl;
setValToJson(acObj,"roomtemp",cmd.getFloat()); // setValToJson(acObj,"roomtemp",cmd.getFloat());
return 1; //return 1;
} }
} }
aJsonObject * i = NULL; aJsonObject * i = NULL;
if (cmd.isCommand() && cmd.getSuffix()==S_FAN) if (cmd.getSuffix()==S_FAN)
{
switch (cmd.getCmd()) switch (cmd.getCmd())
{ {
case CMD_HIGH: case CMD_HIGH:
cmd.Percents255(255); cmd.Percents255(255);
cmd.Cmd(0);
break; break;
case CMD_MED: case CMD_MED:
cmd.Percents255(128); cmd.Percents255(128);
cmd.Cmd(0);
break; break;
case CMD_LOW: case CMD_LOW:
cmd.Percents255(10); cmd.Percents255(10);
cmd.Cmd(0);
break; break;
case CMD_OFF:
cmd.Percents255(0);
cmd.Cmd(0);
break;
} //switch cmd } //switch cmd
}
if (gatesObj) i = gatesObj->child; // Pass 1 - calculate summ air value, max value etc if (gatesObj) i = gatesObj->child; // Pass 1 - calculate summ air value, max value etc
@@ -511,7 +532,20 @@ while (i)
case S_FAN: case S_FAN:
if (getFlag(i,FLAG_FREEZED)) {debugSerial<<F("VENT: zone frozen")<<endl; return -1;} if (getFlag(i,FLAG_FREEZED)) {debugSerial<<F("VENT: zone frozen")<<endl; return -1;}
if (cmd.isValue()) if (cmd.isValue())
{ {
if (!force && pidEnabled(pidObj))
{
debugSerial<<F("VENT: FAN control disabled by PID")<<endl;
return 1;
}
// on boost something requested - remove
//if (!force && getFlag(acObj,FLAG_ACTION_NEEDED))
// {
// debugSerial<<F("VENT: FAN control disabled in boost mode")<<endl;
// return 1;
// }
if (cmd.getInt()) if (cmd.getInt())
{ {
if (cmdObj->valueint == CMD_OFF && turnbyfan) if (cmdObj->valueint == CMD_OFF && turnbyfan)
@@ -550,9 +584,9 @@ while (i)
case S_CMD: case S_CMD:
if (cmd.isCommand()) if (cmd.isCommand())
{ {
switch (cmd.getCmd())
if (cmd.getCmd() == CMD_ON)
{ {
case CMD_ON:
if (getFlag(i,FLAG_FREEZED)) {debugSerial<<F("VENT: zone frozen")<<endl; return -1;} if (getFlag(i,FLAG_FREEZED)) {debugSerial<<F("VENT: zone frozen")<<endl; return -1;}
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != CMD_HALT) break; if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != CMD_HALT) break;
cmd.Percents255(fanObj->valueint); cmd.Percents255(fanObj->valueint);
@@ -563,6 +597,11 @@ while (i)
debugSerial<<"VENT: Turning ON. cmd:"<<cmdObj->valueint<<endl; debugSerial<<"VENT: Turning ON. cmd:"<<cmdObj->valueint<<endl;
cmd.Cmd(cmdObj->valueint); cmd.Cmd(cmdObj->valueint);
setPassiveMode(i,false); setPassiveMode(i,false);
}
switch (cmd.getCmd())
{
case CMD_ON:
break; break;
case CMD_OFF: case CMD_OFF:
if (getFlag(i,FLAG_FREEZED)) {debugSerial<<F("VENT: zone frozen")<<endl; return -1;} if (getFlag(i,FLAG_FREEZED)) {debugSerial<<F("VENT: zone frozen")<<endl; return -1;}
@@ -573,7 +612,9 @@ while (i)
//if (!passiveMode) sendFlags |= FLAG_PARAMETERS; //if (!passiveMode) sendFlags |= FLAG_PARAMETERS;
//else cmd.Cmd(CMD_AUTO); //else cmd.Cmd(CMD_AUTO);
cmdObj->valueint = CMD_OFF; cmdObj->valueint = CMD_OFF;
enablePid(pidObj,false);
break; break;
/*
case CMD_ENABLE: case CMD_ENABLE:
if (pidObj && pidObj->valueint) ((PID *) pidObj->valueint)->SetMode(AUTOMATIC); if (pidObj && pidObj->valueint) ((PID *) pidObj->valueint)->SetMode(AUTOMATIC);
sendFlags |= FLAG_FLAGS; sendFlags |= FLAG_FLAGS;
@@ -585,6 +626,7 @@ while (i)
sendFlags |= FLAG_FLAGS; sendFlags |= FLAG_FLAGS;
setPassiveMode(i,false); setPassiveMode(i,false);
break; break;
*/
case CMD_FREEZE: case CMD_FREEZE:
setFlag(i,FLAG_FREEZED); setFlag(i,FLAG_FREEZED);
@@ -594,12 +636,27 @@ while (i)
clearFlag(i,FLAG_FREEZED); clearFlag(i,FLAG_FREEZED);
return 1; return 1;
case CMD_AUTO:
case CMD_HEATCOOL:
case CMD_COOL: case CMD_COOL:
case CMD_HEAT:
case CMD_FAN:
case CMD_DRY: case CMD_DRY:
enablePid(pidObj,true,REVERSE);
sendFlags |= FLAG_COMMAND;
cmdObj->valueint = cmd.getCmd();
setPassiveMode(i,false);
break;
case CMD_HEAT:
enablePid(pidObj,true,DIRECT);
case CMD_HEATCOOL:
enablePid(pidObj,true);
sendFlags |= FLAG_COMMAND;
cmdObj->valueint = cmd.getCmd();
setPassiveMode(i,false);
break;
case CMD_FAN:
case CMD_AUTO:
enablePid(pidObj,false);
sendFlags |= FLAG_COMMAND; sendFlags |= FLAG_COMMAND;
cmdObj->valueint = cmd.getCmd(); cmdObj->valueint = cmd.getCmd();
setPassiveMode(i,false); setPassiveMode(i,false);
@@ -614,8 +671,6 @@ while (i)
} }
} }
break; break;
case S_SET: case S_SET:
if (cmd.isValue()) if (cmd.isValue())
{ {
@@ -638,14 +693,14 @@ while (i)
} //switch } //switch
if (isNotRetainingStatus()) //Send status separately for cmd, param, flags if (isNotRetainingStatus()) //Send status separately for cmd, param, flags
{ {
if (sendFlags & FLAG_COMMAND) item->SendStatusImmediate(cmd.setSuffix(S_CMD),FLAG_COMMAND,i->name); if (sendFlags & FLAG_COMMAND) item->SendStatusImmediate(itemCmd().Cmd(cmd).setSuffix(S_CMD),FLAG_COMMAND,i->name);
if (sendFlags & FLAG_PARAMETERS ) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name); if (sendFlags & FLAG_PARAMETERS ) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
if (sendFlags & FLAG_FLAGS) item->SendStatusImmediate(cmd,FLAG_FLAGS,i->name); if (sendFlags & FLAG_FLAGS) item->SendStatusImmediate(cmd,FLAG_FLAGS,i->name);
} }
if (cascadeObj) if (cascadeObj)
{ {
if (sendFlags & FLAG_COMMAND) SubmitParameters(cascadeObj,"cmd",cmd.setSuffix(S_CMD).setArgType(0),true); if (sendFlags & FLAG_COMMAND) SubmitParameters(cascadeObj,"cmd",itemCmd().Cmd(cmd).setSuffix(S_CMD).setArgType(0),true);
if (sendFlags & FLAG_PARAMETERS) if (sendFlags & FLAG_PARAMETERS)
switch (cmd.getSuffix()) switch (cmd.getSuffix())
{ {
@@ -732,4 +787,87 @@ while (i)
return 1; return 1;
} }
void out_Multivent::enablePid(aJsonObject* pidObj, int enable, int direction )
{
if (pidObj && pidObj->valueint)
{
((PID *) pidObj->valueint)->SetMode(enable);
if (direction != -1) ((PID *) pidObj->valueint)->SetControllerDirection(direction);
}
}
bool out_Multivent::pidEnabled(aJsonObject* pidObj)
{
return ((pidObj && pidObj->valueint) && (((PID *) pidObj->valueint)->GetMode() ==AUTOMATIC));
}
int out_Multivent::sendACcmd (itemCmd cmd)
{
if (!acObj) return 0;
int lastCmd = getIntFromJson(acObj,"@lastCmd");
int acCmd = getIntFromJson(acObj,"mode");
//if (lastCmd && (acCmd != lastCmd)) {
// //debugSerial<<"VENT: AC MODE changed manually to "<<item->getCmd()<<endl;
// return 0;}
if (cmd.isCommand())
{
if (cmd.getCmd() == lastCmd ) {
//debugSerial<<"VENT: AC MODE already "<<lastCmd<<endl;
}
else
{
executeCommand(acObj,-1,itemCmd().Cmd(cmd).setSuffix(S_CMD).setArgType(0));
setValToJson(acObj,"@lastCmd",cmd.getCmd());
}
}
if (cmd.isValue())
{
executeCommand(acObj,-1,cmd.Cmd(0));
switch (cmd.getSuffix())
{
case S_FAN:
setValToJson(acObj,"@lastFan",cmd.getCmd());
break;
case S_SET:
setValToJson(acObj,"@lastSet",cmd.getCmd());
}
}
return 1;
}
void out_Multivent::setBoost(itemCmd cmd)
{
if (!acObj || getFlag(acObj,FLAG_ACTION_NEEDED)) return;
debugSerial<<"VENT: boost on"<<endl;
int acTemp = getIntFromJson(acObj,"set",21);
setValToJson(acObj,"@preset",acTemp);
//executeCommand(acObj,-1,cmd.setArgType(0).setSuffix(S_CMD));
sendACcmd(cmd);
//executeCommand(acObj,-1,cmd.Cmd(0).setSuffix(S_SET));
setFlag(acObj,FLAG_ACTION_NEEDED);
}
void out_Multivent::resetBoost()
{
if (!acObj || !getFlag(acObj,FLAG_ACTION_NEEDED)) return;
debugSerial<<"VENT: boost off"<<endl;
int preTemp = getIntFromJson(acObj,"@preset",21);
if (preTemp<17) preTemp = 21;
sendACcmd(itemCmd().Cmd(0).Int(preTemp).setSuffix(S_SET));
//executeCommand(acObj,-1,itemCmd().Cmd(0).Int(preTemp).setSuffix(S_SET));
clearFlag(acObj,FLAG_ACTION_NEEDED);
}
void out_Multivent::notifyState(itemCmd state)
{
char val[16];
state.toString(val,sizeof(val),FLAG_COMMAND);
publishTopic(item->itemArr->name,val,"/$state");
}
#endif #endif

View File

@@ -25,11 +25,18 @@ public:
int fanCtrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool force = false); int fanCtrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool force = false);
protected: protected:
void getConfig(); void getConfig();
int sendACcmd (int cmd); int sendACcmd (itemCmd cmd);
void setPassiveMode(aJsonObject* zone, bool mode); void setPassiveMode(aJsonObject* zone, bool mode);
uint32_t getFlag (aJsonObject* zone, uint32_t flag); uint32_t getFlag (aJsonObject* zone, uint32_t flag);
void setFlag (aJsonObject* zone, uint32_t flag); void setFlag (aJsonObject* zone, uint32_t flag);
void clearFlag (aJsonObject* zone, uint32_t flag); void clearFlag (aJsonObject* zone, uint32_t flag);
void enablePid(aJsonObject* zone, int enable, int direction = -1);
bool pidEnabled(aJsonObject* pidObj);
void setBoost(itemCmd);
void resetBoost();
void notifyState(itemCmd state);
aJsonObject * gatesObj; aJsonObject * gatesObj;
aJsonObject * acObj; aJsonObject * acObj;
//float acTemp; //float acTemp;

View File

@@ -377,7 +377,11 @@ case S_CTRL:
executeCommand(oCmd,-1,value); executeCommand(oCmd,-1,value);
return 1; return 1;
} */ } */
case CMD_RESET:
store->pid->Initialize();
debugSerial<<F("PID: reset")<<endl;
return 1;
break;
default: default:
debugSerial<<F("PID: Unknown cmd ")<<cmd.getCmd()<<endl; debugSerial<<F("PID: Unknown cmd ")<<cmd.getCmd()<<endl;
} //switch cmd } //switch cmd