mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Multivent->MultiAC alpha
MEGA env migrated to universal Wiznet driver some important core fixes
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -11,5 +11,5 @@ cp ../.pio/build/esp32-wifi/firmware.bin esp32-wifi
|
|||||||
cp ../.pio/build/stm32-enc2860/firmware.bin stm32-enc2860
|
cp ../.pio/build/stm32-enc2860/firmware.bin stm32-enc2860
|
||||||
cp ../.pio/build/esp8266-wifi/firmware.bin esp8266-wifi
|
cp ../.pio/build/esp8266-wifi/firmware.bin esp8266-wifi
|
||||||
cp ../.pio/build/lighthub21/firmware.bin lighthub21
|
cp ../.pio/build/lighthub21/firmware.bin lighthub21
|
||||||
cp ../.pio/build/mega2560-5500/firmware.hex mega2560-5500
|
cp ../.pio/build/mega2560/firmware.hex mega2560
|
||||||
cp ../.pio/build/stm32/firmware.* stm32
|
cp ../.pio/build/stm32/firmware.* stm32
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ int subitem2cmd(char *payload) {
|
|||||||
else if (strcmp_P(payload, AUTO_P) == 0) cmd = CMD_AUTO;
|
else if (strcmp_P(payload, AUTO_P) == 0) cmd = CMD_AUTO;
|
||||||
else if (strcmp_P(payload, FAN_ONLY_P) == 0) cmd = CMD_FAN;
|
else if (strcmp_P(payload, FAN_ONLY_P) == 0) cmd = CMD_FAN;
|
||||||
else if (strcmp_P(payload, DRY_P) == 0) cmd = CMD_DRY;
|
else if (strcmp_P(payload, DRY_P) == 0) cmd = CMD_DRY;
|
||||||
|
else if (strcmp_P(payload, HEATCOOL_P) == 0) cmd = CMD_HEATCOOL;
|
||||||
//else if (strcmp_P(payload, HIGH_P) == 0) cmd = CMD_HIGH;
|
//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, MED_P) == 0) cmd = CMD_MED;
|
||||||
//else if (strcmp_P(payload, LOW_P) == 0) cmd = CMD_LOW;
|
//else if (strcmp_P(payload, LOW_P) == 0) cmd = CMD_LOW;
|
||||||
@@ -1121,7 +1122,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, uint8_t flags, bool authorized)
|
|||||||
toExecute=true;
|
toExecute=true;
|
||||||
scale100=true; //openHab topic format
|
scale100=true; //openHab topic format
|
||||||
chActive=(isActive()>0);
|
chActive=(isActive()>0);
|
||||||
debugSerial<<chActive<<" "<<cmd.getInt()<<endl;
|
// debugSerial<<chActive<<" "<<cmd.getInt()<<endl;
|
||||||
if (chActive>0 && !cmd.getInt()) {cmd.Cmd(CMD_OFF);status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
|
if (chActive>0 && !cmd.getInt()) {cmd.Cmd(CMD_OFF);status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
|
||||||
if (chActive==0 && cmd.getInt()) {cmd.Cmd(CMD_ON);status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
|
if (chActive==0 && cmd.getInt()) {cmd.Cmd(CMD_ON);status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
|
||||||
|
|
||||||
@@ -1137,6 +1138,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, uint8_t flags, bool authorized)
|
|||||||
|
|
||||||
//Convert value to most approptiate type for channel
|
//Convert value to most approptiate type for channel
|
||||||
stored.assignFrom(cmd,getChanType());
|
stored.assignFrom(cmd,getChanType());
|
||||||
|
//stored.cmd.cmdCode=0; ///////
|
||||||
stored.debugOut();
|
stored.debugOut();
|
||||||
|
|
||||||
if ((scale100 || SCALE_VOLUME_100) && (cmd.getArgType()==ST_HSV255 || cmd.getArgType()==ST_PERCENTS255 || cmd.getArgType()==ST_INT32 || cmd.getArgType()==ST_UINT32))
|
if ((scale100 || SCALE_VOLUME_100) && (cmd.getArgType()==ST_HSV255 || cmd.getArgType()==ST_PERCENTS255 || cmd.getArgType()==ST_INT32 || cmd.getArgType()==ST_UINT32))
|
||||||
@@ -1530,6 +1532,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, uint8_t flags, bool authorized)
|
|||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
||||||
{
|
{
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
@@ -1632,6 +1635,7 @@ if ((!driver || driver->isAllowed(cmd))
|
|||||||
|
|
||||||
switch (icmd){
|
switch (icmd){
|
||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
@@ -1785,6 +1789,8 @@ int Item::isActive() {
|
|||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
|
case CMD_DRY:
|
||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
printActiveStatus(true);
|
printActiveStatus(true);
|
||||||
@@ -1949,6 +1955,7 @@ int Item::SendStatus(long sendFlags, char * subItem) {
|
|||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
@@ -2080,6 +2087,9 @@ int Item::SendStatus(long sendFlags, char * subItem) {
|
|||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
strcpy_P(cmdstr, AUTO_P);
|
strcpy_P(cmdstr, AUTO_P);
|
||||||
break;
|
break;
|
||||||
|
case CMD_HEATCOOL:
|
||||||
|
strcpy_P(cmdstr, HEATCOOL_P);
|
||||||
|
break;
|
||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
strcpy_P(cmdstr, HEAT_P);
|
strcpy_P(cmdstr, HEAT_P);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ e-mail anklimov@gmail.com
|
|||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "aJSON.h"
|
#include "aJSON.h"
|
||||||
|
|
||||||
typedef char cmdstr[9];
|
typedef char cmdstr[10];
|
||||||
|
|
||||||
const cmdstr commands_P[] PROGMEM =
|
const cmdstr commands_P[] PROGMEM =
|
||||||
{
|
{
|
||||||
"","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE",
|
"","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE",
|
||||||
"ENABLE","DISABLE","UNFREEZE","FREEZE",
|
"ENABLE","DISABLE","UNFREEZE","FREEZE",
|
||||||
"AUTO","FAN_ONLY",
|
"AUTO","FAN_ONLY",
|
||||||
"HIGH","MEDIUM","LOW",
|
"HIGH","MEDIUM","LOW","HEAT_COOL",
|
||||||
"HEAT","COOL","DRY","STOP","RGB","HSV"
|
"HEAT","COOL","DRY","RGB","HSV"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
||||||
@@ -87,10 +87,10 @@ const ch_type ch_type_P[] PROGMEM =
|
|||||||
#define CMD_MED 0x11 /// AC/Vent fan level MEDIUM
|
#define CMD_MED 0x11 /// AC/Vent fan level MEDIUM
|
||||||
#define CMD_LOW 0x12 /// AC/Vent fan level LOW
|
#define CMD_LOW 0x12 /// AC/Vent fan level LOW
|
||||||
|
|
||||||
#define CMD_HEAT 0x13 /// Thermostat/AC set to HEATing mode
|
#define CMD_HEATCOOL 0x13 ///
|
||||||
#define CMD_COOL 0x14 /// Thermostat/AC set to COOLing mode
|
#define CMD_HEAT 0x14 /// Thermostat/AC set to HEATing mode
|
||||||
#define CMD_DRY 0x15 /// AC set to Dry mode
|
#define CMD_COOL 0x15 /// Thermostat/AC set to COOLing mode
|
||||||
#define CMD_STOP 0x16 /// stop dimming (for further use)
|
#define CMD_DRY 0x16 /// AC set to Dry mode
|
||||||
|
|
||||||
#define CMD_RGB 0x17
|
#define CMD_RGB 0x17
|
||||||
#define CMD_HSV 0x18
|
#define CMD_HSV 0x18
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ case S_CMD:
|
|||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
if (!item->getExt())
|
if (!item->getExt())
|
||||||
{
|
{
|
||||||
item->setExt(millisNZ());
|
item->setExt(millisNZ());
|
||||||
|
|||||||
@@ -9,13 +9,23 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
void convert2float(aJsonObject * o)
|
||||||
|
{
|
||||||
|
if (!o) return;
|
||||||
|
switch (o->type)
|
||||||
|
{
|
||||||
|
case aJson_Int:
|
||||||
|
o->valuefloat = o->valueint;
|
||||||
|
o->type = aJson_Float;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void out_Multivent::getConfig()
|
void out_Multivent::getConfig()
|
||||||
{
|
{
|
||||||
gatesObj = NULL;
|
gatesObj = NULL;
|
||||||
if (!item || !item->itemArg || item->itemArg->type != aJson_Object) return;
|
if (!item || !item->itemArg || item->itemArg->type != aJson_Object) return;
|
||||||
gatesObj = item->itemArg;
|
gatesObj = item->itemArg;
|
||||||
//acTemp=(float) item->getExt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_Multivent::Setup()
|
int out_Multivent::Setup()
|
||||||
@@ -31,78 +41,37 @@ if (gatesObj)
|
|||||||
{
|
{
|
||||||
if (i->name && *i->name)
|
if (i->name && *i->name)
|
||||||
{
|
{
|
||||||
// aJsonObject * fanObj = aJson.getObjectItem(i, "fan");
|
getCreateObject(i,"fan",-1L);
|
||||||
// if (!fanObj) {aJson.addNumberToObject(i, "fan", (long int) -1);fanObj = aJson.getObjectItem(i, "fan");}
|
getCreateObject(i,"cmd",(long) CMD_OFF);
|
||||||
aJsonObject * fanObj = getCreateObject(i,"fan",-1L);
|
getCreateObject(i,"out",-1L);
|
||||||
|
//getCreateObject(i,"@C",(long) CMD_OFF);
|
||||||
// aJsonObject * cmdObj = aJson.getObjectItem(i, "cmd");
|
|
||||||
// if (!cmdObj) {aJson.addNumberToObject(i, "cmd", (long int) -1);cmdObj = aJson.getObjectItem(i, "cmd");}
|
|
||||||
aJsonObject * cmdObj = getCreateObject(i,"cmd",(long) CMD_OFF);
|
|
||||||
|
|
||||||
//aJsonObject * outObj = aJson.getObjectItem(i, "out");
|
|
||||||
//if (!outObj) {aJson.addNumberToObject(i, "out", (long int) -1);outObj = aJson.getObjectItem(i, "out");}
|
|
||||||
aJsonObject * outObj = getCreateObject(i,"out",-1L);
|
|
||||||
|
|
||||||
aJsonObject * pidObj = aJson.getObjectItem(i, "pid");
|
aJsonObject * pidObj = aJson.getObjectItem(i, "pid");
|
||||||
if (pidObj && pidObj->type == aJson_Array && aJson.getArraySize(pidObj)>=3)
|
if (pidObj && pidObj->type == aJson_Array && aJson.getArraySize(pidObj)>=3)
|
||||||
{
|
{
|
||||||
//aJsonObject * setObj = aJson.getObjectItem(i, "set");
|
aJsonObject * setObj = getCreateObject(i,"set",(float) 20.0);
|
||||||
//if (!setObj) {aJson.addNumberToObject(i, "set", (float) 20.1);setObj = aJson.getObjectItem(i, "set");}
|
convert2float(setObj);
|
||||||
// else if (setObj->type != aJson_Float) {setObj->valuefloat = 20.0;setObj->type= aJson_Float;}
|
aJsonObject * valObj = getCreateObject(i,"val",(float) 20.0);
|
||||||
aJsonObject * setObj = getCreateObject(i,"set",(float) 20.0);
|
convert2float(valObj);
|
||||||
|
aJsonObject * poObj = getCreateObject(i,"po", (float) -2.0);
|
||||||
//aJsonObject * valObj = aJson.getObjectItem(i, "val");
|
convert2float(poObj);
|
||||||
//if (!valObj) {aJson.addNumberToObject(i, "val", (float) 20.1);valObj = aJson.getObjectItem(i, "val");}
|
|
||||||
// else if (valObj->type != aJson_Float) {valObj->valuefloat = 20.0;valObj->type= aJson_Float;}
|
|
||||||
aJsonObject * valObj = getCreateObject(i,"val",(float) 20.0);
|
|
||||||
|
|
||||||
//aJsonObject * poObj = aJson.getObjectItem(i, "po");
|
|
||||||
//if (!poObj) {aJson.addNumberToObject(i, "po", (float) -1.1);poObj = aJson.getObjectItem(i, "po");}
|
|
||||||
// else if (poObj->type != aJson_Float) {poObj->valuefloat = -2.0;valObj->type= aJson_Float;}
|
|
||||||
aJsonObject * poObj = getCreateObject(i,"po", (long) -2);
|
|
||||||
|
|
||||||
float kP = 1.0;
|
|
||||||
float kI = 0.0;
|
|
||||||
float kD = 0.0;
|
|
||||||
|
|
||||||
int direction = DIRECT;
|
int direction = DIRECT;
|
||||||
|
float kP=getFloatFromJson(pidObj,0,1.0);
|
||||||
// aJsonObject * param = aJson.getArrayItem(pidObj, 0);
|
|
||||||
// if (param->type == aJson_Float) kP=param->valuefloat;
|
|
||||||
// else if (param->type == aJson_Int) kP=param->valueint;
|
|
||||||
kP=getFloatFromJson(pidObj,0,1.0);
|
|
||||||
if (kP<0)
|
if (kP<0)
|
||||||
{
|
{
|
||||||
kP=-kP;
|
kP=-kP;
|
||||||
direction=REVERSE;
|
direction=REVERSE;
|
||||||
}
|
}
|
||||||
//param = aJson.getArrayItem(pidObj, 1);
|
float kI=getFloatFromJson(pidObj,1);
|
||||||
//if (param->type == aJson_Float) kI=param->valuefloat;
|
float kD=getFloatFromJson(pidObj,2);
|
||||||
// else if (param->type == aJson_Int) kI=param->valueint;
|
float dT=getFloatFromJson(pidObj,3,5.0);
|
||||||
kI=getFloatFromJson(pidObj,1);
|
|
||||||
|
|
||||||
//param = aJson.getArrayItem(pidObj, 2);
|
|
||||||
//if (param->type == aJson_Float) kD=param->valuefloat;
|
|
||||||
// else if (param->type == aJson_Int) kD=param->valueint;
|
|
||||||
kD=getFloatFromJson(pidObj,2);
|
|
||||||
|
|
||||||
float dT;
|
|
||||||
//if (aJson.getArraySize(pidObj)==4)
|
|
||||||
//{
|
|
||||||
//param = aJson.getArrayItem(pidObj, 3);
|
|
||||||
//if (param->type == aJson_Float) dT=param->valuefloat;
|
|
||||||
// else if (param->type == aJson_Int) dT=param->valueint;
|
|
||||||
//}
|
|
||||||
dT=getFloatFromJson(pidObj,3,5.0);
|
|
||||||
|
|
||||||
debugSerial << "VENT: X:" << (long int) &valObj->valuefloat << "-" << (long int)&poObj->valuefloat <<"="<< (long int)&setObj->valuefloat<<endl;
|
|
||||||
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);
|
||||||
debugSerial << "VENT: Y:" << (long int)((PID*) pidObj->valueint)->myInput << "-" << (long int)((PID*) pidObj->valueint)->myOutput <<"="<< (long int)((PID*) pidObj->valueint)->mySetpoint<<endl;
|
|
||||||
|
|
||||||
((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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i=i->next;
|
i=i->next;
|
||||||
@@ -148,47 +117,103 @@ int out_Multivent::Poll(short cause)
|
|||||||
if (cause == POLLING_SLOW && item->getExt() && isTimeOver(item->getExt(),millisNZ(),60000L))
|
if (cause == POLLING_SLOW && item->getExt() && isTimeOver(item->getExt(),millisNZ(),60000L))
|
||||||
{
|
{
|
||||||
item->setExt(0);
|
item->setExt(0);
|
||||||
item->setCmd((isActive())?CMD_ON:CMD_OFF); // if AC temp unknown - change state to ON or OFF instead HEAT|COOL|FAN
|
//item->setCmd((isActive())?CMD_ON:CMD_OFF); // if AC temp unknown - change state to ON or OFF instead HEAT|COOL|FAN
|
||||||
|
aJsonObject * a = aJson.getObjectItem(aJson.getObjectItem(gatesObj, ""),"val");
|
||||||
|
if (a ) a->type = aJson_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (gatesObj)
|
if (gatesObj)
|
||||||
{
|
{
|
||||||
|
// metrics, collected from AC
|
||||||
|
float acTemp = getFloatFromJson(aJson.getObjectItem(gatesObj, ""),"val",NAN);
|
||||||
|
int actualCmd = item->getCmd();
|
||||||
|
int actualMode = CMD_FAN;
|
||||||
|
if (acTemp>30.0) actualMode = CMD_HEAT;
|
||||||
|
else if (acTemp<15.0) actualMode = CMD_COOL;
|
||||||
|
|
||||||
|
|
||||||
aJsonObject * i = gatesObj->child;
|
aJsonObject * i = gatesObj->child;
|
||||||
|
int balance = 0;
|
||||||
|
bool ventRequested = false; //At least 1 ch requested FAN mode
|
||||||
while (i)
|
while (i)
|
||||||
{
|
{
|
||||||
if (i->name && *i->name)
|
if (i->name && *i->name)
|
||||||
{
|
{
|
||||||
|
int cmd = getIntFromJson(i,"cmd");
|
||||||
|
float set = getIntFromJson(i,"set");
|
||||||
|
float val = getIntFromJson(i,"val");
|
||||||
|
|
||||||
|
int execCmd = 0;
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case CMD_HEATCOOL:
|
||||||
|
{
|
||||||
|
if (set>val) execCmd = CMD_HEAT;
|
||||||
|
if (set<val) execCmd = CMD_COOL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CMD_FAN:
|
||||||
|
ventRequested = true;
|
||||||
|
case CMD_AUTO: //Passive regulation mode
|
||||||
|
case CMD_COOL:
|
||||||
|
case CMD_HEAT:
|
||||||
|
case CMD_OFF:
|
||||||
|
//setValToJson(i,"@C",cmd);
|
||||||
|
execCmd = cmd;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
aJsonObject * pidObj = aJson.getObjectItem(i, "pid");
|
aJsonObject * pidObj = aJson.getObjectItem(i, "pid");
|
||||||
if (pidObj && pidObj->valueint)
|
if (pidObj && pidObj->valueint)
|
||||||
{
|
{
|
||||||
PID * p = (PID *) pidObj->valueint;
|
PID * p = (PID *) pidObj->valueint;
|
||||||
if (p->Compute())
|
if (p->Compute())
|
||||||
{
|
{
|
||||||
aJsonObject * outObj = aJson.getObjectItem(i,"po");
|
aJsonObject * poObj = aJson.getObjectItem(i,"po");
|
||||||
if (outObj && outObj->type == aJson_Float)
|
if (poObj && poObj->type == aJson_Float)
|
||||||
{
|
{
|
||||||
debugSerial<<F("VENT: ")
|
debugSerial<<F("VENT: ")
|
||||||
<<item->itemArr->name<<"/"<<i->name
|
<<item->itemArr->name<<"/"<<i->name
|
||||||
<<F(" in:")<<p->GetIn()<<F(" set:")<<p->GetSet()<<F(" out:")<<p->GetOut()
|
<<F(" in:")<<p->GetIn()<<F(" set:")<<p->GetSet()<<F(" out:")<<p->GetOut()
|
||||||
// <<F(" in:")<<getFloatFromJson(i,"val")<<(" set:")<<getFloatFromJson(i,"set")<<F(" out:")<<outObj->valuefloat
|
<<" 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;
|
||||||
|
|
||||||
|
|
||||||
switch (item->getCmd())
|
switch (execCmd)
|
||||||
{
|
{
|
||||||
|
case CMD_AUTO: //Passive
|
||||||
|
switch (actualMode)
|
||||||
|
{
|
||||||
|
case CMD_HEAT:
|
||||||
|
((PID *) pidObj->valueint)->SetControllerDirection(DIRECT);
|
||||||
|
debugSerial<<F("VENT: PASS PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set DIRECT mode")<<endl;
|
||||||
|
Ctrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name);
|
||||||
|
break;
|
||||||
|
case CMD_COOL:
|
||||||
|
((PID *) pidObj->valueint)->SetControllerDirection(REVERSE);
|
||||||
|
debugSerial<<F("VENT: PASS PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set REVERSE mode")<<endl;
|
||||||
|
Ctrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
((PID *) pidObj->valueint)->SetControllerDirection(DIRECT);
|
((PID *) pidObj->valueint)->SetControllerDirection(DIRECT);
|
||||||
debugSerial<<F("VENT: PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set DIRECT mode")<<endl;
|
debugSerial<<F("VENT: PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set DIRECT mode")<<endl;
|
||||||
|
|
||||||
Ctrl(itemCmd().Percents255(outObj->valuefloat).setSuffix(S_FAN),i->name);
|
if (actualCmd==CMD_HEAT) Ctrl(itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name);
|
||||||
|
//else?
|
||||||
|
|
||||||
|
balance+=poObj->valuefloat;
|
||||||
break;
|
break;
|
||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
//case CMD_FAN: // if PIB using for vent
|
//case CMD_FAN: // if PIB using for vent
|
||||||
//case CMD_ON: // AC temp unknown - assuming that PID used for vent
|
//case CMD_ON: // AC temp unknown - assuming that PID used for vent
|
||||||
((PID *) pidObj->valueint)->SetControllerDirection(REVERSE);
|
((PID *) pidObj->valueint)->SetControllerDirection(REVERSE);
|
||||||
debugSerial<<F("VENT: PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set REVERSE mode")<<endl;
|
debugSerial<<F("VENT: PID: ")<<item->itemArr->name<<"/"<<i->name<<F(" set REVERSE mode")<<endl;
|
||||||
Ctrl(itemCmd().Percents255(outObj->valuefloat).setSuffix(S_FAN),i->name);
|
if (actualCmd==CMD_COOL) (itemCmd().Percents255(poObj->valuefloat).setSuffix(S_FAN),i->name);
|
||||||
|
//else ?
|
||||||
|
balance-=poObj->valuefloat;
|
||||||
break;
|
break;
|
||||||
// if FAN_ONLY (AC report room temp regularry) - not use internal PID - let be on external control via /fan
|
// if FAN_ONLY (AC report room temp regularry) - not use internal PID - let be on external control via /fan
|
||||||
}
|
}
|
||||||
@@ -199,11 +224,32 @@ int out_Multivent::Poll(short cause)
|
|||||||
|
|
||||||
}
|
}
|
||||||
i=i->next;
|
i=i->next;
|
||||||
}
|
}//while
|
||||||
|
if (balance) debugSerial<<F("VENT: Chan balance=")<<balance<<endl;
|
||||||
|
if (balance>0) sendACcmd (CMD_HEAT);
|
||||||
|
else if (balance<0) sendACcmd (CMD_COOL);
|
||||||
|
else if (ventRequested) sendACcmd(CMD_FAN);
|
||||||
|
// else sendACcmd (CMD_OFF);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int out_Multivent::sendACcmd (int cmd)
|
||||||
|
{
|
||||||
|
aJsonObject * a = aJson.getObjectItem(gatesObj, "");
|
||||||
|
if (!a) return 0;
|
||||||
|
int lastCmd = getIntFromJson(a,"@lastCmd");
|
||||||
|
if (lastCmd && (item->getCmd() != 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(a,-1,itemCmd().Cmd(cmd).setSuffix(S_CMD));
|
||||||
|
setValToJson(a,"@lastCmd",cmd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int out_Multivent::getChanType()
|
int out_Multivent::getChanType()
|
||||||
{
|
{
|
||||||
return CH_PWM;
|
return CH_PWM;
|
||||||
@@ -217,24 +263,49 @@ if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
|||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||||
|
|
||||||
if (suffixCode == S_VAL && !subItem && cmd.isValue())
|
|
||||||
{
|
|
||||||
//item->setExt((long)cmd.getFloat());
|
|
||||||
debugSerial << F("VENT:")<<F("AC air temp: ")<< cmd.getFloat()<<endl;
|
|
||||||
item->setExt(millisNZ());
|
|
||||||
int mode = CMD_FAN;
|
|
||||||
int temp = cmd.getInt();
|
|
||||||
if (temp>30) mode = CMD_HEAT;
|
|
||||||
else if (temp<17) mode = CMD_COOL;
|
|
||||||
|
|
||||||
if (item->getCmd() != mode)
|
if (!subItem) // feedback from shared AC
|
||||||
{
|
{
|
||||||
item->setCmd(mode);
|
switch (suffixCode)
|
||||||
pubAction(item->isActive());
|
{
|
||||||
}
|
case S_VAL:
|
||||||
|
if (cmd.isValue())
|
||||||
|
{
|
||||||
|
debugSerial << F("VENT:")<<F("AC air temp: ")<< cmd.getFloat()<<endl;
|
||||||
|
item->setExt(millisNZ());
|
||||||
|
setValToJson(aJson.getObjectItem(gatesObj, ""),"val",cmd.getFloat());
|
||||||
|
/*
|
||||||
|
int mode = CMD_FAN;
|
||||||
|
int temp = cmd.getInt();
|
||||||
|
if (temp>30) mode = CMD_HEAT;
|
||||||
|
else if (temp<17) mode = CMD_COOL;
|
||||||
|
|
||||||
|
if (item->getCmd() != mode)
|
||||||
|
{
|
||||||
|
item->setCmd(mode);
|
||||||
|
pubAction(item->isActive());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case S_FAN:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case S_SET:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case S_MODE:
|
||||||
|
case S_CMD:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case S_TEMP:
|
||||||
|
debugSerial << F("VENT:")<<F("AC air roomtemp: ")<< cmd.getFloat()<<endl;
|
||||||
|
setValToJson(aJson.getObjectItem(gatesObj, ""),"roomtemp",cmd.getFloat());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
aJsonObject * i = NULL;
|
aJsonObject * i = NULL;
|
||||||
|
|
||||||
if (cmd.isCommand() && cmd.getSuffix()==S_FAN)
|
if (cmd.isCommand() && cmd.getSuffix()==S_FAN)
|
||||||
@@ -347,6 +418,7 @@ while (i)
|
|||||||
sendFlags |= FLAG_FLAGS;
|
sendFlags |= FLAG_FLAGS;
|
||||||
break;
|
break;
|
||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
@@ -371,8 +443,6 @@ while (i)
|
|||||||
case S_SET:
|
case S_SET:
|
||||||
if (cmd.isValue())
|
if (cmd.isValue())
|
||||||
{
|
{
|
||||||
//if (!setObj) {aJson.addNumberToObject(i, "set", (float) cmd.getFloat()); setObj = aJson.getObjectItem(i, "set"); }
|
|
||||||
// else {setObj->valuefloat = cmd.getFloat();setObj->type = aJson_Float;}
|
|
||||||
setValToJson(i,"set",cmd.getFloat());
|
setValToJson(i,"set",cmd.getFloat());
|
||||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
|
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
|
||||||
|
|
||||||
@@ -382,9 +452,7 @@ while (i)
|
|||||||
case S_VAL:
|
case S_VAL:
|
||||||
if (cmd.isValue())
|
if (cmd.isValue())
|
||||||
{
|
{
|
||||||
//aJsonObject * valObj = aJson.getObjectItem(i, "val");
|
debugSerial<<F("VENT: value ")<<cmd.getFloat()<<endl;
|
||||||
//if (!valObj) {aJson.addNumberToObject(i, "val", (float) cmd.getFloat()); setObj = aJson.getObjectItem(i, "val");}
|
|
||||||
// else {valObj->valuefloat = cmd.getFloat();valObj->type= aJson_Float;}
|
|
||||||
setValToJson(i,"val",cmd.getFloat());
|
setValToJson(i,"val",cmd.getFloat());
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public:
|
|||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
protected:
|
protected:
|
||||||
void getConfig();
|
void getConfig();
|
||||||
|
int sendACcmd (int cmd);
|
||||||
aJsonObject * gatesObj;
|
aJsonObject * gatesObj;
|
||||||
//float acTemp;
|
//float acTemp;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ case S_CTRL:
|
|||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
|
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
|
||||||
executeCommand(oCmd,-1,value);
|
executeCommand(oCmd,-1,value);
|
||||||
item->SendStatus(FLAG_FLAGS);
|
item->SendStatus(FLAG_FLAGS);
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ case S_SET:
|
|||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
case CMD_HEAT:
|
case CMD_HEAT:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
if (cmd.getPercents255() && !item->getExt()) item->setExt(millisNZ());
|
if (cmd.getPercents255() && !item->getExt()) item->setExt(millisNZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,6 +158,7 @@ case S_CMD:
|
|||||||
case CMD_AUTO:
|
case CMD_AUTO:
|
||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
|
case CMD_HEATCOOL:
|
||||||
if (!item->getExt())
|
if (!item->getExt())
|
||||||
{
|
{
|
||||||
item->setExt(millisNZ());
|
item->setExt(millisNZ());
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ const char on_P[] PROGMEM = "on";
|
|||||||
#define HEAT_P commands_P[CMD_HEAT]
|
#define HEAT_P commands_P[CMD_HEAT]
|
||||||
#define COOL_P commands_P[CMD_COOL]
|
#define COOL_P commands_P[CMD_COOL]
|
||||||
#define AUTO_P commands_P[CMD_AUTO]
|
#define AUTO_P commands_P[CMD_AUTO]
|
||||||
|
#define HEATCOOL_P commands_P[CMD_HEATCOOL]
|
||||||
#define FAN_ONLY_P commands_P[CMD_FAN]
|
#define FAN_ONLY_P commands_P[CMD_FAN]
|
||||||
#define DRY_P commands_P[CMD_DRY]
|
#define DRY_P commands_P[CMD_DRY]
|
||||||
#define HIGH_P commands_P[CMD_HIGH]
|
#define HIGH_P commands_P[CMD_HIGH]
|
||||||
|
|||||||
@@ -1109,8 +1109,8 @@ if (a->type == aJson_Object)
|
|||||||
{
|
{
|
||||||
aJson.addNullToObject(a, name);
|
aJson.addNullToObject(a, name);
|
||||||
element = aJson.getObjectItem(a, name);
|
element = aJson.getObjectItem(a, name);
|
||||||
return element;
|
|
||||||
}
|
}
|
||||||
|
return element;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,11 +117,12 @@ if (a->type == aJson_Array)
|
|||||||
{
|
{
|
||||||
aJsonObject * element = aJson.getArrayItem(a, n);
|
aJsonObject * element = aJson.getArrayItem(a, n);
|
||||||
if (!element)
|
if (!element)
|
||||||
|
{
|
||||||
for (int i = aJson.getArraySize(a); i < n; i++)
|
for (int i = aJson.getArraySize(a); i < n; i++)
|
||||||
if (i==n-1)
|
if (i==n-1)
|
||||||
aJson.addItemToArray(a, element = aJson.createItem(val));
|
aJson.addItemToArray(a, element = aJson.createItem(val));
|
||||||
else aJson.addItemToArray(a, element = aJson.createNull());
|
else aJson.addItemToArray(a, element = aJson.createNull());
|
||||||
|
}
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -140,8 +141,8 @@ if (a->type == aJson_Object)
|
|||||||
{
|
{
|
||||||
aJson.addNumberToObject(a, name, def);
|
aJson.addNumberToObject(a, name, def);
|
||||||
element = aJson.getObjectItem(a, name);
|
element = aJson.getObjectItem(a, name);
|
||||||
return element;
|
|
||||||
}
|
}
|
||||||
|
return element;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user