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

View File

@@ -56,10 +56,10 @@ e-mail anklimov@gmail.com
#define ANALOG_STATE_ATTEMPTS 6
#define ANALOG_NOIZE 1
#define CHECK_INPUT 1
#define CHECK_SENSOR 2
#define CHECK_SENSOR 1
#define CHECK_INPUT 2
#define CHECK_INTERRUPT 3
#define CHECK_DELAYED 4
#define T_LONG 1000
#define T_IDLE 600
@@ -107,16 +107,17 @@ typedef union {
// Analog input structure
struct {
uint8_t reserved;
uint8_t reserved2;
uint8_t logicState;
int16_t currentValue;
};
// Digital input structure
struct {
uint8_t reserved3:1;
uint8_t toggle1:1;
uint8_t toggle2:1;
uint8_t toggle3:1;
uint8_t lastValue:1;
uint8_t logicState:1;
uint8_t delayedState:1;
uint8_t bounce:4;
uint8_t bounce:3;
uint8_t state:4;
uint8_t reqState:4;
uint16_t timestamp16;
@@ -179,5 +180,5 @@ protected:
char* getIdxField();
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
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, OFF_P) == 0) cmd = CMD_OFF;
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, RGB_P) == 0) cmd = S_RGB;
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
else if (strcmp_P(payload, SETPOINT_P) == 0) cmd = S_SETPOINT;
else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP;
@@ -423,9 +426,13 @@ debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
//if (isSet)
//{
switch (cmd) {
case CMD_UP:
case CMD_DN:
setCommand=cmd;
case CMD_HSV:
suffixCode=S_HSV; //override code for known payload
// suffixCode=S_HSV; //override code for known payload
case CMD_NUM:
{
short i = 0;
int Par[3];
@@ -542,6 +549,71 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
}
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
{
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);
}
else
@@ -566,7 +638,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
case 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);
return res;
}
@@ -579,7 +651,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
case CMD_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);
}
else
@@ -594,7 +666,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
break;
*/
default:
res = driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem);
res = driver->Ctrl(cmd, n, Par, send, suffixCode, subItem);
if (cmd) setCmd(cmd);
}
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_FAN 5
#define S_MODE 6
#define S_HUE 7
#define S_SAT 8
#define S_ADDITIONAL 64
/*
@@ -190,6 +192,7 @@ class Item
int Poll(short cause);
int SendStatus(int sendFlags);
int isActive();
int getChanType();
protected:
//short cmd2changeActivity(int lastActivity, short defaultCmd = CMD_SET);
int VacomSetFan (int8_t val, int8_t cmd=0);

View File

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

View File

@@ -67,6 +67,8 @@ const char SET_P[] PROGMEM = "set";
const char CMD_P[] PROGMEM = "cmd";
const char MODE_P[] PROGMEM = "mode";
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 SETPOINT_P[] PROGMEM = "setpoint";
@@ -76,6 +78,7 @@ const char HEAT_P[] PROGMEM = "heat";
*/
const char HSV_P[] PROGMEM = "HSV";
const char RGB_P[] PROGMEM = "RGB";
/*
const char RPM_P[] PROGMEM = "rpm";
const char STATE_P[] PROGMEM = "state";