modbus retry issue, core fixes (cold restore issues)

This commit is contained in:
2019-08-29 16:35:56 +03:00
parent 549bd6527c
commit 4b1be34561
2 changed files with 90 additions and 78 deletions

View File

@@ -409,6 +409,7 @@ debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
//} //}
} }
/*
short Item::cmd2changeActivity(int lastActivity, short defaultCmd) short Item::cmd2changeActivity(int lastActivity, short defaultCmd)
{ {
if (isActive()) if (isActive())
@@ -417,24 +418,27 @@ short Item::cmd2changeActivity(int lastActivity, short defaultCmd)
else if (lastActivity) return CMD_OFF; else if (lastActivity) return CMD_OFF;
else return defaultCmd; else return defaultCmd;
} }
*/
int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode, char *subItem) { int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode, char *subItem) {
debugSerial<<F("RAM=")<<freeRam()<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItem<<F(" Suff=")<<suffixCode<<F(" Cmd=")<<cmd<<F(" Par= "); debugSerial<<F("RAM=")<<freeRam()<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItem<<F(" Suff=")<<suffixCode<<F(" Cmd=")<<cmd<<F(" Par=(");
if (!itemArr) return -1; if (!itemArr) return -1;
int Par[MAXCTRLPAR] = {0, 0, 0}; int Par[MAXCTRLPAR] = {0, 0, 0};
if (Parameters) if (Parameters)
for (short i=0;i<n && i<MAXCTRLPAR;i++){ for (short i=0;i<n && i<MAXCTRLPAR;i++){
Par[i] = Parameters[i]; Par[i] = Parameters[i];
debugSerial<<F("<")<<Par[i]<<F("> "); debugSerial<<F("<")<<Par[i]<<F(">");
} }
debugSerial<<endl; debugSerial<<F(")")<<endl;
/*
if (itemType == CH_GROUP && !send) if (itemType == CH_GROUP && !send)
{ {
debugSerial<<F("Skip Grp")<<endl; debugSerial<<F("Skip Grp")<<endl;
return -1; return -1;
} }
*/
int iaddr = getArg(); int iaddr = getArg();
int chActive =isActive(); int chActive =isActive();
@@ -475,56 +479,32 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
if (driver) return driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem); if (driver) return driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem);
// Legacy code // Legacy code
bool instantON = false; bool toExecute = (chActive>0); //if channel is already active - unconditionally propogate changes
switch (cmd) { switch (cmd) {
case 0: // old style SET - with turning ON case 0: // old style SET - with turning ON
instantON = true; toExecute = true;
case CMD_SET: // new style SET - w/o turning ON case CMD_SET: // new style SET - w/o turning ON
if (itemType !=CH_THERMO) setCmd(CMD_SET); //prevent ON thermostat by semp set ???? //if (/*itemType !=CH_THERMO && */send) setCmd(CMD_SET); //prevent ON thermostat by semp set ????
switch (itemType) { switch (itemType) {
case CH_RGBW: //only if configured VAL array case CH_RGBW: //only if configured VAL array
if (!Par[1] && (n == 3)) itemType = CH_WHITE; if (!Par[1] && (n == 3)) itemType = CH_WHITE;
case CH_RGB: case CH_RGB:
/*
if (n == 3) { // Full triplet passed
st.h = Par[0];
st.s = Par[1];
st.v = Par[2];
setVal(st.aslong);
} else
{ //Uncomplete triplet passed
st.aslong = getVal(); // restore CSV triplet
switch (n) {
case 1:
st.v = Par[0]; // Just volume passed // override volume
break;
case 2:
st.h = Par[0];
st.s = Par[1];
}
setVal(st.aslong); // Save back
Par[0] = st.h;
Par[1] = st.s;
Par[2] = st.v;
n = 3;
}
setCmd(cmd2changeActivity(chActive,cmd));
if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); // Send back triplet ?
break; */
case CH_GROUP: //Save for groups as well case CH_GROUP: //Save for groups as well
st.aslong = getVal(); st.aslong = getVal();
switch (n) switch (n)
{ {
case 1: case 1:
st.v = Par[0]; //Volume only st.v = Par[0]; //Volume only
if (st.hsv_flag)
{
Par[0] = st.h; Par[0] = st.h;
Par[1] = st.s; Par[1] = st.s;
Par[2] = st.v; Par[2] = st.v;
n = 3; n = 3;}
break; break;
case 2: // Just hue and saturation case 2: // Just hue and saturation
st.h = Par[0]; st.h = Par[0];
@@ -540,28 +520,36 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
st.hsv_flag = 1; st.hsv_flag = 1;
} }
setVal(st.aslong); setVal(st.aslong);
if (chActive && !st.v) setCmd(CMD_OFF); if (toExecute)
if (!chActive && st.v) setCmd(CMD_ON); { //
if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED);//// Send back volume for grp? if (chActive && !st.v) setCmd(CMD_OFF);
if (!chActive && st.v) setCmd(CMD_ON);
SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED);
}
else SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
break; break;
case CH_PWM: case CH_PWM:
case CH_VC: case CH_VC:
case CH_DIMMER: case CH_DIMMER:
case CH_MODBUS: case CH_MODBUS:
case CH_VCTEMP:
setVal(Par[0]); // Store value setVal(Par[0]); // Store value
setCmd(cmd2changeActivity(chActive,cmd)); // setCmd(cmd2changeActivity(chActive,cmd));
if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); // Send back parameter for channel above this line if (toExecute)
{ // Not restoring, working
if (chActive && !Par[0]) setCmd(CMD_OFF);
if (!chActive && Par[0]) setCmd(CMD_ON);
SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); // Send back parameter for channel above this line
}
else SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
break; break;
case CH_VCTEMP: // moved
case CH_THERMO: ///? wasnt send before/ now will /// case CH_THERMO: ///? wasnt send before/ now will ///
setVal(Par[0]); // Store value setVal(Par[0]); // Store value
if (send) SendStatus(SEND_PARAMETERS | SEND_DEFFERED); // Send back parameter for channel above this line if (send) SendStatus(SEND_PARAMETERS | SEND_DEFFERED); // Send back parameter for channel above this line
}//itemtype }//itemtype
if (getCmd() == CMD_SET && itemType !=CH_GROUP && !chActive>0) return 1; // Parameters are stored, no further action required if (! toExecute && itemType !=CH_GROUP) return 1; // Parameters are stored, no further action required
break; break;
case CMD_XON: case CMD_XON:
@@ -595,11 +583,14 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS ); if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS );
break; break;
} // if forcewhite } // if forcewhite
setCmd(cmd);
if (chActive>0) {SendStatus(SEND_COMMAND);return 1;} if (chActive>0 && send)
{
SendStatus(SEND_COMMAND);
return 1;
}
{ {
short params = 0; short params = 0;
setCmd(cmd);
//retrive stored values //retrive stored values
st.aslong = getVal(); st.aslong = getVal();
@@ -628,7 +619,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
Par[1] = st.s; Par[1] = st.s;
Par[2] = st.v; Par[2] = st.v;
params = 3; params = 3;
SendStatus(SEND_COMMAND | SEND_PARAMETERS); // Send restored triplet. In any cases if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS); // ???Send restored triplet. In any cases
break; break;
case CH_VCTEMP: case CH_VCTEMP:
@@ -638,7 +629,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
case CH_VC: case CH_VC:
Par[0] = st.aslong; Par[0] = st.aslong;
params = 1; params = 1;
SendStatus(SEND_COMMAND | SEND_PARAMETERS); // Send restored parameter, even if send=false - no problem, loop will be supressed at next hop if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS); // ???Send restored parameter, even if send=false - no problem, loop will be supressed at next hop
break; break;
case CH_THERMO: case CH_THERMO:
Par[0] = st.aslong; Par[0] = st.aslong;
@@ -656,7 +647,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
Par[0] = 20; //20 degrees celsium - safe temperature Par[0] = 20; //20 degrees celsium - safe temperature
params = 1; params = 1;
setVal(20); setVal(20);
SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS); //??? // deffered ???
break; break;
case CH_RGBW: case CH_RGBW:
case CH_RGB: case CH_RGB:
@@ -669,19 +660,19 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
st.s = Par[1]; st.s = Par[1];
st.v = Par[2]; st.v = Par[2];
setVal(st.aslong); setVal(st.aslong);
SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS ); // deffered ???
break; break;
case CH_RELAY: case CH_RELAY:
Par[0] = 100; Par[0] = 100;
params = 1; params = 1;
setVal(100); setVal(100);
if (send) SendStatus(SEND_COMMAND | SEND_DEFFERED); if (send) SendStatus(SEND_COMMAND); // deffered ???
break; break;
default: default:
Par[0] = 100; Par[0] = 100;
params = 1; params = 1;
setVal(100); setVal(100);
SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS); //??? // deffered ???
} }
} // default handler } // default handler
for (short i = 0; i < params; i++) { for (short i = 0; i < params; i++) {
@@ -790,24 +781,12 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
#endif #endif
#ifdef _modbus #ifdef _modbus
case CH_MODBUS: { case CH_MODBUS:
short numpar=0; modbusDimmerSet(Par[0]);
if ((itemArg->type == aJson_Array) && ((numpar = aJson.getArraySize(itemArg)) >= 2)) { break;
int _addr = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_ADDR)->valueint;
int _reg = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG)->valueint;
int _mask = -1;
if (numpar >= (MODBUS_CMD_ARG_MASK+1)) _mask = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_MASK)->valueint;
int _maxval = 0x3f;
if (numpar >= (MODBUS_CMD_ARG_MAX_SCALE+1)) _maxval = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_MAX_SCALE)->valueint;
int _regType = MODBUS_HOLDING_REG_TYPE;
if (numpar >= (MODBUS_CMD_ARG_REG_TYPE+1)) _regType = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG_TYPE)->valueint;
if (_maxval) modbusDimmerSet(_addr, _reg, _regType, _mask, map(Par[0], 0, 100, 0, _maxval));
else modbusDimmerSet(_addr, _reg, _regType, _mask, Par[0]);
}
break;
}
#endif #endif
case CH_GROUP://Group case CH_GROUP://Group
{ {
if (itemArg->type == aJson_Array) { if (itemArg->type == aJson_Array) {
@@ -894,7 +873,7 @@ int Item::isActive() {
int val = 0; int val = 0;
if (!isValid()) return -1; if (!isValid()) return -1;
//debugSerial<<itemArr->name); debugSerial<<itemArr->name;
int cmd = getCmd(); int cmd = getCmd();
@@ -908,12 +887,12 @@ int Item::isActive() {
case CMD_AUTO: case CMD_AUTO:
case CMD_HEAT: case CMD_HEAT:
case CMD_COOL: case CMD_COOL:
//debugSerial<<" active"); debugSerial<<F(" active\n");
return 1; return 1;
case CMD_OFF: case CMD_OFF:
case CMD_HALT: case CMD_HALT:
case -1: ///// No last command case -1: ///// No last command
//debugSerial<<" inactive"); debugSerial<<F(" inactive\n");
return 0; return 0;
} }
@@ -924,17 +903,18 @@ int Item::isActive() {
switch (itemType) { switch (itemType) {
case CH_GROUP: //make recursive calculation - is it some active in group case CH_GROUP: //make recursive calculation - is it some active in group
if (itemArg->type == aJson_Array) { if (itemArg->type == aJson_Array) {
debugSerial<<F("Grp check:\n"); debugSerial<<F(" Grp:");
aJsonObject *i = itemArg->child; aJsonObject *i = itemArg->child;
while (i) { while (i) {
Item it(i->valuestring); Item it(i->valuestring);
if (it.isValid() && it.isActive()) { if (it.isValid() && it.isActive()) {
debugSerial<<F("Active\n"); debugSerial<<F(" active\n");
return 1; return 1;
} }
i = i->next; i = i->next;
} //while } //while
debugSerial<<F(" inactive\n");
return 0; return 0;
} //if } //if
break; break;
@@ -954,9 +934,13 @@ int Item::isActive() {
case CH_VCTEMP: case CH_VCTEMP:
case CH_PWM: case CH_PWM:
val = st.aslong; val = st.aslong;
break;
default:
debugSerial<<F(" unknown\n");
return 0;
} //switch } //switch
//debugSerial<<F(":=")); debugSerial<<F(" value is ");
//debugSerial<<val); debugSerial<<val<<endl;
if (val) return 1; else return 0; if (val) return 1; else return 0;
} }
@@ -1026,6 +1010,32 @@ POLL 2101x10
[22:27:29] => poll: 0A 03 08 34 00 0A 87 18 [22:27:29] => poll: 0A 03 08 34 00 0A 87 18
*/ */
#ifdef _modbus
int Item::modbusDimmerSet(uint16_t value)
{
switch (getCmd())
{
case CMD_OFF:
case CMD_HALT:
value=0;
break;
}
short numpar=0;
if ((itemArg->type == aJson_Array) && ((numpar = aJson.getArraySize(itemArg)) >= 2)) {
int _addr = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_ADDR)->valueint;
int _reg = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG)->valueint;
int _mask = -1;
if (numpar >= (MODBUS_CMD_ARG_MASK+1)) _mask = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_MASK)->valueint;
int _maxval = 0x3f;
if (numpar >= (MODBUS_CMD_ARG_MAX_SCALE+1)) _maxval = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_MAX_SCALE)->valueint;
int _regType = MODBUS_HOLDING_REG_TYPE;
if (numpar >= (MODBUS_CMD_ARG_REG_TYPE+1)) _regType = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG_TYPE)->valueint;
if (_maxval) modbusDimmerSet(_addr, _reg, _regType, _mask, map(value, 0, 100, 0, _maxval));
else modbusDimmerSet(_addr, _reg, _regType, _mask, value);
}
}
#endif
void Item::mb_fail() { void Item::mb_fail() {
debugSerial<<F("Modbus op failed\n"); debugSerial<<F("Modbus op failed\n");
@@ -1244,7 +1254,8 @@ boolean Item::checkModbusRetry() {
int val = getVal(); int val = getVal();
debugSerial<<F("Retrying CMD\n"); debugSerial<<F("Retrying CMD\n");
clearFlag(SEND_RETRY); // Clean retry flag clearFlag(SEND_RETRY); // Clean retry flag
Ctrl(cmd,1,&val); // Execute command again //Ctrl(cmd,1,&val); // Execute command again
modbusDimmerSet(val);
return true; return true;
} }
return false; return false;

View File

@@ -173,6 +173,7 @@ class Item
int VacomSetFan (int8_t val, int8_t cmd=0); int VacomSetFan (int8_t val, int8_t cmd=0);
int VacomSetHeat(int addr, int8_t val, int8_t cmd=0); int VacomSetHeat(int addr, int8_t val, int8_t cmd=0);
int modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint16_t value); int modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint16_t value);
int modbusDimmerSet(uint16_t value);
void mb_fail(); void mb_fail();
int isActive(); int isActive();
void Parse(); void Parse();