Publish on event change


#1

Hope this is not duplicate and someone can help. :slight_smile:

In my code I have a loop which checks state of two reed sensors. Value of those sensors is binded in varaiable “pinState”. Goal is to publish to IFTTT “doorStatus” only when “pinState” chnages, but I get multiple readings/publish.

This is my code:

    #define garagePin D1  // ignore the asterisk in the beginning
    bool toggle = false;
    //int A0 = 0;
    //int A1 = 0;


    //pin initializations
    const int pinReedSensorClosed = A0; // A0 =  HIGH - door closed
    const int pinReedSensorOpen = A1; // A1 = HIGH - door fully open
    const char* STATUS_MESSAGE_UNAVAILABLE = "Status unavailable.";
    const char* CLOSED = "Closed";
    const char* OPEN = "Open";
    const char* MID = "In motion";
    const char* message = STATUS_MESSAGE_UNAVAILABLE;

    int pinState = 0;
    int pinStatePrevious = 0;

    int gateToggle(String command);
    int checkStatus(String command);

    void setup() {
    pinMode(pinReedSensorClosed, INPUT_PULLDOWN);
    pinMode(pinReedSensorOpen, INPUT_PULLDOWN);
    pinMode(garagePin, OUTPUT);
    digitalWrite(garagePin, HIGH);
    Particle.function("toggleRelay", toggleRelay);
    //  Particle.function("toggleFoot", toggleFoot);
    Particle.function("checkStatus", checkStatus);
    Particle.variable("doorStatus", STATUS_MESSAGE_UNAVAILABLE, STRING);
    }


    void loop() {

       // loop over Reed switchs status to see if doors are open / closed / mid and send when changed to IFTTT
       
    const char* message = STATUS_MESSAGE_UNAVAILABLE;

    if(digitalRead(pinReedSensorClosed) ==1 and digitalRead(pinReedSensorOpen) ==0){
    pinState = 1; 
    }

    if(digitalRead(pinReedSensorClosed) ==0 and digitalRead(pinReedSensorOpen) ==1){
    pinState = 3; 
    }
      
    if(digitalRead(pinReedSensorClosed) ==0 and digitalRead(pinReedSensorOpen) ==0){
    pinState = 2; 
    }

    if(pinState == 1 ) message = CLOSED;
    if(pinState == 3 ) message = MID;
    if(pinState == 2 ) message = OPEN;

    if(pinState != pinStatePrevious) {
    Particle.variable("doorStatus", message , STRING);
    }

    delay(50); 
    pinStatePrevious = pinState;


    }

    int checkStatus(String command){
    // Ritual incantation to convert String into Int
    char inputStr[64];
    command.toCharArray(inputStr,64);

    const char* message = STATUS_MESSAGE_UNAVAILABLE;

    if(digitalRead(pinReedSensorClosed) ==1 and digitalRead(pinReedSensorOpen) ==0){
    message = CLOSED; 
    }

    if(digitalRead(pinReedSensorClosed) ==0 and digitalRead(pinReedSensorOpen) ==1){
    message = OPEN; 
    }

    if(digitalRead(pinReedSensorClosed) ==0 and digitalRead(pinReedSensorOpen) ==0){
    message = MID; 
    }
       
    Particle.publish("status", message);
    return 1;
    }

    int toggleRelay(String command){
    // Ritual incantation to convert String into Int
    char inputStr[64];
    command.toCharArray(inputStr,64);
    int i = atoi(inputStr);

    // Turn the desired relay on
    digitalWrite(garagePin, LOW);
    delay(5000);
    digitalWrite(garagePin, HIGH);
    toggle = false;
    // Respond
    return 1;
    }

IFTTT applet:

Thanks!


#2

Not having looked through the entire code, you might want to have another look at the documentation regarding Particle variables. Those things shouldn’t be in the loop.

As far as duplicate notificationa go, that could be an IFTTT thing. I suspect they check your recipe on an interval. As long as your valueatches, it’ll trigger, so if a reed stays actived, it’ll trigger everything it checks that, I think.
To prevent that, you could use publishes, and only publish once for a state change. That way, IFTTT only gets one input and will only trigger once. You’d basically do the “IF” part on the device, and leave the messaging to IFTTT.