Raspberry Pi Coop Automation

Glad to hear your setup and ready to do some coding.

Go back to the beginning of this thread and study the event loop and try to understand what it does while running it.

Better save Gstreamer and NGINX for later...

JT
 
The event loop waits for something to happen that you have programmed it to wait for. For example you can tell it to wait for sunrise to do something at sunrise or it can wait for a button press and do something. It's the heartbeat of the program so to speak. In the example every 0.1 seconds the update function is ran by the updateTimer.

Python:
#!/usr/bin/python3

import sys, time, signal
from datetime import datetime
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QTimer

class main():
    def __init__(self):
        #exit the program when ctrl c is pressed
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        # Set date on startup
        self.today = datetime.today().date()
        self.done = False

        # Setup the heartbeat timer to run the update function every 100ms
        # 1 second has 1000 milliseconds
        updateTimer = QTimer()
        updateTimer.timeout.connect(self.update)
        updateTimer.start(100)

    def printMinute(self, m):
        print(f'The current even minute is {m}')

    def update(self):
        # this example shows a way to do something one time when an event happens
        minute = datetime.now().minute
        # if the remainder of minute / 2 is equal to 0 and self.done is not True
        if minute % 2 == 0 and not self.done:
            # call the printMinute function and pass the minute to it
            self.printMinute(minute)
            # now set self.done to True so it only happens once
            self.done = True
        # else if the remainder of minute / 2 is not equal to 0 set self.done to False
        elif minute % 2 != 0:
            self.done = False

if __name__ == '__main__':
    app = QApplication(sys.argv)
    gui = main()
    sys.exit(app.exec_())

JT
 
When programming in Python if you have a while something loop often it becomes a blocking loop. When a loop is blocking the main event loop from working nothing can happen in the main event loop. So if the main loop monitors a panic button for the door it won't react to that button push until the blocking loop is finished.

A Blocking Loop
Python:
    def openDoor(self): # this is a blocking function
        #print('open')
        self.doorStatus = 'opening'
        print('Opening the Door')
        self.startClock = int(monotonic())
        gpio.output(DOOR_UP, RUN)
        while self.upProx != 1:
            self.upProx = self.upProxState.update()
            current = int(monotonic())
            transitTime = current - self.startClock
            self.transitTimeLbl.setText(f'Transit\nTime\n{transitTime}')
            self.repaint()
            if transitTime > 90:
                print('Door is Broken')
                self.doorStatus = 'broken'
                break
            elif self.upProx == 1:
                print('Door is Open')
                self.doorStatus = 'open'
                self.upProxLbl.setText(self.doorState[self.upProx])
                self.downProxLbl.setText(self.doorState[self.downProx])
        gpio.output(DOOR_UP, STOP)

What happens is the program stays inside of the while loop until it either breaks out due to a time out or the up prox is equal to 1. Then and only then the output is turned off. So not a good way to write your program.

JT
 
This function is non blocking so it does not have a while loop. What you do it call the function over and over from the main event loop.

Non Blocking Function
Python:
    def closeDoor(self): # this is a non blocking function
        # if this is the start of closing get a start time
        if self.doorStatus != 'closing':
            self.startClock = int(monotonic())
            self.doorStatus = 'closing'
            print('Closing the Door')
            gpio.output(DOOR_DOWN, RUN)

        self.downProx = self.downProxState.update()
        currentClock = int(monotonic())
        transitTime = currentClock - self.startClock
        self.transitTimeLbl.setText(f'Transit\nTime\n{transitTime}')
        if transitTime > 90:
            print('Door is Broken')
            # set the door status to broken so it won't keep trying
            self.doorStatus = 'broken'
            gpio.output(DOOR_DOWN, STOP)
        elif self.downProx == 1:
            print('Door is Closed')
            self.doorStatus = 'closed'
            self.downProxLbl.setText(self.doorState[self.downProx])
            self.upProxLbl.setText(self.doorState[self.upProx])
            gpio.output(DOOR_DOWN, STOP)

We call this function from the main event loop over and over like this.

Python:
        # test to see if the door needs to be closed
        closeList = ['closed', 'broken']
        if not doorOpen and self.doorStatus not in closeList:
            self.closeDoor()
            if self.doorStatus == 'closed':
                print('closeDoor Finished')

I've attached both the python file and the Qt5 GUI file so you can test this yourself.

JT
 

Attachments

  • coop3.zip
    4.7 KB · Views: 6
Last edited:
@jthornton I click on the zip file,
but i get an "Oops... We're sorry, the page you are looking for could not be found and/or has been moved " what am i doing wrong to see/get the coop3zip file?

Maybe your connection is flaky, it works for me and I'm on SLOW Satellite.

Just testing out the final version of the basic door control...

JT
 
I should have put a ReadMe.txt file in the zip but forgot.

Copy the 3 files to your bin directory and make sure coop3 is executable then run it from a terminal. If your missing a library look in the coop3 file for the sudo apt install line for that library and run that in a terminal.

BTW, you should run the following commands in a terminal from time to time to keep everything updated.

Code:
sudo apt update
sudo apt dist-upgrade

I've been running the door control and have added light control so I'll push that to the github repo in the morning.

JT
 

New posts New threads Active threads

Back
Top Bottom