Send Motion-user mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.sourceforge.net/lists/listinfo/motion-user
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Motion-user digest..."
Today's Topics:
1. Within py script, using Motion app (standalone, not
MotionEyeOS) in conjunction with button presses (Kevin Roy)
----------------------------------------------------------------------
Message: 1
Date: Mon, 21 Sep 2020 11:56:55 -0400
From: Kevin Roy <[email protected]>
To: [email protected]
Subject: [Motion-user] Within py script, using Motion app (standalone,
not MotionEyeOS) in conjunction with button presses
Message-ID:
<cak8qudcri5chqdi3nx8ud71xybx5z3o-+sq6adjvbcnghtc...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
First time I've posted to the mailing list - apologies in advance if I have
messed something up.
I have a python script (doorbell.py) that, upon a button press, it takes a
picture, plus a few other things like rings a bell and sends an MQTT msg to
Home Assistant.
While the button is inactive/NOT being pressed, I'd like to have Motion
running for motion detection purposes, and eventually do some object
recognition. However, if I start/run Motion in one command line tab, and
run the doorbell.py script in a another, when the button is pressed, the
doorbell.py script fails because the camera is already in use by Motion.
So, I tried to integrate turning motion on and off from within the
doorbell.py script with '''subprocess.call'''. Before integrating any
subprocess.call's into the doorbell.py script, I verified these work when
run as independent py script, and they do work (scripts below).
#start_motion.py
import subprocess
subprocess.call(["motion", "-n"])
#stop_motion.py
import subprocess
subprocess.call(["pkill", "-15", "motion"])
So, I integrated them into the main doorbell.py script. In the beginning of
doorbell.py, Motion is started/turned on. When a button press is detected,
I tried to turn Motion off via ```subprocess.call(["pkill", "-15",
"motion"])``` but it appears to never recognizes the button press - though
I am unsure why.
How could I modify this to make it work - or is there another better/more
simple method I could employ here? Here is the full doorbell.py script. Be
kind, I'm a python (and Motion) noob!
import RPi.GPIO as GPIO
import time
import picamera
import datetime as dt
import sys
import paho.mqtt.client as mqtt # import the MQTT library
import subprocess
# Start Motion app
subprocess.call(["motion", "-n"])
#def MQTT messagefunction here
def messageFunction (client, userdata, message):
topic = str(message.topic)
message = str(message.payload.decode("utf-8"))
print("MQTT Topic: " + topic + "/" + message)
# Set up MQTT client and server connection
MQTTClient=mqtt.Client("pi3a_mqtt")
MQTTClient.username_pw_set(username="*********", password="*********")
MQTTClient.connect("192.168.1.237", 1883)
MQTTClient.subscribe("DOORBELL")
MQTTClient.on_message = messageFunction
MQTTClient.loop_start()
# Set up GPIO mode and assignments
GPIO.setmode(GPIO.BCM)
buttonPIN = 18 # Button PIN
GPIO.setup(buttonPIN, GPIO.IN <https://gpio.in/>,
pull_up_down=GPIO.PUD_DOWN)
# Copied code for buzzer music
class Buzzer(object):
def __init__(self):
GPIO.setmode(GPIO.BCM)
self.buzzer_pin = 14 #set to GPIO pin 14
GPIO.setup(self.buzzer_pin, GPIO.IN <https://gpio.in/>)
GPIO.setup(self.buzzer_pin, GPIO.OUT)
print("buzzer ready")
def __del__(self):
class_name = self.__class__.__name__
print (class_name, "finished")
def buzz(self,pitch, duration): #create the function ?buzz? and feed it the
pitch and duration)
if(pitch==0):
time.sleep(duration)
return
period = 1.0 / pitch #in physics, the period (sec/cyc) is the inverse of
the frequency (cyc/sec)
delay = period / 2 #calcuate the time for half of the wave
cycles = int(duration * pitch) #the number of waves to produce is the
duration times the frequency
for i in range(cycles): #start a loop from 0 to the variable ?cycles?
calculated above
GPIO.output(self.buzzer_pin, True) #set pin 18 to high
time.sleep(delay) #wait with pin 18 high
GPIO.output(self.buzzer_pin, False) #set pin 18 to low
time.sleep(delay) #wait with pin 18 low
def play(self, tune):
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.buzzer_pin, GPIO.OUT)
x=0
print("Playing tune ",tune)
if(tune==1):
pitches=[262,294,330]#,349,392,440,494,523, 587, 659,698,784,880,988,1047]
duration=0.1
for p in pitches:
self.buzz(p, duration) #feed the pitch and duration to the function, ?buzz?
time.sleep(duration *2)
# for p in reversed(pitches):
# self.buzz(p, duration)
# time.sleep(duration *0.5)
elif(tune==2):
pitches=[262,330,392,523,1047]
duration=[0.2,0.2,0.2,0.2,0.2,0,5]
for p in pitches:
self.buzz(p, duration[x]) #feed the pitch and duration to the function,
?buzz?
time.sleep(duration[x] *0.5)
x+=1
elif(tune==3):
pitches=[392,294,0,392,294,0,392,0,392,392,392,0,1047,262]
duration=[0.2,0.2,0.2,0.2,0.2,0.2,0.1,0.1,0.1,0.1,0.1,0.1,0.8,0.4]
for p in pitches:
self.buzz(p, duration[x]) #feed the pitch and duration to the func$
time.sleep(duration[x] *0.5)
x+=1
elif(tune==4):
pitches=[1047, 988,659]
duration=[0.1,0.1,0.2]
for p in pitches:
self.buzz(p, duration[x]) #feed the pitch and duration to the func$
time.sleep(duration[x] *0.5)
x+=1
elif(tune==5):
pitches=[1047, 988,523]
duration=[0.1,0.1,0.2]
for p in pitches:
self.buzz(p, duration[x]) #feed the pitch and duration to the func$
time.sleep(duration[x] *0.5)
x+=1
GPIO.setup(self.buzzer_pin, GPIO.IN <https://gpio.in/>)
# Detect Button Press on GPIO 18
# If button press detected:
# Stop Motion app
# Take picture
# Ring buzzer
# Send MQTT msg
# Restart Motion app
# If not, clean up GPIO pins
while True:
input_state = GPIO.input(buttonPIN)
if input_state == True:
subprocess.call(["pkill", "-15", "motion"])
print('Button Pressed')
# MQTTClient.publish("DOORBELL", "on") # Publish message to MQTT broker
# # buzzer.start(10) # Set dutycycle to 10
# if __name__ == "__main__":
# a = 1
# buzzer = Buzzer()
# buzzer.play(int(a))
time.sleep(0.3)
with picamera.PiCamera() as camera:
camera.resolution = (800, 600)
camera.annotate_background = picamera.Color('black')
camera.annotate_text = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
camera.start_preview()
camera.capture('doorbell.jpg', use_video_port=True)
# camera.start_recording('doorbell.h264')
# camera.wait_recording(20)
MQTTClient.publish("DOORBELL", "on") # Publish message to MQTT broker
# buzzer.start(10) # Set dutycycle to 10
if __name__ == "__main__":
a = 1
buzzer = Buzzer()
buzzer.play(int(a))
time.sleep(.5)
# buzzer.stop()
subprocess.call(["motion", "-n"])
GPIO.cleanup()
-------------- next part --------------
An HTML attachment was scrubbed...
------------------------------
------------------------------
Subject: Digest Footer
_______________________________________________
Motion-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/motion-user
------------------------------
End of Motion-user Digest, Vol 171, Issue 13
********************************************