contact input: two-way long click

INCREASE and DECREASE (%) commands for volume, hue, sat
This commit is contained in:
2020-01-08 03:00:38 +03:00
parent 951d0d4383
commit 0044b741ac
6 changed files with 129 additions and 23 deletions

View File

@@ -452,7 +452,7 @@ void Input::dht22Poll() {
} }
#endif #endif
bool Input::executeCommand(aJsonObject* cmd, char* defCmd) bool Input::executeCommand(aJsonObject* cmd, int8_t toggle, char* defCmd)
{ {
if (!cmd) return false; if (!cmd) return false;
@@ -465,7 +465,7 @@ bool Input::executeCommand(aJsonObject* cmd, char* defCmd)
aJsonObject * command = cmd->child; aJsonObject * command = cmd->child;
while (command) while (command)
{ {
executeCommand(command,defCmd); executeCommand(command,toggle,defCmd);
command = command->next; command = command->next;
} }
} }
@@ -474,15 +474,19 @@ bool Input::executeCommand(aJsonObject* cmd, char* defCmd)
{ {
aJsonObject *item = aJson.getObjectItem(cmd, "item"); aJsonObject *item = aJson.getObjectItem(cmd, "item");
aJsonObject *icmd = aJson.getObjectItem(cmd, "icmd"); aJsonObject *icmd = aJson.getObjectItem(cmd, "icmd");
aJsonObject *irev = aJson.getObjectItem(cmd, "irev");
aJsonObject *ecmd = aJson.getObjectItem(cmd, "ecmd"); aJsonObject *ecmd = aJson.getObjectItem(cmd, "ecmd");
aJsonObject *erev = aJson.getObjectItem(cmd, "erev");
aJsonObject *emit = aJson.getObjectItem(cmd, "emit"); aJsonObject *emit = aJson.getObjectItem(cmd, "emit");
char * itemCommand; char * itemCommand;
if(icmd) itemCommand = icmd->valuestring; if (irev && toggle) itemCommand = irev->valuestring;
else if(icmd) itemCommand = icmd->valuestring;
else itemCommand = defCmd; else itemCommand = defCmd;
char * emitCommand; char * emitCommand;
if(ecmd) emitCommand = ecmd->valuestring; if (erev && toggle) itemCommand = erev->valuestring;
else if(ecmd) emitCommand = ecmd->valuestring;
else emitCommand = defCmd; else emitCommand = defCmd;
debugSerial << F("IN:") << (pin) << F(" : ") <<endl; debugSerial << F("IN:") << (pin) << F(" : ") <<endl;
@@ -546,6 +550,7 @@ else if (store->delayedState)
return false; //State changing is postponed already (( giving up return false; //State changing is postponed already (( giving up
aJsonObject *cmd = NULL; aJsonObject *cmd = NULL;
int8_t toggle=0;
switch (newState) switch (newState)
{ {
@@ -554,12 +559,15 @@ aJsonObject *cmd = NULL;
{ {
case IS_RELEASED: //click case IS_RELEASED: //click
cmd = aJson.getObjectItem(inputObj, "click"); cmd = aJson.getObjectItem(inputObj, "click");
toggle=store->toggle1;
break; break;
case IS_RELEASED2: //doubleclick case IS_RELEASED2: //doubleclick
cmd = aJson.getObjectItem(inputObj, "dclick"); cmd = aJson.getObjectItem(inputObj, "dclick");
toggle=store->toggle2;
break; break;
case IS_PRESSED3: //tripple click case IS_PRESSED3: //tripple click
cmd = aJson.getObjectItem(inputObj, "tclick"); cmd = aJson.getObjectItem(inputObj, "tclick");
toggle=store->toggle3;
break; break;
case IS_WAITPRESS: //do nothing case IS_WAITPRESS: //do nothing
break; break;
@@ -570,37 +578,50 @@ aJsonObject *cmd = NULL;
break; break;
case IS_PRESSED: //scmd case IS_PRESSED: //scmd
cmd = aJson.getObjectItem(inputObj, "scmd"); cmd = aJson.getObjectItem(inputObj, "scmd");
toggle=store->toggle1;
store->toggle1 = !store->toggle1;
break; break;
case IS_PRESSED2: //scmd2 case IS_PRESSED2: //scmd2
cmd = aJson.getObjectItem(inputObj, "scmd2"); cmd = aJson.getObjectItem(inputObj, "scmd2");
toggle=store->toggle2;
store->toggle2 = !store->toggle2;
break; break;
case IS_PRESSED3: //scmd3 case IS_PRESSED3: //scmd3
cmd = aJson.getObjectItem(inputObj, "scmd3"); cmd = aJson.getObjectItem(inputObj, "scmd3");
toggle=store->toggle3;
store->toggle3 = !store->toggle3;
break; break;
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(inputObj, "rcmd");
// toggle=state->toggle1;
break; break;
case IS_LONG: //lcmd case IS_LONG: //lcmd
cmd = aJson.getObjectItem(inputObj, "lcmd"); cmd = aJson.getObjectItem(inputObj, "lcmd");
toggle=store->toggle1;
break; break;
case IS_REPEAT: //rpcmd case IS_REPEAT: //rpcmd
cmd = aJson.getObjectItem(inputObj, "rpcmd"); cmd = aJson.getObjectItem(inputObj, "rpcmd");
toggle=store->toggle1;
break; break;
case IS_LONG2: //lcmd2 case IS_LONG2: //lcmd2
cmd = aJson.getObjectItem(inputObj, "lcmd2"); cmd = aJson.getObjectItem(inputObj, "lcmd2");
toggle=store->toggle2;
break; break;
case IS_REPEAT2: //rpcmd2 case IS_REPEAT2: //rpcmd2
cmd = aJson.getObjectItem(inputObj, "rpcmd2"); cmd = aJson.getObjectItem(inputObj, "rpcmd2");
toggle=store->toggle2;
break; break;
case IS_LONG3: //lcmd3 case IS_LONG3: //lcmd3
cmd = aJson.getObjectItem(inputObj, "lcmd3"); cmd = aJson.getObjectItem(inputObj, "lcmd3");
toggle=store->toggle3;
break; break;
case IS_REPEAT3: //rpcmd3 case IS_REPEAT3: //rpcmd3
cmd = aJson.getObjectItem(inputObj, "rpcmd3"); cmd = aJson.getObjectItem(inputObj, "rpcmd3");
toggle=store->toggle3;
break; break;
} }
@@ -611,9 +632,9 @@ aJsonObject *cmd = NULL;
} }
if (cause != CHECK_INTERRUPT) if (cause != CHECK_INTERRUPT)
{ {
executeCommand(cmd);
//Executed
store->state=newState; store->state=newState;
executeCommand(cmd,toggle);
//Executed
store->delayedState=false; store->delayedState=false;
return true; return true;
} }
@@ -721,9 +742,9 @@ switch (store->state) //Timer based transitions
if (inType & IN_PUSH_TOGGLE) { //To refactore if (inType & IN_PUSH_TOGGLE) { //To refactore
if (currentInputState) { //react on leading edge only (change from 0 to 1) if (currentInputState) { //react on leading edge only (change from 0 to 1)
store->logicState = !store->logicState; //store->logicState = !store->logicState;
store->lastValue = currentInputState; store->lastValue = currentInputState;
onContactChanged(store->logicState); onContactChanged(store->toggle1);
} }
} else } else
@@ -774,7 +795,7 @@ switch (store->state) //Timer based transitions
break; break;
} }
if (res) { //State changed or postponed if (res) { //State changed or postponed
store->logicState = currentInputState; // store->logicState = currentInputState;
store->lastValue = currentInputState; store->lastValue = currentInputState;
} }
} }

View File

@@ -56,10 +56,10 @@ e-mail anklimov@gmail.com
#define ANALOG_STATE_ATTEMPTS 6 #define ANALOG_STATE_ATTEMPTS 6
#define ANALOG_NOIZE 1 #define ANALOG_NOIZE 1
#define CHECK_INPUT 1 #define CHECK_SENSOR 1
#define CHECK_SENSOR 2 #define CHECK_INPUT 2
#define CHECK_INTERRUPT 3 #define CHECK_INTERRUPT 3
#define CHECK_DELAYED 4
#define T_LONG 1000 #define T_LONG 1000
#define T_IDLE 600 #define T_IDLE 600
@@ -107,16 +107,17 @@ typedef union {
// Analog input structure // Analog input structure
struct { struct {
uint8_t reserved; uint8_t reserved;
uint8_t reserved2; uint8_t logicState;
int16_t currentValue; int16_t currentValue;
}; };
// Digital input structure // Digital input structure
struct { struct {
uint8_t reserved3:1; uint8_t toggle1:1;
uint8_t toggle2:1;
uint8_t toggle3:1;
uint8_t lastValue:1; uint8_t lastValue:1;
uint8_t logicState:1;
uint8_t delayedState:1; uint8_t delayedState:1;
uint8_t bounce:4; uint8_t bounce:3;
uint8_t state:4; uint8_t state:4;
uint8_t reqState:4; uint8_t reqState:4;
uint16_t timestamp16; uint16_t timestamp16;
@@ -179,5 +180,5 @@ protected:
char* getIdxField(); char* getIdxField();
bool changeState(uint8_t newState, short cause); bool changeState(uint8_t newState, short cause);
bool executeCommand(aJsonObject* cmd, char* defCmd = NULL); bool executeCommand(aJsonObject* cmd, int8_t toggle = -1, char* defCmd = NULL);
}; };

View File

@@ -57,6 +57,7 @@ int txt2cmd(char *payload) {
// Check for command // Check for command
if (*payload == '-' || (*payload >= '0' && *payload <= '9')) cmd = CMD_NUM; if (*payload == '-' || (*payload >= '0' && *payload <= '9')) cmd = CMD_NUM;
else if (*payload == '%') cmd = CMD_UP;
else if (strcmp_P(payload, ON_P) == 0) cmd = CMD_ON; else if (strcmp_P(payload, ON_P) == 0) cmd = CMD_ON;
else if (strcmp_P(payload, OFF_P) == 0) cmd = CMD_OFF; else if (strcmp_P(payload, OFF_P) == 0) cmd = CMD_OFF;
else if (strcmp_P(payload, REST_P) == 0) cmd = CMD_RESTORE; else if (strcmp_P(payload, REST_P) == 0) cmd = CMD_RESTORE;
@@ -96,6 +97,8 @@ int txt2subItem(char *payload) {
else if (strcmp_P(payload, HSV_P) == 0) cmd = S_HSV; else if (strcmp_P(payload, HSV_P) == 0) cmd = S_HSV;
else if (strcmp_P(payload, RGB_P) == 0) cmd = S_RGB; else if (strcmp_P(payload, RGB_P) == 0) cmd = S_RGB;
else if (strcmp_P(payload, FAN_P) == 0) cmd = S_FAN; else if (strcmp_P(payload, FAN_P) == 0) cmd = S_FAN;
else if (strcmp_P(payload, HUE_P) == 0) cmd = S_HUE;
else if (strcmp_P(payload, SAT_P) == 0) cmd = S_SAT;
/* UnUsed now /* UnUsed now
else if (strcmp_P(payload, SETPOINT_P) == 0) cmd = S_SETPOINT; else if (strcmp_P(payload, SETPOINT_P) == 0) cmd = S_SETPOINT;
else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP; else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP;
@@ -423,9 +426,13 @@ debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
//if (isSet) //if (isSet)
//{ //{
switch (cmd) { switch (cmd) {
case CMD_UP:
case CMD_DN:
setCommand=cmd;
case CMD_HSV: case CMD_HSV:
suffixCode=S_HSV; //override code for known payload // suffixCode=S_HSV; //override code for known payload
case CMD_NUM: case CMD_NUM:
{ {
short i = 0; short i = 0;
int Par[3]; int Par[3];
@@ -542,6 +549,71 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
} }
break; break;
case CMD_DN:
case CMD_UP:
if (itemType == CH_GROUP) break;
if (!n || !Par[0]) Par[0] = DEFAULT_INC_STEP;
if (cmd == CMD_DN) Par[0]=-Par[0];
st.aslong = getVal();
debugSerial<<"from: h="<<st.h<<" s="<<st.s <<" v="<<st.v<<endl;
switch (suffixCode)
{
case S_NOTFOUND:
case S_SET:
Par[0] += st.v;
if (Par[0]>100) Par[0]=100;
if (Par[0]<0) Par[0]=0;
n=1;
cmd=CMD_NUM;
debugSerial<<" to v="<<Par[0]<<endl;
break;
}
int cType=getChanType();
if ( cType == CH_RGB || cType == CH_RGBW)
{
bool modified = false;
switch (suffixCode)
{
case S_HSV:
Par[0] += st.h;
Par[1] += st.s;
Par[2] += st.v;
modified = true;
break;
case S_HUE:
Par[0] += st.h;
Par[1] = st.s;
Par[2] = st.v;
modified = true;
break;
case S_SAT:
Par[1] = st.s + Par[0];
Par[0] = st.h;
Par[2] = st.v;
modified = true;
break;
}
if (modified)
{
if (Par[0]>365 ) Par[0]=0;
if (Par[0]<0) Par[0]=365;
if (Par[1]>100) Par[1]=100;
if (Par[1]<0) Par[1]=0;
if (Par[2]>100) Par[2]=100;
if (Par[2]<0) Par[2]=0;
n=3;
cmd=CMD_NUM;
suffixCode=S_SET;
debugSerial<<"to: h="<<Par[0]<<" s="<<Par[1] <<" v="<<Par[2]<<endl;
}
}
} }
@@ -554,7 +626,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
if (!chActive>0) //if channel was'nt active before CMD_XON if (!chActive>0) //if channel was'nt active before CMD_XON
{ {
debugSerial<<F("Turning XON\n"); debugSerial<<F("Turning XON\n");
res = driver->Ctrl(CMD_ON, n, Parameters, send, suffixCode, subItem); res = driver->Ctrl(CMD_ON, n, Par, send, suffixCode, subItem);
setCmd(CMD_XON); setCmd(CMD_XON);
} }
else else
@@ -566,7 +638,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
case CMD_HALT: case CMD_HALT:
if (chActive>0) //if channel was active before CMD_HALT if (chActive>0) //if channel was active before CMD_HALT
{ {
res = driver->Ctrl(CMD_OFF, n, Parameters, send, suffixCode, subItem); res = driver->Ctrl(CMD_OFF, n, Par, send, suffixCode, subItem);
setCmd(CMD_HALT); setCmd(CMD_HALT);
return res; return res;
} }
@@ -579,7 +651,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
case CMD_OFF: case CMD_OFF:
if (getCmd() != CMD_HALT) //Halted, ignore OFF if (getCmd() != CMD_HALT) //Halted, ignore OFF
{ {
res = driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem); res = driver->Ctrl(cmd, n, Par, send, suffixCode, subItem);
setCmd(CMD_OFF); setCmd(CMD_OFF);
} }
else else
@@ -594,7 +666,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
break; break;
*/ */
default: default:
res = driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem); res = driver->Ctrl(cmd, n, Par, send, suffixCode, subItem);
if (cmd) setCmd(cmd); if (cmd) setCmd(cmd);
} }
return res; return res;
@@ -1759,6 +1831,10 @@ int Item::SendStatus(int sendFlags) {
} }
} }
int Item::getChanType()
{
if (driver) return driver->getChanType();
return itemType;
}
///////////////////////////////////////// /////////////////////////////////////////

View File

@@ -33,6 +33,8 @@ e-mail anklimov@gmail.com
#define S_RGB 4 #define S_RGB 4
#define S_FAN 5 #define S_FAN 5
#define S_MODE 6 #define S_MODE 6
#define S_HUE 7
#define S_SAT 8
#define S_ADDITIONAL 64 #define S_ADDITIONAL 64
/* /*
@@ -190,6 +192,7 @@ class Item
int Poll(short cause); int Poll(short cause);
int SendStatus(int sendFlags); int SendStatus(int sendFlags);
int isActive(); int isActive();
int getChanType();
protected: protected:
//short cmd2changeActivity(int lastActivity, short defaultCmd = CMD_SET); //short cmd2changeActivity(int lastActivity, short defaultCmd = CMD_SET);
int VacomSetFan (int8_t val, int8_t cmd=0); int VacomSetFan (int8_t val, int8_t cmd=0);

View File

@@ -134,6 +134,8 @@
#define LAN_INIT_DELAY 500 #define LAN_INIT_DELAY 500
#endif #endif
#define DEFAULT_INC_STEP 5
#if defined(ARDUINO_ARCH_AVR) #if defined(ARDUINO_ARCH_AVR)
//All options available //All options available
#ifdef CONTROLLINO #ifdef CONTROLLINO

View File

@@ -67,6 +67,8 @@ const char SET_P[] PROGMEM = "set";
const char CMD_P[] PROGMEM = "cmd"; const char CMD_P[] PROGMEM = "cmd";
const char MODE_P[] PROGMEM = "mode"; const char MODE_P[] PROGMEM = "mode";
const char FAN_P[] PROGMEM = "fan"; const char FAN_P[] PROGMEM = "fan";
const char HUE_P[] PROGMEM = "hue";
const char SAT_P[] PROGMEM = "sat";
/* /*
const char TEMP_P[] PROGMEM = "temp"; const char TEMP_P[] PROGMEM = "temp";
const char SETPOINT_P[] PROGMEM = "setpoint"; const char SETPOINT_P[] PROGMEM = "setpoint";
@@ -76,6 +78,7 @@ const char HEAT_P[] PROGMEM = "heat";
*/ */
const char HSV_P[] PROGMEM = "HSV"; const char HSV_P[] PROGMEM = "HSV";
const char RGB_P[] PROGMEM = "RGB"; const char RGB_P[] PROGMEM = "RGB";
/* /*
const char RPM_P[] PROGMEM = "rpm"; const char RPM_P[] PROGMEM = "rpm";
const char STATE_P[] PROGMEM = "state"; const char STATE_P[] PROGMEM = "state";