Rotary Encoder - chaning config section

input - regress fix
MBUS - logginng fix
This commit is contained in:
2025-04-19 23:25:39 +03:00
parent 2b5b780586
commit c9714ef982
4 changed files with 131 additions and 61 deletions

View File

@@ -145,7 +145,7 @@ void Input::Parse(aJsonObject * configObj)
} //switch } //switch
else pin = static_cast<uint8_t>(atoi(configObj->name)); else pin = static_cast<uint8_t>(atoi(configObj->name));
store = (inStore *) &configObj->valueint; store = (inStore *) &inputObj->valueint;
} }
/* /*
// Persistant storage // Persistant storage
@@ -601,10 +601,68 @@ debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") <<
setNextPollTime(millis()); setNextPollTime(millis());
} }
#endif #endif
// To Be Refactored - move to Execute after class Input inheritation on abstract chan
bool Input::checkInstructions(aJsonObject * obj)
{
aJsonObject *gotoObj = aJson.getObjectItem(obj, "goto");
if (gotoObj)
switch (gotoObj->type)
{
case aJson_Int:
debugSerial<<F("Activate in ")<< gotoObj->valueint <<endl;
return setCurrentInput(gotoObj->valueint);
break;
case aJson_String:
debugSerial<<F("Activate in ")<< gotoObj->valuestring <<endl;
return setCurrentInput(gotoObj->valuestring);
}
return false;
}
aJsonObject * Input::getCurrentInput()
{
if (!inputObj) return NULL;
aJsonObject *act = aJson.getObjectItem(inputObj, "act");
if (act && (act->type == aJson_Array || act->type == aJson_Object) && act->valuestring) return (aJsonObject * ) act->valuestring;
return inputObj;
}
bool Input::setCurrentInput(int n)
{
if (!inputObj) return false;
aJsonObject * curInput = NULL;
aJsonObject *act = aJson.getObjectItem(inputObj, "act");
if (act && act->type == aJson_Array)
{
if (n)
curInput = aJson.getArrayItem(act,n-1);
else curInput = inputObj;
act->valuestring = (char *) curInput;
return true;
}
return false;
}
bool Input::setCurrentInput(char * name)
{
if (!inputObj) return false;
aJsonObject * curInput = NULL;
aJsonObject *act = aJson.getObjectItem(inputObj, "act");
if (act && act->type == aJson_Object)
{
if (name && *name)
curInput = aJson.getObjectItem(act,name);
else curInput = inputObj;
act->valuestring = (char *) curInput;
return true;
}
return false;
}
// TODO Polling via timed interrupt with CHECK_INTERRUPT cause // TODO Polling via timed interrupt with CHECK_INTERRUPT cause
bool Input:: bool Input::
changeState(uint8_t newState, short cause) changeState(uint8_t newState, short cause, aJsonObject * currentInputObject)
{ {
if (!inputObj || !store) return false; if (!inputObj || !store) return false;
@@ -635,37 +693,37 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
switch (store->state) switch (store->state)
{ {
case IS_RELEASED: //click case IS_RELEASED: //click
cmd = aJson.getObjectItem(inputObj, "click"); cmd = aJson.getObjectItem(currentInputObject, "click");
toggle=store->toggle1; toggle=store->toggle1;
break; break;
case IS_RELEASED2: //doubleclick case IS_RELEASED2: //doubleclick
cmd = aJson.getObjectItem(inputObj, "dclick"); cmd = aJson.getObjectItem(currentInputObject, "dclick");
toggle=store->toggle2; toggle=store->toggle2;
break; break;
case IS_PRESSED3: //tripple click case IS_PRESSED3: //tripple click
cmd = aJson.getObjectItem(inputObj, "tclick"); cmd = aJson.getObjectItem(currentInputObject, "tclick");
toggle=store->toggle3; toggle=store->toggle3;
break; break;
case IS_WAITPRESS: //do nothing case IS_WAITPRESS: //do nothing
break; break;
default: //rcmd default: //rcmd
cmd = aJson.getObjectItem(inputObj, "rcmd"); cmd = aJson.getObjectItem(currentInputObject, "rcmd");
; ;
} }
break; break;
case IS_PRESSED: //scmd case IS_PRESSED: //scmd
cmd = aJson.getObjectItem(inputObj, "scmd"); cmd = aJson.getObjectItem(currentInputObject, "scmd");
toggle=store->toggle1; toggle=store->toggle1;
store->toggle1 = !store->toggle1; store->toggle1 = !store->toggle1;
if (!cmd) defCmd.Cmd(CMD_ON); if (!cmd) defCmd.Cmd(CMD_ON);
break; break;
case IS_PRESSED2: //scmd2 case IS_PRESSED2: //scmd2
cmd = aJson.getObjectItem(inputObj, "scmd2"); cmd = aJson.getObjectItem(currentInputObject, "scmd2");
toggle=store->toggle2; toggle=store->toggle2;
store->toggle2 = !store->toggle2; store->toggle2 = !store->toggle2;
break; break;
case IS_PRESSED3: //scmd3 case IS_PRESSED3: //scmd3
cmd = aJson.getObjectItem(inputObj, "scmd3"); cmd = aJson.getObjectItem(currentInputObject, "scmd3");
toggle=store->toggle3; toggle=store->toggle3;
store->toggle3 = !store->toggle3; store->toggle3 = !store->toggle3;
break; break;
@@ -673,41 +731,41 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
case IS_RELEASED: //rcmd case IS_RELEASED: //rcmd
case IS_WAITPRESS: case IS_WAITPRESS:
case IS_RELEASED2: case IS_RELEASED2:
cmd = aJson.getObjectItem(inputObj, "rcmd"); cmd = aJson.getObjectItem(currentInputObject, "rcmd");
if (!cmd) defCmd.Cmd(CMD_OFF); if (!cmd) defCmd.Cmd(CMD_OFF);
// toggle=state->toggle1; // toggle=state->toggle1;
break; break;
case IS_LONG: //lcmd case IS_LONG: //lcmd
cmd = aJson.getObjectItem(inputObj, "lcmd"); cmd = aJson.getObjectItem(currentInputObject, "lcmd");
toggle=store->toggle1; toggle=store->toggle1;
break; break;
case IS_REPEAT: //rpcmd case IS_REPEAT: //rpcmd
cmd = aJson.getObjectItem(inputObj, "rpcmd"); cmd = aJson.getObjectItem(currentInputObject, "rpcmd");
toggle=store->toggle1; toggle=store->toggle1;
break; break;
case IS_LONG2: //lcmd2 case IS_LONG2: //lcmd2
cmd = aJson.getObjectItem(inputObj, "lcmd2"); cmd = aJson.getObjectItem(currentInputObject, "lcmd2");
toggle=store->toggle2; toggle=store->toggle2;
break; break;
case IS_REPEAT2: //rpcmd2 case IS_REPEAT2: //rpcmd2
cmd = aJson.getObjectItem(inputObj, "rpcmd2"); cmd = aJson.getObjectItem(currentInputObject, "rpcmd2");
toggle=store->toggle2; toggle=store->toggle2;
break; break;
case IS_LONG3: //lcmd3 case IS_LONG3: //lcmd3
cmd = aJson.getObjectItem(inputObj, "lcmd3"); cmd = aJson.getObjectItem(currentInputObject, "lcmd3");
toggle=store->toggle3; toggle=store->toggle3;
break; break;
case IS_REPEAT3: //rpcmd3 case IS_REPEAT3: //rpcmd3
cmd = aJson.getObjectItem(inputObj, "rpcmd3"); cmd = aJson.getObjectItem(currentInputObject, "rpcmd3");
toggle=store->toggle3; toggle=store->toggle3;
break; break;
} }
aJsonObject *defaultItem = aJson.getObjectItem(inputObj, "item"); aJsonObject *defaultItem = aJson.getObjectItem(currentInputObject, "item");
aJsonObject *defaultEmit = aJson.getObjectItem(inputObj, "emit"); aJsonObject *defaultEmit = aJson.getObjectItem(currentInputObject, "emit");
aJsonObject *defaultCan = aJson.getObjectItem(inputObj, "can"); aJsonObject *defaultCan = aJson.getObjectItem(currentInputObject, "can");
if (!defaultEmit && !defaultItem) defCmd.Cmd(CMD_VOID); if (!defaultEmit && !defaultItem) defCmd.Cmd(CMD_VOID);
@@ -723,6 +781,7 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
{ {
store->state=newState; store->state=newState;
store->delayedState=false; store->delayedState=false;
checkInstructions(cmd);
executeCommand(cmd,toggle,defCmd,defaultItem,defaultEmit,defaultCan); executeCommand(cmd,toggle,defCmd,defaultItem,defaultEmit,defaultCan);
return true; return true;
} }
@@ -748,8 +807,8 @@ void Input::contactPoll(short cause, RotaryEncoder * re) {
if ((inType == IN_ULTRASONIC) && (cause!=CHECK_ULTRASONIC)) return; if ((inType == IN_ULTRASONIC) && (cause!=CHECK_ULTRASONIC)) return;
contactPollBusy++; contactPollBusy++;
aJsonObject * currentInputObject = getCurrentInput();
changeState(IS_REQSTATE,cause); //Check for postponed states transitions changeState(IS_REQSTATE,cause,currentInputObject); //Check for postponed states transitions
uint8_t inputOnLevel; uint8_t inputOnLevel;
@@ -779,15 +838,15 @@ switch (store->state) //Timer based transitions
case IS_PRESSED: case IS_PRESSED:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF))
{ {
if (!aJson.getObjectItem(inputObj, "lcmd") && !aJson.getObjectItem(inputObj, "rpcmd")) changeState(IS_WAITRELEASE, cause); if (!aJson.getObjectItem(inputObj, "lcmd") && !aJson.getObjectItem(currentInputObject, "rpcmd")) changeState(IS_WAITRELEASE, cause,currentInputObject);
else changeState(IS_LONG, cause); else changeState(IS_LONG, cause,currentInputObject);
} }
break; break;
case IS_LONG: case IS_LONG:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF))
{ {
changeState(IS_REPEAT, cause); changeState(IS_REPEAT, cause,currentInputObject);
store->timestamp16 = millis() & 0xFFFF; store->timestamp16 = millis() & 0xFFFF;
} }
break; break;
@@ -795,7 +854,7 @@ switch (store->state) //Timer based transitions
case IS_REPEAT: case IS_REPEAT:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF))
{ {
changeState(IS_REPEAT, cause); changeState(IS_REPEAT, cause,currentInputObject);
store->timestamp16 = millis() & 0xFFFF; store->timestamp16 = millis() & 0xFFFF;
} }
break; break;
@@ -803,15 +862,15 @@ switch (store->state) //Timer based transitions
case IS_PRESSED2: case IS_PRESSED2:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF))
{ {
if (!aJson.getObjectItem(inputObj, "lcmd2") && !aJson.getObjectItem(inputObj, "rpcmd2")) changeState(IS_WAITRELEASE, cause); if (!aJson.getObjectItem(currentInputObject, "lcmd2") && !aJson.getObjectItem(currentInputObject, "rpcmd2")) changeState(IS_WAITRELEASE, cause,currentInputObject);
else changeState(IS_LONG2, cause); else changeState(IS_LONG2, cause,currentInputObject);
} }
break; break;
case IS_LONG2: case IS_LONG2:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF))
{ {
changeState(IS_REPEAT2, cause); changeState(IS_REPEAT2, cause,currentInputObject);
store->timestamp16 = millis() & 0xFFFF; store->timestamp16 = millis() & 0xFFFF;
} }
break; break;
@@ -819,7 +878,7 @@ switch (store->state) //Timer based transitions
case IS_REPEAT2: case IS_REPEAT2:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF))
{ {
changeState(IS_REPEAT2, cause); changeState(IS_REPEAT2, cause,currentInputObject);
store->timestamp16 = millis() & 0xFFFF; store->timestamp16 = millis() & 0xFFFF;
} }
break; break;
@@ -827,19 +886,19 @@ switch (store->state) //Timer based transitions
case IS_PRESSED3: case IS_PRESSED3:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF))
{ {
if (!aJson.getObjectItem(inputObj, "lcmd3") && !aJson.getObjectItem(inputObj, "rpcmd3")) //No longpress handlers if (!aJson.getObjectItem(currentInputObject, "lcmd3") && !aJson.getObjectItem(currentInputObject, "rpcmd3")) //No longpress handlers
{ {
if (aJson.getObjectItem(inputObj, "scmd3")) changeState(IS_WAITRELEASE, cause); //was used if (aJson.getObjectItem(currentInputObject, "scmd3")) changeState(IS_WAITRELEASE, cause,currentInputObject); //was used
else changeState(IS_PRESSED2, cause); // completely empty trippleClick section - fallback to first click handler else changeState(IS_PRESSED2, cause,currentInputObject); // completely empty trippleClick section - fallback to first click handler
} }
else changeState(IS_LONG3, cause); else changeState(IS_LONG3, cause,currentInputObject);
} }
break; break;
case IS_LONG3: case IS_LONG3:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF))
{ {
changeState(IS_REPEAT3, cause); changeState(IS_REPEAT3, cause,currentInputObject);
store->timestamp16 = millis() & 0xFFFF; store->timestamp16 = millis() & 0xFFFF;
} }
break; break;
@@ -847,7 +906,7 @@ switch (store->state) //Timer based transitions
case IS_REPEAT3: case IS_REPEAT3:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF)) if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF))
{ {
changeState(IS_REPEAT3, cause); changeState(IS_REPEAT3, cause,currentInputObject);
store->timestamp16 = millis() & 0xFFFF; store->timestamp16 = millis() & 0xFFFF;
} }
break; break;
@@ -857,7 +916,7 @@ switch (store->state) //Timer based transitions
case IS_WAITPRESS: case IS_WAITPRESS:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_IDLE,0xFFFF)) changeState(IS_IDLE, cause); if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_IDLE,0xFFFF)) changeState(IS_IDLE, cause,currentInputObject);
break; break;
} //switch } //switch
@@ -867,12 +926,12 @@ if (re)
switch (re->getDirection()) switch (re->getDirection())
{ {
case RotaryEncoder::Direction::CLOCKWISE: case RotaryEncoder::Direction::CLOCKWISE:
if (bufferItem=aJson.getObjectItem(inputObj, "+-")) executeCommand(bufferItem,0); if (bufferItem=aJson.getObjectItem(currentInputObject, "+-")) {checkInstructions(bufferItem);executeCommand(bufferItem,0);};
if (bufferItem=aJson.getObjectItem(inputObj, "+")) executeCommand(bufferItem); if (bufferItem=aJson.getObjectItem(currentInputObject, "+")) {checkInstructions(bufferItem);executeCommand(bufferItem,0);};
break; break;
case RotaryEncoder::Direction::COUNTERCLOCKWISE: case RotaryEncoder::Direction::COUNTERCLOCKWISE:
if (bufferItem=aJson.getObjectItem(inputObj, "+-")) executeCommand(bufferItem,1); if (bufferItem=aJson.getObjectItem(currentInputObject, "+-")) {checkInstructions(bufferItem);executeCommand(bufferItem,1);};
if (bufferItem=aJson.getObjectItem(inputObj, "-")) executeCommand(bufferItem); if (bufferItem=aJson.getObjectItem(currentInputObject, "-")) {checkInstructions(bufferItem);executeCommand(bufferItem,0);};
} }
} }
@@ -903,27 +962,27 @@ if (re)
switch (store->state) switch (store->state)
{ {
case IS_IDLE: case IS_IDLE:
res = changeState(IS_PRESSED, cause); res = changeState(IS_PRESSED, cause,currentInputObject);
break; break;
case IS_RELEASED: case IS_RELEASED:
case IS_WAITPRESS: case IS_WAITPRESS:
if ( //No future if ( //No future
!aJson.getObjectItem(inputObj, "scmd2") && !aJson.getObjectItem(currentInputObject, "scmd2") &&
!aJson.getObjectItem(inputObj, "lcmd2") && !aJson.getObjectItem(currentInputObject, "lcmd2") &&
!aJson.getObjectItem(inputObj, "rpcmd2") && !aJson.getObjectItem(currentInputObject, "rpcmd2") &&
!aJson.getObjectItem(inputObj, "dclick") !aJson.getObjectItem(currentInputObject, "dclick")
) )
res = changeState(IS_PRESSED, cause); res = changeState(IS_PRESSED, cause,currentInputObject);
else res = changeState(IS_PRESSED2, cause); else res = changeState(IS_PRESSED2, cause,currentInputObject);
break; break;
case IS_RELEASED2: case IS_RELEASED2:
res = changeState(IS_PRESSED3, cause); res = changeState(IS_PRESSED3, cause,currentInputObject);
break; break;
} }
else else
@@ -931,24 +990,24 @@ if (re)
{ {
case IS_PRESSED: case IS_PRESSED:
res = changeState(IS_RELEASED, cause); res = changeState(IS_RELEASED, cause,currentInputObject);
break; break;
case IS_LONG: case IS_LONG:
case IS_REPEAT: case IS_REPEAT:
case IS_WAITRELEASE: case IS_WAITRELEASE:
res = changeState(IS_WAITPRESS, cause); res = changeState(IS_WAITPRESS, cause,currentInputObject);
break; break;
case IS_PRESSED2: case IS_PRESSED2:
if ( //No future if ( //No future
!aJson.getObjectItem(inputObj, "scmd2") && !aJson.getObjectItem(currentInputObject, "scmd2") &&
!aJson.getObjectItem(inputObj, "lcmd2") && !aJson.getObjectItem(currentInputObject, "lcmd2") &&
!aJson.getObjectItem(inputObj, "rpcmd2") && !aJson.getObjectItem(currentInputObject, "rpcmd2") &&
!aJson.getObjectItem(inputObj, "dclick") !aJson.getObjectItem(currentInputObject, "dclick")
) res = changeState(IS_IDLE, cause); ) res = changeState(IS_IDLE, cause,currentInputObject);
else res = changeState(IS_RELEASED2, cause); else res = changeState(IS_RELEASED2, cause,currentInputObject);
break; break;
case IS_LONG2: case IS_LONG2:
@@ -956,7 +1015,7 @@ if (re)
case IS_LONG3: case IS_LONG3:
case IS_REPEAT3: case IS_REPEAT3:
case IS_PRESSED3: case IS_PRESSED3:
res = changeState(IS_IDLE, cause); res = changeState(IS_IDLE, cause,currentInputObject);
break; break;
} }
if (res) { //State changed or postponed if (res) { //State changed or postponed
@@ -1130,6 +1189,7 @@ void Input::onAnalogChanged(itemCmd newValue) {
// New tyle unified activities // New tyle unified activities
aJsonObject *act = aJson.getObjectItem(inputObj, "act"); aJsonObject *act = aJson.getObjectItem(inputObj, "act");
//checkInstructions(act);
executeCommand(act,-1,newValue); executeCommand(act,-1,newValue);
// Legacy // Legacy

View File

@@ -1,4 +1,4 @@
/* Copyright © 2017-2018 Andrey Klimov. All rights reserved. /* Copyright © 2017-2025 Andrey Klimov. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -184,8 +184,14 @@ protected:
bool publishDataToDomoticz(int , aJsonObject *, const char *format, ...); bool publishDataToDomoticz(int , aJsonObject *, const char *format, ...);
char* getIdxField(); char* getIdxField();
bool changeState(uint8_t newState, short cause); bool changeState(uint8_t newState, short cause, aJsonObject * currentInputObject);
void setupRotaryEncoder(); void setupRotaryEncoder();
aJsonObject * getCurrentInput();
bool setCurrentInput(int n);
bool setCurrentInput(char * name);
bool checkInstructions(aJsonObject * obj);
//bool executeCommand(aJsonObject* cmd, int8_t toggle = -1, char* defCmd = NULL); //bool executeCommand(aJsonObject* cmd, int8_t toggle = -1, char* defCmd = NULL);
}; };

View File

@@ -856,7 +856,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
do do
{ {
savedValue = outValue->valueint; savedValue = outValue->valueint;
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<"/"<<execObj->name<<"="<<outValue<<endl; debugSerial<<"MBUS: SEND "<<item->itemArr->name<<"/"<<execObj->name<<"="<<outValue->valueint<<endl;
sendRes = sendModbus(execObj->name,outValue); sendRes = sendModbus(execObj->name,outValue);
needResend = (savedValue != outValue->valueint); needResend = (savedValue != outValue->valueint);
while(needResend && mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),200)) modbusIdle(); while(needResend && mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),200)) modbusIdle();

View File

@@ -671,6 +671,10 @@ aJsonObject *icmd = NULL;
aJsonObject *ecmd = NULL; aJsonObject *ecmd = NULL;
char cmdType = 0; char cmdType = 0;
//char * out = aJson.print(cmd);
//debugSerial<<"Exec:"<<out<<endl;
//free (out);
if (cmd) cmdType = cmd->type; if (cmd) cmdType = cmd->type;
switch (cmdType) switch (cmdType)
@@ -743,7 +747,7 @@ switch (cmdType)
else if (_itemCmd.isValue()) suffix = S_SET; else if (_itemCmd.isValue()) suffix = S_SET;
} }
} }
//debugSerial<<"EC:"<<emitCommand<<endl;
//debugSerial << F("IN:") << (pin) << F(" : ") <<endl; //debugSerial << F("IN:") << (pin) << F(" : ") <<endl;
if (item) { if (item) {
if (itemCommand) if (itemCommand)