Raspberry Pi Generic Digial IO Notifications

I have a Raspberry Pi 4. I have connected it to MyDevices and setup a Generic Digital IO Widget. I am getting data back properly from the IO but when I setup a notification I just keeps seding me emails like crazy. I would like to receive one email when the state goes to 1 and another email when the state goes 0. How can I accomplish this? I feel like this should be stupid simple, so I have most likely just missed something. Thanks for your help!

have a look at this topic Sending MQTT messages within notification limit and the solution for it.

I tried

#!/usr/bin/env python

import cayenne.client

import time

import logging



# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.

MQTT_USERNAME  = "MQTT_USERNAME"

MQTT_PASSWORD  = "MQTT_PASSWORD"

MQTT_CLIENT_ID = "MQTT_CLIENT_ID"



TRIGGER_CHANNEL = 2  #Virtual channel for publishing the trigger value.

DATA_CHANNEL = 1     #Virtual channel for publishing the sensor data.

THRESHOLD = 6        #Threshold for the trigger.



i=0

timestamp = 0

send_below_threshold = False #Set to true if the trigger should happen when the data value is below the threshold, 

                             #false if it should happen when the data value is above or equal to the threshold.

crossed_threshold = False



# The callback for when a message is received from Cayenne.

def on_message(message):    

    print("message received: " + str(message))

    # If there is an error processing the message return an error string, otherwise return nothing.



client = cayenne.client.CayenneMQTTClient()

client.on_message = on_message

client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO)

# For a secure connection use port 8883 when calling client.begin:

# client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)



def send_trigger_value(trigger_channel, sensor_value, threshold, send_below_threshold):

    global crossed_threshold

    if (((sensor_value >= threshold) and not send_below_threshold) or ((sensor_value < threshold) and send_below_threshold)):

        if not crossed_threshold:

            client.virtualWrite(trigger_channel, 1, "digital_sensor", "d")

            crossed_threshold = True

    else:

        client.virtualWrite(trigger_channel, 0, "digital_sensor", "d")

        crossed_threshold = False





while True:

    client.loop()

    if (time.time() > timestamp + 10):

        sensor_value =  i 

        client.celsiusWrite(DATA_CHANNEL, sensor_value)

        send_trigger_value(TRIGGER_CHANNEL, sensor_value, THRESHOLD, send_below_threshold)

        timestamp = time.time()

        i = i + 1

        if (i == 12): # Reset the sensor value to test that the trigger gets reset.

            i = 0`

and it gives me this error

client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, loglevel=logging.INFO)
TypeError: begin() got an unexpected keyword argument ‘loglevel’

are you using python2 or python3?

Python 3

you can remove this part , loglevel=logging.INFO

I just tried that and its running now. But after setting up the trigger notification it sent me 10 texts in less than 2 minutes. I have the threashold set to 6. But if im reading this correctly, it will send me a text as long as the sensor sends a value of less than six… right?

I am trying to monitor the state of a digital IO. So, the data will only be 1 or 0. I need a notification for when it goes high and a notification for when it goes low. But I only want one notification for each occurrence of the change from 0 to 1 or from 1 to 0.

it only works for one state change, either from 0 to 1 or 1 to 0. It wont work for both.

Well so far I have only been reading a 0 and normally I will only be reading a zero. The problem is that it is sending constant notifications for a 0 value. The threshold is for not sending notifications above a specified sensor value right? How do I stop it from sending constant notifications when I have a trigger set for when the value is 1? this is for monitoring my generators running state so that I know when it comes on?I don’t want a notification every 2 seconds whenever its on.

the code is meant to add trigger when the state changes from 0 to 1 and not for 1 to 0. Hence you are getting so many notifications.

I’ve done this both ways. I was at the generator for 2 hours this morning testing in both directions by just adding a generic digital input. We tried it running and off and in both senerios it was sending constant notifications. I came back to do some research and found the information that you initially shared with me and tried that but couldn’t get it to work. Since following the guide you sent me and using your advice I was able to successfully “bring my own device” and setup the trigger but with the same results as before. So, I’m confused. No matter what I do, when the state triggers the notification regardless of weather it set for 0 to 1 or 1 to 0 I get constant notifications. Is there no way to only get one notification when the state changes from 0 to 1?

are you sure, with the above code and notification trigger set for change from 0 to 1, you get many notifications? Also to note there is a reset counter in the code, so it will send a new notification once reset.

def send_trigger_value(trigger_channel, sensor_value, threshold, send_below_threshold):

    global crossed_threshold

    if (((sensor_value >= threshold) and not send_below_threshold) or ((sensor_value < threshold) and send_below_threshold)):

        if not crossed_threshold:

            client.virtualWrite(trigger_channel, 1, "digital_sensor", "d")

            crossed_threshold = True

    else:

        client.virtualWrite(trigger_channel, 0, "digital_sensor", "d")

        crossed_threshold = False





while True:

    client.loop()

    if (time.time() > timestamp + 10):

        sensor_value =  i

        client.celsiusWrite(DATA_CHANNEL, sensor_value)

        send_trigger_value(TRIGGER_CHANNEL, sensor_value, THRESHOLD, send_below_threshold)

        timestamp = time.time()

        i = i + 1

        if (i == 12): # Reset the sensor value to test that the trigger gets reset.

            i = 0

Im sure. It may not be every 2 seconds… maybe as the code says it is every 12 seconds but still constant notifications.
I need more like
If IO == 1 then send notification
not
While == 1 send notifications

Is this possible?

this is what it is doing.

I have shared the code I used and I guess I could share my texts too if you need the proof. But that’s not what is happening. If I have a trigger set for either from 1 to 0 or from 0 to 1 then I am getting constant notifications.

can you try now, and i will monitor it.

running now

check the state in the notification, i guess find out the mistake you are making.

What did you find on your end?