mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 19:59:50 +03:00
single, double, tripple click, longpress, repeat logic for contact inputs are added
This commit is contained in:
@@ -113,7 +113,7 @@ void Input::Parse()
|
|||||||
void Input::setup()
|
void Input::setup()
|
||||||
{
|
{
|
||||||
if (!isValid() || (!root)) return;
|
if (!isValid() || (!root)) return;
|
||||||
|
/*
|
||||||
#ifndef CSSHDC_DISABLE
|
#ifndef CSSHDC_DISABLE
|
||||||
if (inType == IN_CCS811)
|
if (inType == IN_CCS811)
|
||||||
{
|
{
|
||||||
@@ -127,6 +127,51 @@ if (!isValid() || (!root)) return;
|
|||||||
}
|
}
|
||||||
// TODO rest types setup
|
// TODO rest types setup
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
store->aslong=0;
|
||||||
|
uint8_t inputPinMode = INPUT; //if IN_ACTIVE_HIGH
|
||||||
|
switch (inType)
|
||||||
|
{
|
||||||
|
case IN_PUSH_ON:
|
||||||
|
case IN_PUSH_TOGGLE :
|
||||||
|
inputPinMode = INPUT_PULLUP;
|
||||||
|
|
||||||
|
case IN_PUSH_ON | IN_ACTIVE_HIGH:
|
||||||
|
case IN_PUSH_TOGGLE | IN_ACTIVE_HIGH:
|
||||||
|
pinMode(pin, inputPinMode);
|
||||||
|
|
||||||
|
store->state=IS_IDLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IN_ANALOG:
|
||||||
|
inputPinMode = INPUT_PULLUP;
|
||||||
|
|
||||||
|
case IN_ANALOG | IN_ACTIVE_HIGH:
|
||||||
|
pinMode(pin, inputPinMode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IN_DHT22:
|
||||||
|
case IN_COUNTER:
|
||||||
|
case IN_UPTIME:
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef CSSHDC_DISABLE
|
||||||
|
case IN_CCS811:
|
||||||
|
{
|
||||||
|
in_ccs811 ccs811(this);
|
||||||
|
ccs811.Setup();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IN_HDC1080:
|
||||||
|
{
|
||||||
|
in_hdc1080 hdc1080(this);
|
||||||
|
hdc1080.Setup();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} //switch
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,17 +185,18 @@ if (!isValid()) return -1;
|
|||||||
|
|
||||||
switch (cause) {
|
switch (cause) {
|
||||||
case CHECK_INPUT: //Fast polling
|
case CHECK_INPUT: //Fast polling
|
||||||
|
case CHECK_INTERRUPT: //Realtime polling
|
||||||
switch (inType)
|
switch (inType)
|
||||||
{
|
{
|
||||||
case IN_PUSH_ON:
|
case IN_PUSH_ON:
|
||||||
case IN_PUSH_ON | IN_ACTIVE_HIGH:
|
case IN_PUSH_ON | IN_ACTIVE_HIGH:
|
||||||
case IN_PUSH_TOGGLE :
|
case IN_PUSH_TOGGLE :
|
||||||
case IN_PUSH_TOGGLE | IN_ACTIVE_HIGH:
|
case IN_PUSH_TOGGLE | IN_ACTIVE_HIGH:
|
||||||
contactPoll();
|
contactPoll(cause);
|
||||||
break;
|
break;
|
||||||
case IN_ANALOG:
|
case IN_ANALOG:
|
||||||
case IN_ANALOG | IN_ACTIVE_HIGH:
|
case IN_ANALOG | IN_ACTIVE_HIGH:
|
||||||
analogPoll();
|
analogPoll(cause);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// No fast polling
|
// No fast polling
|
||||||
@@ -406,43 +452,331 @@ void Input::dht22Poll() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Input::contactPoll() {
|
bool Input::executeCommand(aJsonObject* cmd, char* defCmd)
|
||||||
boolean currentInputState;
|
{
|
||||||
|
if (!cmd) return false;
|
||||||
|
|
||||||
|
switch (cmd->type)
|
||||||
|
{
|
||||||
|
case aJson_String: //legacy - no action
|
||||||
|
break;
|
||||||
|
case aJson_Array: //array - recursive iterate
|
||||||
|
{
|
||||||
|
aJsonObject * command = cmd->child;
|
||||||
|
while (command)
|
||||||
|
{
|
||||||
|
executeCommand(command,defCmd);
|
||||||
|
command = command->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case aJson_Object:
|
||||||
|
{
|
||||||
|
aJsonObject *item = aJson.getObjectItem(cmd, "item");
|
||||||
|
aJsonObject *icmd = aJson.getObjectItem(cmd, "icmd");
|
||||||
|
aJsonObject *ecmd = aJson.getObjectItem(cmd, "ecmd");
|
||||||
|
aJsonObject *emit = aJson.getObjectItem(cmd, "emit");
|
||||||
|
|
||||||
|
char * itemCommand;
|
||||||
|
if(icmd) itemCommand = icmd->valuestring;
|
||||||
|
else itemCommand = defCmd;
|
||||||
|
|
||||||
|
char * emitCommand;
|
||||||
|
if(ecmd) emitCommand = ecmd->valuestring;
|
||||||
|
else emitCommand = defCmd;
|
||||||
|
|
||||||
|
debugSerial << F("IN:") << (pin) << F(" : ") <<endl;
|
||||||
|
if (item) debugSerial << item->valuestring<< F(" -> ")<<itemCommand<<endl;
|
||||||
|
if (emit) debugSerial << emit->valuestring<< F(" -> ")<<emitCommand<<endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (emit && emitCommand) {
|
||||||
/*
|
/*
|
||||||
#if defined(ARDUINO_ARCH_STM32)
|
TODO implement
|
||||||
WiringPinMode inputPinMode;
|
#ifdef WITH_DOMOTICZ
|
||||||
#endif
|
if (getIdxField())
|
||||||
|
{ (newValue) ? publishDataToDomoticz(0, emit, "{\"command\":\"switchlight\",\"idx\":%s,\"switchcmd\":\"On\"}",
|
||||||
#if defined(__SAM3X8E__)||defined(ARDUINO_ARCH_AVR)||defined(ARDUINO_ARCH_ESP8266)||defined(ARDUINO_ARCH_ESP32)
|
: publishDataToDomoticz(0,emit,"{\"command\":\"switchlight\",\"idx\":%s,\"switchcmd\":\"Off\"}",getIdxField()); getIdxField())
|
||||||
|
: publishDataToDomoticz(0, emit,
|
||||||
|
"{\"command\":\"switchlight\",\"idx\":%s,\"switchcmd\":\"Off\"}",
|
||||||
|
getIdxField());
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
uint32_t inputPinMode;
|
|
||||||
uint8_t inputOnLevel;
|
{
|
||||||
if (inType & IN_ACTIVE_HIGH) {
|
char addrstr[MQTT_TOPIC_LENGTH];
|
||||||
inputOnLevel = HIGH;
|
strncpy(addrstr,emit->valuestring,sizeof(addrstr));
|
||||||
inputPinMode = INPUT;
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
} else {
|
{
|
||||||
inputOnLevel = LOW;
|
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
|
||||||
inputPinMode = INPUT_PULLUP;
|
mqttClient.publish(addrstr, emitCommand , true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // emit
|
||||||
|
if (item && itemCommand) {
|
||||||
|
//debugSerial <<F("Controlled item:")<< item->valuestring <<endl;
|
||||||
|
Item it(item->valuestring);
|
||||||
|
if (it.isValid()) it.Ctrl(itemCommand, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
} //switch type
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Polling via timed interrupt with CHECK_INTERRUPT cause
|
||||||
|
bool Input::changeState(uint8_t newState, short cause)
|
||||||
|
{
|
||||||
|
if (!inputObj || !store) return false;
|
||||||
|
|
||||||
|
if (newState == IS_REQSTATE)
|
||||||
|
if (store->delayedState && cause != CHECK_INTERRUPT)
|
||||||
|
{
|
||||||
|
// Requested delayed change State and safe moment
|
||||||
|
newState=store->reqState; //Retrieve requested state
|
||||||
|
debugSerial<<F("Pended state retrieved:")<<newState;
|
||||||
|
|
||||||
}
|
}
|
||||||
pinMode(pin, inputPinMode);
|
else return true; // No pended State
|
||||||
|
else if (store->delayedState)
|
||||||
|
return false; //State changing is postponed already (( giving up
|
||||||
|
|
||||||
|
aJsonObject *cmd = NULL;
|
||||||
|
|
||||||
|
switch (newState)
|
||||||
|
{
|
||||||
|
case IS_IDLE:
|
||||||
|
switch (store->state)
|
||||||
|
{
|
||||||
|
case IS_RELEASED: //click
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "click");
|
||||||
|
break;
|
||||||
|
case IS_RELEASED2: //doubleclick
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "dclick");
|
||||||
|
break;
|
||||||
|
case IS_PRESSED3: //tripple click
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "tclick");
|
||||||
|
break;
|
||||||
|
case IS_WAITPRESS: //do nothing
|
||||||
|
break;
|
||||||
|
default: //rcmd
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "rcmd");
|
||||||
|
;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IS_PRESSED: //scmd
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "scmd");
|
||||||
|
break;
|
||||||
|
case IS_PRESSED2: //scmd2
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "scmd2");
|
||||||
|
break;
|
||||||
|
case IS_PRESSED3: //scmd3
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "scmd3");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_RELEASED: //rcmd
|
||||||
|
case IS_WAITPRESS:
|
||||||
|
case IS_RELEASED2:
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "rcmd");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case IS_LONG: //lcmd
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "lcmd");
|
||||||
|
break;
|
||||||
|
case IS_REPEAT: //rpcmd
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "rpcmd");
|
||||||
|
break;
|
||||||
|
case IS_LONG2: //lcmd2
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "lcmd2");
|
||||||
|
break;
|
||||||
|
case IS_REPEAT2: //rpcmd2
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "rpcmd2");
|
||||||
|
break;
|
||||||
|
case IS_LONG3: //lcmd3
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "lcmd3");
|
||||||
|
break;
|
||||||
|
case IS_REPEAT3: //rpcmd3
|
||||||
|
cmd = aJson.getObjectItem(inputObj, "rpcmd3");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!cmd)
|
||||||
|
{
|
||||||
|
store->state=newState;
|
||||||
|
return true; //nothing to do
|
||||||
|
}
|
||||||
|
if (cause != CHECK_INTERRUPT)
|
||||||
|
{
|
||||||
|
executeCommand(cmd);
|
||||||
|
//Executed
|
||||||
|
store->state=newState;
|
||||||
|
store->delayedState=false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Postpone actual execution
|
||||||
|
store->reqState=store->state;
|
||||||
|
store->delayedState=true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::contactPoll(short cause) {
|
||||||
|
boolean currentInputState;
|
||||||
|
if (!store) return;
|
||||||
|
|
||||||
|
changeState(IS_REQSTATE,cause); //Check for postponed states transitions
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t inputOnLevel;
|
||||||
|
if (inType & IN_ACTIVE_HIGH) inputOnLevel = HIGH;
|
||||||
|
else inputOnLevel = LOW;
|
||||||
|
|
||||||
|
|
||||||
currentInputState = (digitalRead(pin) == inputOnLevel);
|
currentInputState = (digitalRead(pin) == inputOnLevel);
|
||||||
if (currentInputState != store->currentValue) // value changed
|
|
||||||
|
switch (store->state) //Timer based transitions
|
||||||
|
{
|
||||||
|
case IS_PRESSED:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF)) changeState(IS_LONG, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_LONG:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF))
|
||||||
|
{
|
||||||
|
changeState(IS_REPEAT, cause);
|
||||||
|
store->timestamp16 = millis() & 0xFFFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_REPEAT:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF))
|
||||||
|
{
|
||||||
|
changeState(IS_REPEAT, cause);
|
||||||
|
store->timestamp16 = millis() & 0xFFFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_PRESSED2:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF)) changeState(IS_LONG2, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_LONG2:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF))
|
||||||
|
{
|
||||||
|
changeState(IS_REPEAT2, cause);
|
||||||
|
store->timestamp16 = millis() & 0xFFFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_REPEAT2:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF))
|
||||||
|
{
|
||||||
|
changeState(IS_REPEAT2, cause);
|
||||||
|
store->timestamp16 = millis() & 0xFFFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_PRESSED3:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF)) changeState(IS_LONG3, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_LONG3:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT,0xFFFF))
|
||||||
|
{
|
||||||
|
changeState(IS_REPEAT3, cause);
|
||||||
|
store->timestamp16 = millis() & 0xFFFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_REPEAT3:
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_RPT_PULSE,0xFFFF))
|
||||||
|
{
|
||||||
|
changeState(IS_REPEAT3, cause);
|
||||||
|
store->timestamp16 = millis() & 0xFFFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_RELEASED:
|
||||||
|
case IS_RELEASED2:
|
||||||
|
case IS_WAITPRESS:
|
||||||
|
|
||||||
|
|
||||||
|
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_IDLE,0xFFFF)) changeState(IS_IDLE, cause);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentInputState != store->lastValue) // value changed
|
||||||
{
|
{
|
||||||
if (store->bounce) store->bounce = store->bounce - 1;
|
if (store->bounce) store->bounce = store->bounce - 1;
|
||||||
else //confirmed change
|
else //confirmed change
|
||||||
{
|
{
|
||||||
if (inType & IN_PUSH_TOGGLE) {
|
store->timestamp16 = millis() & 0xFFFF; //Saving timestamp of changing
|
||||||
|
|
||||||
|
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->currentValue = currentInputState;
|
store->lastValue = currentInputState;
|
||||||
onContactChanged(store->logicState);
|
onContactChanged(store->logicState);
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
store->logicState = currentInputState;
|
|
||||||
store->currentValue = currentInputState;
|
{
|
||||||
onContactChanged(currentInputState);
|
onContactChanged(currentInputState); //Legacy input - to remove later
|
||||||
|
|
||||||
|
bool res = true;
|
||||||
|
if (currentInputState) //Button pressed state transitions
|
||||||
|
|
||||||
|
switch (store->state)
|
||||||
|
{
|
||||||
|
case IS_IDLE:
|
||||||
|
res = changeState(IS_PRESSED, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_RELEASED:
|
||||||
|
case IS_WAITPRESS:
|
||||||
|
res = changeState(IS_PRESSED2, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_RELEASED2:
|
||||||
|
|
||||||
|
res = changeState(IS_PRESSED3, cause);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (store->state) //Button released state transitions
|
||||||
|
{
|
||||||
|
case IS_PRESSED:
|
||||||
|
res = changeState(IS_RELEASED, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_LONG:
|
||||||
|
case IS_REPEAT:
|
||||||
|
res = changeState(IS_WAITPRESS, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_PRESSED2:
|
||||||
|
res = changeState(IS_RELEASED2, cause);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IS_LONG2:
|
||||||
|
case IS_REPEAT2:
|
||||||
|
case IS_LONG3:
|
||||||
|
case IS_REPEAT3:
|
||||||
|
case IS_PRESSED3:
|
||||||
|
res = changeState(IS_IDLE, cause);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (res) { //State changed or postponed
|
||||||
|
store->logicState = currentInputState;
|
||||||
|
store->lastValue = currentInputState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// store->currentValue = currentInputState;
|
// store->currentValue = currentInputState;
|
||||||
}
|
}
|
||||||
@@ -451,23 +785,26 @@ void Input::contactPoll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Input::analogPoll() {
|
|
||||||
|
void Input::analogPoll(short cause) {
|
||||||
int16_t inputVal;
|
int16_t inputVal;
|
||||||
int32_t mappedInputVal; // 10x inputVal
|
int32_t mappedInputVal; // 10x inputVal
|
||||||
aJsonObject *inputMap = aJson.getObjectItem(inputObj, "map");
|
aJsonObject *inputMap = aJson.getObjectItem(inputObj, "map");
|
||||||
int16_t Noize = ANALOG_NOIZE;
|
int16_t Noize = ANALOG_NOIZE;
|
||||||
short simple = 0;
|
short simple = 0;
|
||||||
uint32_t inputPinMode;
|
// uint32_t inputPinMode;
|
||||||
int max=1024*10;
|
int max=1024*10;
|
||||||
int min=0;
|
int min=0;
|
||||||
|
|
||||||
|
/*
|
||||||
if (inType & IN_ACTIVE_HIGH) {
|
if (inType & IN_ACTIVE_HIGH) {
|
||||||
inputPinMode = INPUT;
|
inputPinMode = INPUT;
|
||||||
} else {
|
} else {
|
||||||
inputPinMode = INPUT_PULLUP;
|
inputPinMode = INPUT_PULLUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
pinMode(pin, inputPinMode);
|
pinMode(pin, inputPinMode);
|
||||||
|
*/
|
||||||
inputVal = analogRead(pin);
|
inputVal = analogRead(pin);
|
||||||
// Mapping
|
// Mapping
|
||||||
if (inputMap && inputMap->type == aJson_Array)
|
if (inputMap && inputMap->type == aJson_Array)
|
||||||
@@ -522,11 +859,13 @@ void Input::analogPoll() {
|
|||||||
|
|
||||||
|
|
||||||
void Input::onContactChanged(int newValue) {
|
void Input::onContactChanged(int newValue) {
|
||||||
debugSerial << F("IN:") << (pin) << F("=") << newValue << endl;
|
|
||||||
aJsonObject *item = aJson.getObjectItem(inputObj, "item");
|
aJsonObject *item = aJson.getObjectItem(inputObj, "item");
|
||||||
|
aJsonObject *emit = aJson.getObjectItem(inputObj, "emit");
|
||||||
|
if (!item && !emit) return;
|
||||||
aJsonObject *scmd = aJson.getObjectItem(inputObj, "scmd");
|
aJsonObject *scmd = aJson.getObjectItem(inputObj, "scmd");
|
||||||
aJsonObject *rcmd = aJson.getObjectItem(inputObj, "rcmd");
|
aJsonObject *rcmd = aJson.getObjectItem(inputObj, "rcmd");
|
||||||
aJsonObject *emit = aJson.getObjectItem(inputObj, "emit");
|
debugSerial << F("LEGACY IN:") << (pin) << F("=") << newValue << endl;
|
||||||
if (emit) {
|
if (emit) {
|
||||||
#ifdef WITH_DOMOTICZ
|
#ifdef WITH_DOMOTICZ
|
||||||
if (getIdxField())
|
if (getIdxField())
|
||||||
|
|||||||
@@ -35,6 +35,22 @@ e-mail anklimov@gmail.com
|
|||||||
#define IN_COUNTER 8
|
#define IN_COUNTER 8
|
||||||
#define IN_UPTIME 16
|
#define IN_UPTIME 16
|
||||||
|
|
||||||
|
#define IS_IDLE 0
|
||||||
|
#define IS_PRESSED 1
|
||||||
|
#define IS_RELEASED 2
|
||||||
|
#define IS_LONG 3
|
||||||
|
#define IS_REPEAT 4
|
||||||
|
#define IS_WAITPRESS 5
|
||||||
|
#define IS_PRESSED2 6
|
||||||
|
#define IS_RELEASED2 7
|
||||||
|
#define IS_LONG2 8u
|
||||||
|
#define IS_REPEAT2 9u
|
||||||
|
#define IS_PRESSED3 10u
|
||||||
|
#define IS_LONG3 11u
|
||||||
|
#define IS_REPEAT3 12u
|
||||||
|
#define IS_REQSTATE 0xFF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SAME_STATE_ATTEMPTS 3
|
#define SAME_STATE_ATTEMPTS 3
|
||||||
#define ANALOG_STATE_ATTEMPTS 6
|
#define ANALOG_STATE_ATTEMPTS 6
|
||||||
@@ -42,6 +58,15 @@ e-mail anklimov@gmail.com
|
|||||||
|
|
||||||
#define CHECK_INPUT 1
|
#define CHECK_INPUT 1
|
||||||
#define CHECK_SENSOR 2
|
#define CHECK_SENSOR 2
|
||||||
|
#define CHECK_INTERRUPT 3
|
||||||
|
#define CHECK_DELAYED 4
|
||||||
|
|
||||||
|
#define T_LONG 1000
|
||||||
|
#define T_IDLE 600
|
||||||
|
#define T_RPT 300
|
||||||
|
#define T_RPT_PULSE 200
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// in syntaxis
|
// in syntaxis
|
||||||
// "pin": { "T":"N", "emit":"out_emit", item:"out_item", "scmd": "ON,OFF,TOGGLE,INCREASE,DECREASE", "rcmd": "ON,OFF,TOGGLE,INCREASE,DECREASE", "rcmd":"repeat_command" }
|
// "pin": { "T":"N", "emit":"out_emit", item:"out_item", "scmd": "ON,OFF,TOGGLE,INCREASE,DECREASE", "rcmd": "ON,OFF,TOGGLE,INCREASE,DECREASE", "rcmd":"repeat_command" }
|
||||||
@@ -79,11 +104,24 @@ extern aJsonObject *inputs;
|
|||||||
typedef union {
|
typedef union {
|
||||||
long int aslong;
|
long int aslong;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
|
// Analog input structure
|
||||||
struct {
|
struct {
|
||||||
int8_t logicState;
|
uint8_t reserved;
|
||||||
int8_t bounce;
|
uint8_t reserved2;
|
||||||
int16_t currentValue;
|
int16_t currentValue;
|
||||||
};
|
};
|
||||||
|
// Digital input structure
|
||||||
|
struct {
|
||||||
|
uint8_t reserved3:1;
|
||||||
|
uint8_t lastValue:1;
|
||||||
|
uint8_t logicState:1;
|
||||||
|
uint8_t delayedState:1;
|
||||||
|
uint8_t bounce:4;
|
||||||
|
uint8_t state:4;
|
||||||
|
uint8_t reqState:4;
|
||||||
|
uint16_t timestamp16;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} inStore;
|
} inStore;
|
||||||
|
|
||||||
@@ -121,8 +159,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void Parse();
|
void Parse();
|
||||||
|
|
||||||
void contactPoll();
|
void contactPoll(short cause);
|
||||||
void analogPoll();
|
void analogPoll(short cause);
|
||||||
|
|
||||||
void dht22Poll();
|
void dht22Poll();
|
||||||
|
|
||||||
@@ -140,4 +178,6 @@ 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 executeCommand(aJsonObject* cmd, char* defCmd = NULL);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
int mqtt::publish(int value)
|
|
||||||
{};
|
|
||||||
|
|
||||||
int mqtt::publish(float value)
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
int mqtt::publish(char * value)
|
|
||||||
{
|
|
||||||
char addrstr[MQTT_TOPIC_LENGTH];
|
|
||||||
aJsonObject *emit = aJson.getObjectItem(in, "emit");
|
|
||||||
strncpy(addrstr,emit->valuestring,sizeof(addrstr));
|
|
||||||
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
|
|
||||||
if mqttClient.connected() mqttClient.publish(addrstr, value, true);
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
#define EEPROM_offset EEPROM_offset_NotAlligned + (4 -(EEPROM_offset_NotAlligned & 3))
|
#define EEPROM_offset EEPROM_offset_NotAlligned + (4 -(EEPROM_offset_NotAlligned & 3))
|
||||||
|
|
||||||
#ifndef INTERVAL_CHECK_INPUT
|
#ifndef INTERVAL_CHECK_INPUT
|
||||||
#define INTERVAL_CHECK_INPUT 50
|
#define INTERVAL_CHECK_INPUT 15
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INTERVAL_CHECK_SENSOR
|
#ifndef INTERVAL_CHECK_SENSOR
|
||||||
|
|||||||
@@ -504,5 +504,13 @@ RebootFunc();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool isTimeOver(uint32_t timestamp, uint32_t currTime, uint32_t time, uint32_t modulo)
|
||||||
|
{
|
||||||
|
uint32_t endTime=(timestamp + time) % modulo;
|
||||||
|
return ((currTime>endTime) && (currTime <timestamp)) ||
|
||||||
|
((timestamp<endTime) && ((currTime>endTime) || (currTime <timestamp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma message(VAR_NAME_VALUE(debugSerial))
|
#pragma message(VAR_NAME_VALUE(debugSerial))
|
||||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||||
|
|||||||
@@ -59,3 +59,4 @@ char* setTopic(char* buf, int8_t buflen, topicType tt, const char* suffix = NULL
|
|||||||
void printUlongValueToStr(char *valstr, unsigned long value);
|
void printUlongValueToStr(char *valstr, unsigned long value);
|
||||||
void scan_i2c_bus();
|
void scan_i2c_bus();
|
||||||
void softRebootFunc();
|
void softRebootFunc();
|
||||||
|
bool isTimeOver(uint32_t timestamp, uint32_t currTime, uint32_t time, uint32_t modulo = 0xFFFFFFFF);
|
||||||
|
|||||||
Reference in New Issue
Block a user