How to trigger a script on pi 3?

It is almost working now. The Cayenne dasboard widget detected motion, but not easy, and the trigger did not run. But I start to see the way. Some small adjustment and it might be OK.

hold on with trigger. looks like there is some problem with trigger.

In addition to the triggers having issues, I did modify that a few times. Double check that you have the current code that’s in the post above. As I thought about it I added a couple lines.

If it is cretical not to have more than 2 sec delay in the loop, maybe it is possible to just start a small program that run in parallell and take picture and save to the disk. I got the feeling this camera operation take some time.

code by adam should work with a bit of change

if GPIO.input(18):
            print("Motion Detected...")
            client.virtualWrite(2,1,"digital_sensor","d")
            #time.sleep(2) ####If you really do need a delay here make it less than 1 second
            camera.capture('/home/pi/Desktop/image.jpg')
            motion = true
            motioncounter = 0

I was thinking of using fork.

But I will try the code of adam some more.

Just tested the new code, and it is working the first time I make a move, and the dashboard widges goes from 0 till 1. Then after a minute, it goes back to 0. Then it looks like I loose connection to the dashboard, because it will only show 0.

Are you seeing any errors in the terminal when you run the code? I didn’t test the code I posted above, it’s possible I missed something.

No, only that i har to ude kapital lettere in True ond False.

I will make Ä quick test now before going to work. I will comment out the picture takling and leiting to disk to are if this time consuming operasjon hÄs any effekt.

-------- Opprinnelig melding --------

When I commented out the line:
camera.capture(
)
The rest is working, and I can see the changes in the dasboard.

check for any error in the terminal.

No errors. Now I have commented out the line with camera.:

pi@raspberrypi:~/mqtt/examples $ python3 Ex-04-CayenneClient.py
Connecting to mqtt.mydevices.com:1883
Motion Detected

Connected with result code 0
SUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/cmd/+

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/sys/model
Python

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/sys/version
1.1.0

Motion Detected

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/data/2
digital_sensor,d=1

Made a new run with the camera line active:

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2–9794-1f5f0ee2f68d/data/2
digital_sensor,d=0

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/data/2
digital_sensor,d=0

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/data/2
digital_sensor,d=0

Motion Detected

PUB v1/a7fc5bb0-e16c-11e6-a446-0d180dc59d42/things/2d4d4ad0-4fc2-11e8-9794-1f5f0ee2f68d/data/2
digital_sensor,d=1

Made a new run with the camera line active:

The dasboard is not changing from 0 till 1, and the python program is not reporting any errors.
Every time, I stop the python promgram with ctrl-z, I need to reboot the pi, otherwise I get som error that camera is not free.

If it is the time the camera function is using that might be too long for Cayenne. I guess it takes some time to write the picture down to a SD card. What if Cayenne’s .py file just write a short message down to a file, like 0 for no motion and 1 for motion.
Then a separate python program that has no time limitation read this file every second or five, and take the picture if 1 is on the file, and change the file back to 0.
It means introducing two new files, but it should help for the time problem. What do you think?
At least this could be temporary solution until Cayenne manage to take pictures.

i will test some scripts with PIR and camera and let you know.

Made a test program Motion_0_1.py

It is working, but I need to reboot the pi every time I stop it with Ctrl-Z. Need to free camera.

#!/usr/bin/env python

import time
from picamera import PiCamera
from time import sleep
camera = PiCamera()

while (True):
time.sleep(1)
f = open(“test.txt”,“r”)
data = f.read()
#f.write(“0”)
f.close()
if (data == “1” ):
print(“Motion read
”)
camera.capture(‘/home/pi/Desktop/image.jpg’)
f = open(“test.txt”,“w”)
f.write(“0”)
f.close()

i don’t have a PIR sensor around but tried some workaround and it works. this example uses a button channel 4 on the dashboard to take a pic. do the neccesary changes with PIR code in this code. to overcome the problem of camera been busy, I have added a button “exit” with channel 5 to quit the script.

#!/usr/bin/env python

from picamera import PiCamera
from time import sleep

camera = PiCamera()

import cayenne.client
import time
x = 0
# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = ""
MQTT_PASSWORD  = ""
MQTT_CLIENT_ID = ""


# The callback for when a message is received from Cayenne.
def on_message(message):
    global x
    print("message received: " + str(message))
    # If there is an error processing the message return an error string, otherwise return nothing.
    if (message.channel == 4) and (message.value == "1"):
        print("button is pressed")
        x = 1
    if (message.channel == 5) and (message.value == "1"):
        print("button is pressed")
        quit()

client = cayenne.client.CayenneMQTTClient()
client.on_message = on_message
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)
# For a secure connection use port 8883 when calling client.begin:
# client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883)

i=0
timestamp = 0

while True:
    client.loop()

    if (x == 1):
        i = i + 1
        client.virtualWrite(2,1,"digital_sensor","d")
        time.sleep(1) ####If you really do need a delay here make it less than 1 second
        photo_path = '/home/pi/image%s.jpg' %i
        camera.capture(photo_path)
        print("taking pic")
        x = 0
    else:
        if (time.time() > timestamp + 10):
            print("making two state zero")
            client.virtualWrite(2,0,"digital_sensor","d")
            timestamp = time.time()

this is because it is hitting rate limit.

I have made changes to the code given by @adam. give it a try and let me know.

motion = false
motioncounter = 0
while True:
    client.loop()
    if motion:
        motioncounter += 1
    if (not motion) or (motioncounter > 50):
        if motioncounter > 50:
            motioncounter = 0
        if GPIO.input(18):
            print("Motion Detected...")
            client.virtualWrite(2,1,"digital_sensor","d")
            camera.start_preview()
            #time.sleep(5) ####If you really do need a delay here make it less than 1 second
            camera.capture('/home/pi/Desktop/image.jpg')
            camera.stop_preview()
            motion = true
            motioncounter = 0
        else:
            if (time.time() > timestamp + 10):
                print("making two state zero")
                client.virtualWrite(2,0,"digital_sensor","d")
                 timestamp = time.time()
                 motion = false
    time.sleep(0.1)

Good call, forgot to mention that

I just got home, and tested first the code without motion detection, and it was working fine. Thank you for the Quit button. It saved me from reboot of the Pi between ever test.
Then I added the last part with motion detection, and it is working too. And I can see the changes in pi window and on Cayenne dasboard.Very good.
Now I only need the triggers to work.
Keep up the good work.

1 Like