core refactored (Alpha)

This commit is contained in:
2021-08-17 19:40:03 +03:00
parent 8e96b4623f
commit 674a438bde
12 changed files with 383 additions and 406 deletions

View File

@@ -62,7 +62,7 @@ case S_HSV:
PixelCtrl(cmd, subItem, toExecute);
return 1;
case S_CMD:
item->setCmd(cmd.getCmd());
//item->setCmd(cmd.getCmd());
switch (cmd.getCmd())
{
case CMD_ON:

View File

@@ -71,49 +71,74 @@ bool systemConfig::isValidSysConf()
return isMacValid;
}
bool systemConfig::getMQTTpwd(char * buffer, uint16_t bufLen)
bool systemConfig::setMAC(macAddress& _mac)
{
return 0;
if (!stream || !isValidSysConf()) return false;
stream->seek(offsetof(systemConfigData,mac));
///stream->write ((const uint8_t *)&_mac,sizeof(_mac));
memcpy(mac, _mac, sizeof(mac));
return true;
}
char * systemConfig::getMQTTpwd(char * buffer, uint16_t bufLen)
{
if (!stream || !isValidSysConf()) return NULL;
stream->seek(offsetof(systemConfigData,MQTTpwd));
if (stream->readBytesUntil(0,buffer,bufLen)) return buffer;
return NULL;
}
bool systemConfig::setMQTTpwd(char * pwd)
{
return 0;
if (!stream || !isValidSysConf()) return false;
stream->seek(offsetof(systemConfigData,MQTTpwd));
stream->print(pwd);
return stream->write(0);
}
bool systemConfig::getOTApwd(char * buffer, uint16_t bufLen)
char * systemConfig::getOTApwd(char * buffer, uint16_t bufLen)
{
return 0;
if (!stream || !isValidSysConf()) return NULL;
stream->seek(offsetof(systemConfigData,OTApwd));
if (stream->readBytesUntil(0,buffer,bufLen)) return buffer;
return NULL;
}
bool systemConfig::setOTApwd(char * pwd)
{
return 0;
if (!stream || !isValidSysConf()) return false;
stream->seek(offsetof(systemConfigData,OTApwd));
stream->print(pwd);
return stream->write(0);
}
bool systemConfig::setMAC(macAddress mac)
char * systemConfig::getServer(char * buffer, uint16_t bufLen)
{
return 0;
if (!stream || !isValidSysConf()) return NULL;
stream->seek(offsetof(systemConfigData,configURL));
if (stream->readBytesUntil(0,buffer,bufLen)) return buffer;
return NULL;
}
bool systemConfig::setServer(char* url)
{
return 0;
}
if (!stream || !isValidSysConf()) return false;
stream->seek(offsetof(systemConfigData,OTApwd));
stream->print(url);
return stream->write(0);
bool systemConfig::getServer(char* url)
{
return 0;
}
bool systemConfig::getIP(IPAddress& ip)
{
return 0;
if (!stream || !isValidSysConf()) return false;
stream->seek(offsetof(systemConfigData,ip));
stream->readBytes((char *)&ip,sizeof(ip));
return ip;
}

View File

@@ -57,21 +57,20 @@ class systemConfig {
macAddress mac;
systemConfig() {stream=NULL;};
systemConfig(flashStream * fs){stream=fs;};
//systemConfigData data;
bool isValidSysConf();
//bool isValidJSON();
bool getMAC();
//inline macAddress * getMAC() {return &mac;};
bool getMQTTpwd(char * buffer, uint16_t bufLen);
bool isValidSysConf();
bool getMAC();
bool setMAC(macAddress& mac);
char * getMQTTpwd(char * buffer, uint16_t bufLen);
bool setMQTTpwd(char * pwd = NULL);
bool getOTApwd(char * buffer, uint16_t bufLen);
char * getOTApwd(char * buffer, uint16_t bufLen);
bool setOTApwd(char * pwd = NULL);
bool setMAC(macAddress mac);
bool setServer(char* url);
bool getServer(char* url);
char * getServer(char * buffer, uint16_t bufLen);
bool getIP(IPAddress& ip);
bool getMask(IPAddress& mask);

View File

@@ -127,7 +127,7 @@ void Item::Parse() {
if (isValid()) {
// Todo - avoid static enlarge for every types
for (int i = aJson.getArraySize(itemArr); i < 4; i++)
aJson.addItemToArray(itemArr, aJson.createItem( (long int) 0));
aJson.addItemToArray(itemArr, aJson.createNull());//( (long int) 0));
// int(defval[i]) )); //Enlarge item to 4 elements. VAL=int if no other definition in conf
itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint;
itemArg = aJson.getArrayItem(itemArr, I_ARG);
@@ -301,7 +301,7 @@ void Item::setFlag (short flag)
if (itemCmd)
{
itemCmd->valueint |= flag & FLAG_MASK; // Preserve CMD bits
debugSerial<<F("SetFlag:")<<flag<<endl;
// debugSerial<<F("SetFlag:")<<flag<<endl;
}
}
@@ -312,7 +312,7 @@ void Item::clearFlag (short flag)
if (itemCmd)
{
itemCmd->valueint &= CMD_MASK | ~(flag & FLAG_MASK); // Preserve CMD bits
debugSerial<<F("ClrFlag:")<<flag<<endl;
// debugSerial<<F("ClrFlag:")<<flag<<endl;
}
}
@@ -361,7 +361,7 @@ long int Item::getVal() //Return Val if val is int or first elem of Value array
uint8_t Item::getSubtype()
{
if (!itemVal) return 0;//-1;
if (itemVal->type == aJson_Int || itemVal->type == aJson_Float) return itemVal->subtype;
if (itemVal->type == aJson_Int || itemVal->type == aJson_Float || itemVal->type == aJson_NULL) return itemVal->subtype;
else if (itemVal->type == aJson_Array) {
aJsonObject *t = aJson.getArrayItem(itemVal, 0);
if (t) return t->subtype;
@@ -382,7 +382,7 @@ void Item::setVal(short n, int par) // Only store if VAL is array defined in c
void Item::setVal(long int par) // Only store if VAL is int (autogenerated or config-defined)
{
if (!itemVal || (itemVal->type != aJson_Int && itemVal->type != aJson_Float)) return;
if (!itemVal || (itemVal->type != aJson_Int && itemVal->type != aJson_Float && itemVal->type != aJson_NULL)) return;
//debugSerial<<F(" Store ")<<F(" Val=")<<par<<endl;
itemVal->valueint = par;
itemVal->type = aJson_Int;
@@ -390,7 +390,7 @@ void Item::setVal(long int par) // Only store if VAL is int (autogenerated or c
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)) 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;
}
@@ -411,11 +411,12 @@ void Item::setExt(long int par) // Only store if VAL is int (autogenerated or c
if (!itemExt)
{
for (int i = aJson.getArraySize(itemArr); i <= 4; i++)
aJson.addItemToArray(itemArr, itemExt=aJson.createItem((long int)0));
aJson.addItemToArray(itemArr, itemExt=aJson.createNull());// Item((long int)0));
//itemExt = aJson.getArrayItem(itemArr, I_EXT);
};
if(!itemExt || itemExt->type != aJson_Int) return;
if(!itemExt ) return;
if(itemExt->type == aJson_NULL) itemExt->type=aJson_Int;
else if(itemExt->type != aJson_Int ) return;
itemExt->valueint = par;
debugSerial<<F("Stored EXT:")<<par<<endl;
}
@@ -433,11 +434,14 @@ chPersistent * Item::setPersistent(chPersistent * par)
if (!itemExt)
{
for (int i = aJson.getArraySize(itemArr); i <= 4; i++)
aJson.addItemToArray(itemArr, itemExt = aJson.createItem((long int)0));
aJson.addItemToArray(itemArr, itemExt = aJson.createNull());//Item((long int)0));
//itemExt = aJson.getArrayItem(itemArr, I_EXT);
};
if(!itemExt || (itemExt->type != aJson_Int)) return NULL;
if(!itemExt ) return NULL;
if(itemExt->type == aJson_NULL) itemExt->type=aJson_Int;
else if(itemExt->type != aJson_Int ) return NULL;
itemExt->valueint = 0;
itemExt->child = (aJsonObject *) par;
// debugSerial<<F("Persisted.")<<endl;
return par;
@@ -481,8 +485,6 @@ else
return suffixCode;
}
//#define MAXCTRLPAR 3
// myhome/dev/item/subItem
int Item::Ctrl(char * payload, char * subItem)
{
@@ -511,7 +513,7 @@ int i=0;
while (payload[i]) {payload[i]=toupper(payload[i]);i++;};
int cmd = txt2cmd(payload);
debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
//debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
itemCmd st(ST_VOID,cmd);
@@ -526,26 +528,6 @@ switch (suffixCode) {
st.setSuffix(suffixCode);
switch (cmd) {
/*
case CMD_ON:
case CMD_OFF:
case CMD_TOGGLE:
case CMD_HALT:
case CMD_RESTORE:
case CMD_XON:
case CMD_XOFF:
case CMD_UP:
case CMD_DN:
{
return Ctrl(st,subItem);
}
break;
*/
case CMD_HSV:
st.Cmd(0);
case CMD_VOID:
@@ -668,17 +650,20 @@ bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem)
return false;
}
//Main routine to control Item
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
{
//char stringBuffer[16];
int suffixCode = cmd.getSuffix();
bool operation = isNotRetainingStatus() ;
bool operation = isNotRetainingStatus();
if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem))
subItem = defaultSubItem; /// possible problem here with truncated default
if (!suffixCode && subItem && strlen(subItem))
{
suffixCode = retrieveCode(&subItem);
if (!cmd.getSuffix()) cmd.setSuffix(suffixCode);
}
if (!suffixCode && defaultSuffixCode)
{
@@ -688,15 +673,18 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
int fr = freeRam();
debugSerial<<F("RAM=")<<fr<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItem<<F(" Cmd:");
if (fr < 200) {
if (fr < 200)
{
errorSerial<<F("OutOfMemory!\n")<<endl;
return -1;
}
cmd.debugOut();
debugSerial<<endl;
if (!itemArr) return -1;
/// DELAYED COMMANDS processing
if (suffixCode == S_DELAYED)
{
for (int i = aJson.getArraySize(itemArr); i < I_TIMESTAMP+1; i++)
@@ -714,21 +702,59 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
else
{
timestampObj->subtype=0;
debugSerial<<F( "Disarmed")<<endl;
debugSerial<<F( " Disarmed")<<endl;
}
return 1;
}
return 0;
}
bool chActive = (isActive()>0);
bool toExecute = chActive; // execute if channel is active now
///
int8_t chActive = -1;
bool toExecute = false;
bool scale100 = false;
int res = -1;
uint16_t status2Send = 0;
uint8_t command2Set = 0;
debugSerial<<endl;
/// Common (GRP & NO GRP) commands
switch (cmd.getCmd())
{
case CMD_TOGGLE:
chActive=(isActive()>0);
toExecute=true;
if (itemType != CH_GROUP )
if (chActive) cmd.Cmd(CMD_OFF);
else
{
cmd.loadItemDef(this);
cmd.Cmd(CMD_ON);
}
status2Send |=SEND_COMMAND | SEND_IMMEDIATE;
break;
// TBD - INCREMENT-DECREMENT
}
///
if (itemType==CH_GROUP)
{
if (allowRecursion && itemArg->type == aJson_Array && operation)
{
digGroup(itemArg,&cmd,subItem);
status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE;
res=1;
}
// return 1;
} // GROUP
else
{ // NON GROUP part
if (chActive<0) chActive = (isActive()>0);
toExecute=chActive || toExecute; // Execute if active
if (subItem)
{
//Check if subitem is some sort of command
int subitemCmd = subitem2cmd(subItem);
@@ -744,287 +770,214 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
}
subItem=NULL;
}
}
if (subItem) // Fast track for commands to subitems
///
else // Fast track for commands to subitems
{
if (itemType==CH_GROUP)
{
if (allowRecursion && itemArg->type == aJson_Array && operation) digGroup(itemArg,&cmd,subItem);
return 1;
}
if (driver) return driver->Ctrl(cmd,subItem,toExecute);
return 0;
}
itemCmd st(ST_VOID,CMD_VOID);
//Restore previous channel state to "st"
//if no values - set default values, save and put to MQTT
if (!st.loadItem(this))
{
debugSerial<<F("No stored values - default: ");
st.setChanType(getChanType());
st.setDefault();
st.saveItem(this);
st.debugOut();
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
}
//threating Toggle, Restore, XOFF (special conditional commands)/ convert to ON, OFF and SET values
// Commands for NON GROUP
//threating Restore, XOFF (special conditional commands)/ convert to ON, OFF and SET values
switch (cmd.getCmd()) {
int t;
case CMD_TOGGLE:
toExecute=true;
if (chActive) st.Cmd(CMD_OFF);
else st.Cmd(CMD_ON);
cmd.Cmd(st.getCmd()); // For GROUP control
break;
case CMD_RESTORE:
if (itemType != CH_GROUP) //individual threating of channels. Ignore restore command for groups
switch (t = getCmd()) {
case CMD_HALT: //previous command was HALT ?
debugSerial << F("Restored from:") << t << endl;
cmd.loadItemDef(this);
toExecute=true;
if (itemType == CH_THERMO) st.Cmd(CMD_AUTO); ////
else st.Cmd(CMD_ON); //turning on
if (itemType == CH_THERMO) cmd.Cmd(CMD_AUTO); ////
else cmd.Cmd(CMD_ON); //turning on
break;
default:
return -3;
}
status2Send |= SEND_COMMAND;
break;
case CMD_XOFF:
if (itemType != CH_GROUP) //individual threating of channels. Ignore restore command for groups
switch (t = getCmd()) {
case CMD_XON: //previous command was CMD_XON ?
debugSerial << F("Turned off from:") << t << endl;
toExecute=true;
st.Cmd(CMD_OFF); //turning Off
cmd.Cmd(CMD_OFF); //turning Off
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
break;
default:
debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl;
return -3;
}
break;
case CMD_DN:
case CMD_UP:
{
st.Cmd(CMD_VOID); // Converting to SET value command
short step=0;
if (cmd.isValue()) step=cmd.getInt();
if (!step) step=DEFAULT_INC_STEP;
if (cmd.getCmd() == CMD_DN) step=-step;
cmd.loadItemDef(this);
cmd.Cmd(CMD_VOID); // Converting to SET value command
switch (suffixCode)
{
case S_NOTFOUND:
toExecute=true;
case S_SET:
if (st.incrementPercents(step))
if (cmd.incrementPercents(step))
{
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
}
break;
case S_HUE:
//if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
if (st.incrementH(step))
if (cmd.incrementH(step))
{
st.setSuffix(S_SET);
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
cmd.setSuffix(S_SET);
}
break;
case S_SAT:
//if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
if (st.incrementS(step))
if (cmd.incrementS(step))
{
st.setSuffix(S_SET);
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
cmd.setSuffix(S_SET);
}
} //switch suffix
} //Case UP/DOWN
break;
case CMD_VOID: // No commands, just set value
{
itemCmd stored;
if (!cmd.isValue()) break;
switch (suffixCode)
{
case S_NOTFOUND: //For empty (universal) OPENHAB suffix - turn ON/OFF automatically
toExecute=true;
scale100=true; //openHab topic format
if (chActive>0 && !cmd.getInt()) st.Cmd(CMD_OFF);
if (chActive==0 && cmd.getInt()) st.Cmd(CMD_ON);
setCmd(st.getCmd());
st.saveItem(this);
SendStatus(SEND_COMMAND | SEND_DEFFERED);
if (chActive>0 && !cmd.getInt()) {cmd.Cmd(CMD_OFF);status2Send |= SEND_COMMAND | SEND_IMMEDIATE;}
if (chActive==0 && cmd.getInt()) {cmd.Cmd(CMD_ON);status2Send |= SEND_COMMAND | SEND_IMMEDIATE;}
// continue processing as SET
case S_SET:
stored.loadItemDef(this);
// if previous color was in RGB notation but new value is HSV - discard previous val and change type;
if ((st.getArgType() == ST_RGB || st.getArgType() == ST_RGBW) &&
if ((stored.getArgType() == ST_RGB || stored.getArgType() == ST_RGBW) &&
(cmd.getArgType() == ST_HSV255))
st.setArgType(cmd.getArgType());
stored.setArgType(cmd.getArgType());
if (itemType == CH_GROUP && cmd.isColor()) st.setArgType(ST_HSV255);//Extend storage for group channel
//if (itemType == CH_GROUP && cmd.isColor()) stored.setArgType(ST_HSV255);//Extend storage for group channel
//Convert value to most approptiate type for channel
st.assignFrom(cmd,getChanType());
if (scale100 || SCALE_VOLUME_100) st.scale100();
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
stored.assignFrom(cmd,getChanType());
if (scale100 || SCALE_VOLUME_100) stored.scale100();
cmd=stored;
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
break;
case S_VAL:
st=cmd;
break;
case S_SAT:
//if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
if (st.setS(cmd.getS()))
stored.loadItemDef(this);
if (stored.setS(cmd.getS()))
{
st.setSuffix(S_SET);
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
cmd=stored;
cmd.setSuffix(S_SET);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
}
break;
case S_HUE:
//if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
if (st.setH(cmd.getH()))
stored.loadItemDef(this);
if (stored.setH(cmd.getH()))
{
st.setSuffix(S_SET);
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
cmd=stored;
cmd.setSuffix(S_SET);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
}
break;
case S_TEMP:
//st.setSuffix(suffixCode);
st.setColorTemp(cmd.getColorTemp());
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
stored.loadItemDef(this);
stored.setColorTemp(cmd.getColorTemp());
cmd=stored;
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
}
}
break;
default:
st.Cmd(cmd.getCmd());
st.setSuffix(suffixCode);
toExecute=true;
} //Switch commands
if (driver) //New style modular code
{
int res = -1;
switch (st.getCmd()) ///cmd///???????st ??? wtf
{
case CMD_XON:
if (!chActive) //if channel was'nt active before CMD_XON
{
debugSerial<<F("Turning XON\n");
st.Cmd(CMD_ON);
res = driver->Ctrl(st, subItem);
setCmd(CMD_XON);
st.saveItem(this);
SendStatus(SEND_COMMAND);
cmd.Cmd(CMD_ON);
command2Set=CMD_XON;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
toExecute=true;
}
else
{ //cmd = CMD_ON;
debugSerial<<F("Already Active\n");
{
debugSerial<<F("XON:Already Active\n");
return -3;
}
break;
case CMD_HALT:
if (chActive) //if channel was active before CMD_HALT
{
st.Cmd(CMD_OFF);
res = driver->Ctrl(st, subItem);
setCmd(CMD_HALT);
st.saveItem(this);
SendStatus(SEND_COMMAND);
return res;
cmd.Cmd(CMD_OFF);
command2Set=CMD_HALT;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
toExecute=true;
}
else
{
debugSerial<<F("Already Inactive\n");
debugSerial<<F("HALT:Already Inactive\n");
return -3;
}
break;
case CMD_OFF:
if (getCmd() != CMD_HALT) //Halted, ignore OFF
{
//debugSerial<<"OFF! ";
//st.debugOut();
st.Cmd(CMD_OFF);
res = driver->Ctrl(st, subItem);
setCmd(CMD_OFF);
st.saveItem(this);
SendStatus(SEND_COMMAND);
}
else
{
debugSerial<<F("Already Halted\n");
return -3;
}
break;
case CMD_VOID:
case CMD_DN:
case CMD_UP:
res = driver->Ctrl(st, subItem, toExecute);
if (getCmd() == CMD_HALT) return -3; //Halted, ignore OFF
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
toExecute=true;
break;
case CMD_ON:
//debugSerial<<"ON!"<<endl;
if (chActive) break;
res = driver->Ctrl(st, subItem);
st.saveItem(this);
setCmd(st.getCmd());
SendStatus(SEND_COMMAND);
break;
default: //another command
if (cmd.isCommand()) st.Cmd(cmd.getCmd());
//debugSerial<<"DEF!"<<endl;
//st.debugOut();
res = driver->Ctrl(st, subItem);
st.saveItem(this);
if (st.isCommand())
if (chActive)
{
setCmd(st.getCmd());
SendStatus(SEND_COMMAND);
debugSerial<<F("ON:Already Active\n");
return -3;
}
}
debugSerial<<F("Driver Res:")<<res<<endl;
return res;
}
else //Driver not found
//==================
cmd.loadItemDef(this);
status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE;
toExecute=true;
break;
default:
if (cmd.isCommand()) status2Send |= SEND_COMMAND;
if (cmd.isValue()) status2Send |= SEND_PARAMETERS;
toExecute=true;
} //Switch commands
} // NO GROUP
// UPDATE internal variables
if (status2Send) cmd.saveItem(this,status2Send);
//debugSerial<<F("sts:")<<status2Send<<endl;
if (driver) //New style modular code
res = driver->Ctrl(cmd, subItem, toExecute);
else
{
switch (itemType) {
case CH_GROUP:
if (allowRecursion && itemArg->type == aJson_Array && operation)
digGroup(itemArg,&cmd,subItem);
break;
/// rest of Legacy monolite core code (to be refactored ) BEGIN ///
case CH_RELAY:
{
short iaddr=getArg();
short icmd =st.getCmd();
short icmd =cmd.getCmd();
if (iaddr)
{
@@ -1040,10 +993,12 @@ switch (itemType) {
pinMode(iaddr, OUTPUT);
if (inverse)
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_XON) ? LOW : HIGH));
digitalWrite(iaddr, k = ((icmd == CMD_ON) ? LOW : HIGH));
else
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_XON) ? HIGH : LOW));
digitalWrite(iaddr, k = ((icmd == CMD_ON) ? HIGH : LOW));
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
res=1;
}
}
break;
@@ -1058,78 +1013,70 @@ switch (itemType) {
thermostatStore tStore;
tStore.asint=getExt();
if (!tStore.timestamp16) mqttClient.publish("/alarmoff/snsr", itemArr->name);
tStore.tempX100=st.getFloat()*100.; //Save measurement
tStore.tempX100=cmd.getFloat()*100.; //Save measurement
tStore.timestamp16=millisNZ(8) & 0xFFFF; //And timestamp
debugSerial<<F(" T:")<<tStore.tempX100<<F(" TS:")<<tStore.timestamp16<<endl;
setExt(tStore.asint);
res=1;
}
break;
case S_SET:
st.saveItem(this);
status2Send |= SEND_PARAMETERS | SEND_IMMEDIATE;
res=1;
//st.saveItem(this);
break;
case S_CMD:
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
res=1;
}
break;
#ifndef MODBUS_DISABLE
case CH_MODBUS:
if (toExecute && !(chActive && st.getCmd()==CMD_ON && !cmd.isValue()))
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue()))
{
int vol;
if (!chActive && st.getCmd()== CMD_ON && (vol=st.getPercents())<MIN_VOLUME && vol>=0)
if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())<MIN_VOLUME && vol>=0)
{
st.setPercents(INIT_VOLUME);
st.saveItem(this);
SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
cmd.setPercents(INIT_VOLUME);
status2Send |= SEND_PARAMETERS | SEND_IMMEDIATE;
};
modbusDimmerSet(st);
res=modbusDimmerSet(cmd);
}
break;
case CH_VC:
if (toExecute && !(chActive && st.getCmd()==CMD_ON && !cmd.isValue())) VacomSetFan(st);
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetFan(cmd);
break;
case CH_VCTEMP:
if (toExecute && !(chActive && st.getCmd()==CMD_ON && !cmd.isValue())) VacomSetHeat(st);
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetHeat(cmd);
break;
#endif
/// rest of Legacy monolite core code (to be refactored ) END ///
} //switch
if (st.isCommand())
{
if (cmd.getCmd() == CMD_HALT)
{
if (chActive>0) //if channel was active before CMD_HALT
{
setCmd(CMD_HALT);
cmd.saveItem(this); ///
SendStatus(SEND_COMMAND);
}
}
else
{
setCmd(st.getCmd());
st.saveItem(this);
SendStatus(SEND_COMMAND);
}
}
}
return 1;
} //else (nodriver)
//update command for HALT & XON and send MQTT status
if (command2Set) setCmd(command2Set | SEND_COMMAND);
if (operation) SendStatus(status2Send);
debugSerial<<F("Ctrl Res:")<<res<<endl;
return res;
}
void printActiveStatus(bool active)
{
if (active) debugSerial<<F(" active ");
else debugSerial<<F(" inactive ");
if (active) debugSerial<<F("(+) ");
else debugSerial<<F("(-) ");
}
int Item::isActive() {
itemCmd st;
int val = 0;
debugSerial<<itemArr->name;
debugSerial<<itemArr->name<<F(" ");
if (!isValid())
{
debugSerial<<F(" invalid")<<endl;
@@ -1167,9 +1114,11 @@ int Item::isActive() {
switch (itemType) {
case CH_GROUP: //make recursive calculation - is it some active in group
if (itemArg->type == aJson_Array) {
debugSerial<<F(" Grp:");
debugSerial<<F("[");
val=digGroup(itemArg);
debugSerial<<F("]=");
printActiveStatus(val);
debugSerial<<endl;
return val;
} //if
break;
@@ -1278,7 +1227,7 @@ void Item::sendDelayedStatus()
int Item::SendStatus(int sendFlags) {
if (sendFlags & SEND_IMMEDIATE) sendFlags &= ~ (SEND_IMMEDIATE | SEND_DEFFERED);
if ((sendFlags & SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
setFlag(sendFlags & (SEND_COMMAND | SEND_PARAMETERS));
debugSerial<<F("Status deffered\n");
@@ -1287,8 +1236,9 @@ int Item::SendStatus(int sendFlags) {
else
{
itemCmd st(ST_VOID,CMD_VOID);
st.loadItem(this, true);
st.loadItem(this, SEND_COMMAND | SEND_PARAMETERS);
sendFlags |= getFlag(SEND_COMMAND | SEND_PARAMETERS); //if some delayed status is pending
//debugSerial<<F("ssi:")<<sendFlags<<endl;
return SendStatusImmediate(st,sendFlags);
}
}
@@ -1487,7 +1437,7 @@ int Item::checkModbusRetry() {
if (modbusBusy) return M_BUSY;
if (getFlag(SEND_RETRY)) { // if last sending attempt of command was failed
itemCmd val(ST_VOID,CMD_VOID);
val.loadItem(this, true);
val.loadItem(this, SEND_COMMAND | SEND_PARAMETERS);
debugSerial<<F("Retrying modbus CMD\n");
clearFlag(SEND_RETRY); // Clean retry flag
if (driver) result=driver->Ctrl(val);
@@ -1638,7 +1588,7 @@ int Item::VacomSetFan(itemCmd st) {
if (modbusBusy) {
// setCmd(cmd);
// setVal(val);
st.saveItem(this,true);
st.saveItem(this,SEND_PARAMETERS|SEND_COMMAND);
mb_fail();
return 0;
}
@@ -1685,7 +1635,7 @@ int addr;
if (modbusBusy) {
//setCmd(cmd);
//setVal(val);
st.saveItem(this,true);
st.saveItem(this,SEND_COMMAND|SEND_PARAMETERS);
mb_fail();
return 0;
}
@@ -1883,47 +1833,7 @@ int Item::checkFM() {
//resumeModbus();
return 1;
}
/*
boolean Item::checkModbusRetry() {
if (modbusBusy) return false;
if (getFlag(SEND_RETRY)) { // if last sending attempt of command was failed
itemCmd val(ST_VOID,CMD_VOID);
val.loadItem(this, true);
debugSerial<<F("Retrying dimmer CMD\n");
clearFlag(SEND_RETRY); // Clean retry flag
modbusDimmerSet(val);
return true;
}
return false;
}
boolean Item::checkVCRetry() {
if (modbusBusy) return false;
if (getFlag(SEND_RETRY)) { // if last sending attempt of command was failed
itemCmd val(ST_VOID,CMD_VOID);
val.loadItem(this, true);
debugSerial<<F("Retrying VC CMD\n");
clearFlag(SEND_RETRY); // Clean retry flag
VacomSetFan(val);
return true;
}
return false;
}
boolean Item::checkHeatRetry() {
if (modbusBusy) return false;
if (getFlag(SEND_RETRY)) { // if last sending attempt of command was failed
itemCmd val(ST_VOID,CMD_VOID);
val.loadItem(this, true);
debugSerial<<F("Retrying VC temp CMD\n");
clearFlag(SEND_RETRY); // Clean retry flag
VacomSetHeat(val);
return true;
}
return false;
}
*/
int Item::checkModbusDimmer() {
if (modbusBusy) return -1;
//if (checkModbusRetry()) return -2;
@@ -2020,7 +1930,7 @@ int Item::checkModbusDimmer(int data) {
if (d) { // Actually turned on
if (cmd != CMD_XON && cmd != CMD_ON) setCmd(CMD_ON); //store command
st.Percents255(d);
st.saveItem(this);
st.saveItem(this,SEND_PARAMETERS);
//setVal(d); //store value
if (cmd == CMD_OFF || cmd == CMD_HALT) SendStatus(SEND_COMMAND); //update OH with ON if it was turned off before
SendStatus(SEND_PARAMETERS); //update OH with value

View File

@@ -81,6 +81,7 @@ itemCmd::itemCmd(Item *item)
itemCmd itemCmd::setChanType(short chanType)
{
cmd.itemArgType=getStoragetypeByChanType(chanType);
debugSerial<<F("Chan type:")<<chanType<<F(" -> AT:")<<cmd.itemArgType<<endl;
return *this;
}
@@ -105,6 +106,7 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
case CH_RELAY:
case CH_VC:
case CH_MODBUS:
case CH_GROUP:
return ST_PERCENTS255;
break;
default:
@@ -356,6 +358,8 @@ itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
case ST_FLOAT:
param.v=constrain(from.param.asfloat,0.,255.);
break;
case ST_VOID:
break;
default:
debugSerial<<F("Wrong Assignment ")<<from.cmd.itemArgType<<F("->")<<cmd.itemArgType<<endl;
}
@@ -422,6 +426,8 @@ itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
param.s=from.param.s;
cmd.itemArgType=ST_HSV255;
break;
case ST_VOID:
break;
default:
debugSerial<<F("Wrong Assignment ")<<from.cmd.itemArgType<<F("->")<<cmd.itemArgType<<endl;
}
@@ -559,6 +565,8 @@ itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
debugOut();
break;
}
case ST_VOID:
break;
default:
debugSerial<<F("Wrong Assignment ")<<from.cmd.itemArgType<<F("->")<<cmd.itemArgType<<endl;
} //Translation to RGB_XX
@@ -685,7 +693,8 @@ short itemCmd::getPercents(bool inverse)
case ST_TENS:
if (inverse) return constrain (100-param.asInt32/10,0,100);
else return constrain(param.asInt32/10,0,100);
case ST_VOID:
return 0;
default:
return -1;
@@ -733,6 +742,8 @@ short itemCmd::getPercents255(bool inverse)
case ST_TENS:
if (inverse) return 255-constrain(param.asInt32/10,0,255); else return constrain(param.asInt32/10,0,255);
case ST_VOID:
return 0;
default:
return -1;
}
@@ -912,33 +923,38 @@ itemCmd itemCmd::setSuffix(uint8_t suffix)
return *this;
}
bool itemCmd::loadItem(Item * item, bool includeCommand)
bool itemCmd::loadItem(Item * item, uint16_t optionsFlag)
{
bool res = false;
if (item && item->isValid())
{
short subtype =item->getSubtype();
if (optionsFlag & SEND_COMMAND) cmd.cmdCode = item->getCmd();
if (subtype)
{
param.asInt32=item->getVal();
cmd.itemArgType= subtype;
if (includeCommand) cmd.cmdCode=item->getCmd();
// debugSerial<<F("Loaded :");
// debugOut();
return 1;
if (optionsFlag & SEND_PARAMETERS) param.asInt32 = item->getVal();
debugSerial<<F("Loaded :");
debugOut();
return true;
}
if (optionsFlag & SEND_PARAMETERS)
switch (item->itemVal->type)
{
case aJson_Int:
Int((int32_t)item->itemVal->valueint);
// debugSerial<<F("Loaded Int:");
// debugOut();
debugSerial<<F("Loaded Int:");
debugOut();
return true;
case aJson_Float:
Float(item->itemVal->valueint);
// debugSerial<<F("Loaded Float:");
// debugOut();
debugSerial<<F("Loaded Float:");
debugOut();
return true;
}
@@ -946,13 +962,34 @@ bool itemCmd::loadItem(Item * item, bool includeCommand)
return false;
}
bool itemCmd::saveItem(Item * item, bool includeCommand)
bool itemCmd::loadItemDef(Item * item, uint16_t optionsFlag)
{
//Restrieve previous channel state to "stored"
//if no values - set default values, save and put to MQTT
if (!loadItem(item,optionsFlag))
{
debugSerial<<F("No stored values - default: ");
setChanType(item->getChanType());
setDefault();
saveItem(item);
debugOut();
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
return false;
}
return true;
}
bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
{
if (item && item->isValid())
{
item->setVal(param.asInt32);
if (optionsFlag & SEND_COMMAND) item->setCmd(cmd.cmdCode);
if (optionsFlag & SEND_PARAMETERS)
{
item->setSubtype(cmd.itemArgType);
if (includeCommand) item->setCmd(cmd.cmdCode);
item->setVal(param.asInt32);
}
debugSerial<<F("Saved:");
debugOut();
return true;

View File

@@ -64,6 +64,7 @@ const cmdstr commands_P[] PROGMEM =
#define CMD_UNKNOWN -1
#define CMD_JSON -2
#define SEND_IMMEDIATE 0x1
#define SEND_COMMAND 0x100
#define SEND_PARAMETERS 0x200
#define SEND_RETRY 0x400
@@ -170,8 +171,9 @@ public:
itemCmd assignFrom(itemCmd from, short chanType=-1);
bool loadItem(Item * item, bool includeCommand=false );
bool saveItem(Item * item, bool includeCommand=false);
bool loadItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS);
bool loadItemDef(Item * item, uint16_t optionsFlag=SEND_PARAMETERS );
bool saveItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS);
itemCmd Int(int32_t i);
itemCmd Int(uint32_t i);

View File

@@ -332,15 +332,9 @@ int intopic;
}
void mqttCallback(char *topic, byte *payload, unsigned int length)
{
{
if (!payload) return;
payload[length] = 0;
// itemCommand(topic, (char*) payload);
// }
//int itemCommand(char *topic, char *payload){
int fr = freeRam();
@@ -370,9 +364,7 @@ else
}
itemName=topic+pfxlen;
debugSerial<<itemName<<endl;
// debugSerial<<itemName<<endl;
if(!strcmp(itemName,CMDTOPIC) && payload && (strlen((char*) payload)>1)) {
// mqttClient.publish(topic, "");
cmd_parse((char *)payload);
@@ -1419,7 +1411,7 @@ lan_status loadConfigFromHttp(int arg_cnt, char **args)
sysConf.setServer(configServer);
//saveFlash(OFFSET_CONFIGSERVER, configServer);
infoSerial<<configServer<<F(" Saved")<<endl;
} else if (!sysConf.getServer(configServer))
} else if (!sysConf.getServer(configServer,sizeof(configServer)))
{
strncpy_P(configServer,configserver,sizeof(configServer));
infoSerial<<F(" Default config server used: ")<<configServer<<endl;
@@ -1615,10 +1607,10 @@ volatile unsigned long timerCount=0;
volatile int16_t timerNumber=-1;
void TimerHandler(void)
{
timerCount=millis();
{ interrupts();
timerCount=micros();
if (configLoaded) inputLoop(CHECK_INTERRUPT);
timerCount=millis()-timerCount;
timerCount=micros()-timerCount;
}
@@ -2073,10 +2065,10 @@ void modbusIdle(void) {
#endif
}
volatile bool inputLoopBusy = false;
volatile int8_t inputLoopBusy = 0;
void inputLoop(short cause) {
if (!inputs || inputLoopBusy) return;
inputLoopBusy = true;
inputLoopBusy++;
configLocked++;
//if (millis() > timerInputCheck)
@@ -2130,7 +2122,7 @@ configLocked++;
timerSensorCheck = millis();// + INTERVAL_CHECK_SENSOR;
}
configLocked--;
inputLoopBusy= false;
inputLoopBusy--;
}

View File

@@ -298,7 +298,7 @@ case S_SET:
//break;
case S_CMD:
item->setCmd(cmd.getCmd());
//item->setCmd(cmd.getCmd());
switch (cmd.getCmd())
{
case CMD_ON:

View File

@@ -210,7 +210,7 @@ case S_SET:
//break;
case S_CMD:
item->setCmd(cmd.getCmd());
//item->setCmd(cmd.getCmd());
switch (cmd.getCmd())
{
case CMD_ON:

View File

@@ -200,8 +200,8 @@ case S_CMD:
{
case CMD_ON:
case CMD_OFF:
item->setCmd(cmd.getCmd());
item->SendStatus(SEND_COMMAND);
//item->setCmd(cmd.getCmd());
//item->SendStatus(SEND_COMMAND);
return 1;
default:
debugSerial<<F("Unknown cmd ")<<cmd.getCmd()<<endl;

View File

@@ -40,6 +40,13 @@ unsigned long owTimer = 0;
owChangedType owChanged;
bool zero(const uint8_t *addr, uint8_t len)
{
while (len--)
if (addr[len]) return false;
return true;
}
int owUpdate() {
#ifndef OWIRE_DISABLE
unsigned long finish = millis();// + OW_UPDATE_INTERVAL;
@@ -50,7 +57,7 @@ int owUpdate() {
return false;
}
*/
Serial.println(F("Searching"));
//Serial.println(F("Searching"));
if (oneWire) oneWire->reset_search();
for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent
@@ -67,7 +74,8 @@ int owUpdate() {
debugSerial.println(F(" alive"));
break;
}; //alive
if (ifind < 0 && sensors) {
if (ifind < 0 && sensors && !zero(term[t_count],8))
{
wstat[t_count] = SW_FIND; //Newly detected
debugSerial<<F("dev#")<<t_count<<F(" Addr:");
PrintBytes(term[t_count], 8,0);
@@ -219,13 +227,17 @@ int owFind(DeviceAddress addr) {
void owAdd(DeviceAddress addr) {
#ifndef OWIRE_DISABLE
infoSerial<<F("dev#")<<t_count<<F(" Addr:");
PrintBytes(term[t_count], 8,0);
infoSerial<<endl;
if (t_count>=t_max) return;
if (zero(term[t_count],8)) return;
wstat[t_count] = SW_FIND; //Newly detected
memcpy(term[t_count], addr, 8);
debugSerial<<F("dev#")<<t_count<<F(" Addr:");
PrintBytes(term[t_count], 8,0);
debugSerial.println();
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
if (term[t_count][0] == 0x28)
oneWire->setStrongPullup();

View File

@@ -53,11 +53,11 @@ extern aJsonObject *topics;
void PrintBytes(uint8_t *addr, uint8_t count, bool newline) {
for (uint8_t i = 0; i < count; i++) {
Serial.print(addr[i] >> 4, HEX);
Serial.print(addr[i] & 0x0f, HEX);
infoSerial<< _HEX(addr[i] >> 4);
infoSerial<< _HEX(addr[i] & 0x0f);
}
if (newline)
Serial.println();
infoSerial<<endl;
}
const char HEXSTR[] = "0123456789ABCDEF";