Using openhab2 on machine A. Machine B is a RPi which controls a relay.
Using pigpio and gpiozero from machine a to control machine b gpio pins.
Using below script for testing. How can I rewrite this so that the on/off function in openhab will work? as of now it just loops between on and off.
help a noob please
#!/usr/bin/python
# https://gpiozero.readthedocs.io/en/stable/
# https://gpiozero.readthedocs.io/en/stable/api_output.html#outputdevice
import sys
import time
import gpiozero
relay = gpiozero.OutputDevice(18, active_high=False, initial_value=False)
def set_relay(status):
if status:
print("Setting relay: ON")
relay.on()
else:
print("Setting relay: OFF")
relay.off()
def toggle_relay():
print("toggling relay")
relay.toggle()
def main_loop():
while 1:
# then toggle the relay every second until the app closes
toggle_relay()
# wait a second
time.sleep(1)
if __name__ == "__main__":
try:
main_loop()
except KeyboardInterrupt:
# turn the relay off
set_relay(False)
print("\nExiting application\n")
# exit the application
sys.exit(0)
Related
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt
import time
def privacyfunc():
# Pin Definitions:
led_pin_1 = 7
led_pin_2 = 21
but_pin = 18
# blink LED 2 quickly 5 times when button pressed
def blink(channel):
x=GPIO.input(18)
print("blinked")
for i in range(1):
GPIO.output(led_pin_2, GPIO.HIGH)
time.sleep(0.5)
GPIO.output(led_pin_2, GPIO.LOW)
time.sleep(0.5)
mqttBroker="mqtt.fluux.io"#connect mqtt broker
client=mqtt.Client("privacybtn") #create a client and give a name
client.connect_async(mqttBroker)#from the client -connect broker
while True:
client.publish("privacy", x)#publish this random number to the topic called temparature
print("Just published"+str(x)+"to Topc to privacy")#just print random no to topic temparature
break
def main():
# Pin Setup:
GPIO.setmode(GPIO.BOARD) # BOARD pin-numbering scheme
GPIO.setup([led_pin_1, led_pin_2], GPIO.OUT) # LED pins set as output
GPIO.setup(but_pin, GPIO.IN) # button pin set as input
# Initial state for LEDs:
GPIO.output(led_pin_1, GPIO.LOW)
GPIO.output(led_pin_2, GPIO.LOW)
GPIO.add_event_detect(but_pin, GPIO.FALLING, callback=blink, bouncetime=10)
print("Starting demo now! Press CTRL+C to exit")
try:
while True:
x=GPIO.input(18)
print(x)
# blink LED 1 slowly
GPIO.output(led_pin_1, GPIO.HIGH)
time.sleep(2)
finally:
GPIO.cleanup() # cleanup all GPIOs
if __name__ == '__main__':
main()
need to take this whole code into a function that can be accessed from another python file.plz, help me with this coding part.
In the new python file call import module where module is the name of the file. Like led_blink.py would be import led_blink
Then you can call the methods like so:
led_blink.blink(channel)
This is assuming the files are in the same folder.
Easiest way that I do this is to take a .py file and put it in the same directory you created the python script you are working with. From there you can do the following code from The_Python_File import *
Additionally note that the "The_Python_File" is the name of the .py file that contains the function you are trying to call, but you do not include .py when importing the file.
I have the following scenario. With a raspberry pi I have a main function which runs in a while loop and alternates tasks between calls to sleep. I would like a button press to interrupt the main loop and do another task for a certain amount of time before returning to the main loop. In reality I am displaying output on an LCD screen but I coded up this simpler example to illustrate the problem with my logic. I think things are getting crossed up because both functions seem to be active at the same time? I don't know the correct way to handle this scenario. Can someone suggest how to do this properly?
from time import sleep
import RPi.GPIO as GPIO
BUTTON_PIN = 2 # GPIO pin for mode button
def main():
print("mode1 part A")
sleep(4)
print("mode1 part B")
sleep(4)
def run_mode_two():
# I would like this function to full execute before retuning to main
print("mode2")
sleep(8)
# function to be called by interrupt
def button_released_callback(channel):
run_mode_two()
# intialize gpio for button
GPIO.setmode(GPIO.BCM)
GPIO.setup(
BUTTON_PIN,
GPIO.IN,
pull_up_down = GPIO.PUD_UP)
# interrupt to listen for button push
GPIO.add_event_detect(
BUTTON_PIN,
GPIO.RISING,
callback = button_released_callback,
bouncetime = 300)
while True:
main()
The following pseudo code for your reference. Only focus on the flow, please adapt it to your own needs.
mode = 1
def button_callback():
mode = 2
start_timer(5)
def timer_callback():
mode = 1
def loop():
if mode == 1:
# run code in mode 1
else:
# run code in mode 2
def main():
# init code here
# ...
while True:
loop()
I am writing python code on raspberry pi 3. I am registering an event on input channel 21, to check moisture detection. I am getting this error Runtime error:Failed to add edge detection.
My code is:
import RPi.GPIO as GPIO
import sys,os
import time
import datetime
channel = 21
led_output = 18
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(channel, GPIO.IN)
GPIO.setup(led_output, GPIO.OUT)
def callback(channel):
filehandle = open("output.txt", "w") or die ("Could not write out")
if GPIO.input(channel) == 1:
print ("Water Detected!")
filehandle.write("1")
GPIO.output(led_output, GPIO.LOW)
else:
print ("Water Not Detected!")
filehandle.write("0")
GPIO.output(led_output, GPIO.HIGH)
filehandle.close()
GPIO.add_event_detect(channel, GPIO.BOTH, bouncetime=300)
GPIO.add_event_callback(channel, callback)
print(GPIO.input(channel))
while True:
time.sleep(5)
When I reboot the Raspberry and run your code it works perfect.
Only after killing the process or CTRL-C keyboard interrupting and running it again the problem/error occurs. I think this has to do with the fact that you exit the program without cleaning up properly...
I got it working in case you exit the running the program with CTRL-C with the code below in which I included a GPIO.cleanup()
However...this unfortunately it does not cover the situation in which you simply kill the running programm...In that case you still need to reboot.
So there is room for improvement.
Please re-insert your own file management commands again.
import RPi.GPIO as GPIO
import sys,os
import time
import datetime
channel = 21
led_output = 18
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(channel, GPIO.IN)
GPIO.setup(led_output, GPIO.OUT)
def callback(channel):
if GPIO.input(channel) == 1:
print ("Water Detected!")
GPIO.output(led_output, GPIO.LOW)
else:
print ("Water Not Detected!")
GPIO.output(led_output, GPIO.HIGH)
GPIO.add_event_detect(channel, GPIO.BOTH, bouncetime=300)
GPIO.add_event_callback(channel, callback)
print(GPIO.input(channel))
try:
while True:
#main loop here with some (dummy) code
eg_set_a_dummy_variable = 0
except KeyboardInterrupt:
# here you put any code you want to run before the program
# exits when you press CTRL+C
print ("Program interrupted by CTRL-C")
except:
# this catches ALL other exceptions including errors.
# You won't get any error messages for debugging
# so only use it once your code is working
print ("Other error or exception occurred!")
finally:
# this ensures a clean exit and prevents your
# error "Runtime error:Failed to add edge detection"
# in case you run your code for the second time after a break
GPIO.cleanup()
# credits to:
# https://raspi.tv/2013/rpi-gpio-basics-3-how-to-exit-gpio-programs-cleanly-avoid-warnings-and-protect-your-pi
It is not very clean solution, but you can call GPIO.cleanup() at the start of your script too for case when your process was killed before and GPIO.cleanup() was not called.
Hi I am trying to make drive recorder by raspberry pi3 and camera module.
Then I am using picamera which is python library that uses the official camera module for development.
Here is a document of picamera.
Basic idea is this.
Record for 10 min and loop this.
If user pushed button that connected to GPIO pin, stop recording.
I thought I can use the callback function to end the recording.
But I couldn't stop camera recording by callback method.
Does anyone tell me my recognition of callback is wrong?
Here is my code.
#!/usr/bin/python
# -*- coding: utf-8 -*-
from time import sleep
from picamera import PiCamera
import os
import sys
import datetime
import RPi.GPIO as GPIO
import os
class driveRecoder():
try:
#Button setup
SWITCH_PIN=21
GPIO.setmode(GPIO.BCM)
GPIO.setup(SWITCH_PIN,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
#Camera setup
camera = PiCamera()
resolution_width = 1920
resolution_height = 1080
record_time=60
camera.resolution = (resolution_width, resolution_height)
camera.framerate = 30
camera.led = False
def shutdown():
print "shutdown"
os.system("sudo shutdown -h now")
#Callback function
def stopRecording():
camera.stop_recording()
print("録画終了")
#I want to power down after stop recording
#GPIO.cleanup()
#shutdown()
GPIO.add_event_detect(SWITCH_PIN,GPIO.FALLING)
GPIO.add_event_callback(SWITCH_PIN,stopRecording)
while True:
try:
print("録画開始")
#setup file name and directory path to save
now = datetime.datetime.now()
dir_name = now.strftime('%Y%m%d')
dir_path = '/home/admini/Video/'+dir_name
file_name = now.strftime('%H%M%S')
#Make each date folder if not exist folder
if not os.path.exists(dir_path):
os.makedirs(dir_path)
os.chmod(dir_path, 0777)
#Recording 10 min the loop
camera.start_recording(dir_path+'/'+file_name+'.h264')
camera.wait_recording(record_time)
camera.stop_recording()
print("録画終了")
sleep(2)
except KeyboardInterrupt:
camera.stop_recording()
break
finally:
pass
print("録画終了")
except KeyboardInterrupt:
print("ctl+c終了")
GPIO.cleanup()
sys.exit(0)
finally:
pass
print("終了")
GPIO.cleanup()
sys.exit(0)
You need to pull this function out of the class for DriveRecorder. I am surprised you aren't seeing an error. I would pull "shutdown" function out, too.
#Callback function
def stopRecording():
camera.stop_recording()
print("録画終了")
#I want to power down after stop recording
#GPIO.cleanup()
#shutdown()
I'm an absolute python newbie and this is my first raspberry project. I try to build a simple music player in which every input button loads a different album (8 albums) and 3 buttons to control playback (next, pause, last).
To load the music I use a USB drive which, as soon as it is connected automatically triggers the copy process.
The buttons are debounced with a callback function. Everything works great, except that after new music is loaded with the USB drive the buttons don't work anymore.
Most likely it is a simple programming issue which I - as a beginner - just don't see.
This is the code to work with two buttons:
#!/usr/bin/env python
import RPi.GPIO as GPIO
import os
import pyudev
from time import sleep
from mpd import MPDClient
from socket import error as SocketError
# Configure MPD connection settings
HOST = 'localhost'
PORT = '6600'
CON_ID = {'host':HOST, 'port':PORT}
#Configure Buttons
Button1 = 25
Button2 = 24
GPIO.setmode(GPIO.BCM)
GPIO.setup(Button1, GPIO.IN)
GPIO.setup(Button2, GPIO.IN)
client = MPDClient()
#Function to check if USB is connected
def checkForUSBDevice(name):
res = ""
context = pyudev.Context()
for device in context.list_devices(subsystem='block', DEVTYPE='partition'):
if device.get('ID_FS_LABEL') == name:
res = device.device_node
return res
#Function to load music from USB
def loadMusic(client, con_id, device):
os.system("mount "+device+" /music/usb")
os.system("/etc/init.d/mpd stop")
os.system("rm -r /music/mp3/*")
os.system("cp -r /music/usb/* /music/mp3/")
os.system("umount /music/usb")
os.system("rm /music/mpd/tag_cache")
os.system("/etc/init.d/mpd start")
os.system("mpc clear")
os.system("mpc ls | mpc add")
os.system("/etc/init.d/mpd restart")
#Function to connect to MPD
def mpdConnect(client, con_id):
try:
client.connect(**con_id)
except SocketError:
return False
return True
#Function to load an Album
def loadAlbum(number):
mpdConnect(client, CON_ID)
if client.status()["state"] == "play" or client.status()["state"] == "pause": client.stop()
os.system("mpc clear")
os.system("mpc ls "+str(number)+" | mpc add")
client.play()
client.disconnect()
#Callback Function
def buttonPressed(channel):
if channel == Button1:
print('Button 1 HIT')
loadAlbum(1)
elif channel == Button2:
print('Button 2 HIT')
loadAlbum(2)
def main():
GPIO.add_event_detect(Button1, GPIO.RISING, callback=buttonPressed, bouncetime=200)
GPIO.add_event_detect(Button2, GPIO.RISING, callback=buttonPressed, bouncetime=200)
# This function just creates an endless loop which does
# nothing, in order for the button detection to work
try:
flag = 0
while flag == 0:
device = checkForUSBDevice("MUSIC") # MUSIC is the name of my thumb drive
if flag == 1:
flag = 0
else:
flag = 0
if device != "":
# USB thumb drive has been inserted, new music will be copied
print('USB erkannt, Musik wird kopiert.', device)
loadMusic(client, CON_ID, device)
print('Musik wurde kopiert, USB kann entfernt werden!', device)
while checkForUSBDevice("MUSIC") == device:
sleep(1.0)
print('USB wurde entfernt.')
loadAlbum(1)
except KeyboardInterrupt:
GPIO.cleanup()
if __name__ == "__main__":
main()
Hope anyone can help me on this?
Matthias
Here is what did the trick for me. Probably it's not the best solution but it seams to do the trick.
Only the main function was changed. Changes are highlighted at the beginning of the line with a comment.
def main():
GPIO.add_event_detect(Button1, GPIO.RISING, callback=buttonPressed, bouncetime=200)
GPIO.add_event_detect(Button2, GPIO.RISING, callback=buttonPressed, bouncetime=200)
# This function just creates an endless loop which does
# nothing, in order for the button detection to work
try:
flag = 0
while flag == 0:
device = checkForUSBDevice("MUSIC") # MUSIC is the name of my thumb drive
if flag == 1:
flag = 0
else:
flag = 0
if device != "":
# USB thumb drive has been inserted, new music will be copied
print('USB erkannt, Musik wird kopiert.', device)
# Stop the callback before loading the files from the USB:
GPIO.remove_event_detect(Button1)
GPIO.remove_event_detect(Button2)
loadMusic(client, CON_ID, device)
print('Musik wurde kopiert, USB kann entfernt werden!', device)
while checkForUSBDevice("MUSIC") == device:
sleep(1.0)
print('USB wurde entfernt.')
loadAlbum(1)
# Recall the main function
main()
except KeyboardInterrupt:
GPIO.cleanup()
The reason that the buttons dont work any more is because you are still in the callback function - so it cant get triggered again. The solution is to use the callback function to simply set a flag and have the main waiting loop detect the flag and do the playing. But note that playing is probably blocking so that the main loop will also have stopped for the duration.