0

So I'm trying to make a timer script that will run one relay (on/off) at a given time everyday, then the other seven to perform a function over time or (once started) to be interrupted by a switch being flipped. I tried learning python over the last several weeks and I seem to be having trouble grasping it.

I came across some pre-built scripts and have gotten a beginner's level understanding.

I am not looking for someone to build me a script (although it would be amazing). I simply want to know why this one isn't working.

    # Raspberry Pi custom appliance timer

    # import GPIO module
    import RPi.GPIO as GPIO


    # set up GPIO pins as outputs
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Button
    GPIO.setup(21, GPIO.OUT) # Appliance 5/25 volt relay
    ##GPIO.setup(24, GPIO.OUT)# LED
    state = 0
    button = GPIO.input(25)


    # import date and time modules
    import datetime
    import time

    # Enter the times you want the appliance to turn on and off for
    # each day of the week.

    MonAMOn  = datetime.time(hour=5)
    #MonAMOff = datetime.time(hour=7)
    #MonPMOn  = datetime.time(hour=16)
    MonPMOff = datetime.time(hour=22)
    TueAMOn  = datetime.time(hour=5)
    #TueAMOff = datetime.time(hour=7)
    #TuePMOn  = datetime.time(hour=16)
    TuePMOff = datetime.time(hour=22)
    WedAMOn  = datetime.time(hour=5)
    #WedAMOff = datetime.time(hour=7)
    #WedPMOn  = datetime.time(hour=16)
    WedPMOff = datetime.time(hour=22)
    ThuAMOn  = datetime.time(hour=5)
    #ThuAMOff = datetime.time(hour=7)
    #ThuPMOn  = datetime.time(hour=16)
    ThuPMOff = datetime.time(hour=22)
    FriAMOn  = datetime.time(hour=5)
    #FriAMOff = datetime.time(hour=7)
    #FriPMOn  = datetime.time(hour=16)
    FriPMOff = datetime.time(hour=22)
    SatAMOn  = datetime.time(hour=5)
    #SatAMOff = datetime.time(hour=7)
    #SatPMOn  = datetime.time(hour=16)
    SatPMOff = datetime.time(hour=22)
    SunAMOn  = datetime.time(hour=5)
    #SunAMOff = datetime.time(hour=7)
    #SunPMOn  = datetime.time(hour=16)
    SunPMOff = datetime.time(hour=22)

    # Store these times in an array for easy access later.
    OnTimeAM = [MonAMOn, TueAMOn, WedAMOn, ThuAMOn, FriAMOn, SatAMOn,               SunPMOn]
    OnTimePM = [MonPMOn, TuePMOn, WedPMOn, ThuPMOn, FriPMOn, SatPMOn, SunPMOn]
    OffTimeAM = [MonAMOff, TueAMOff, WedAMOff, ThuAMOff, FriAMOff, SatAMOff, SunAMOff]
    OffTimePM = [MonPMOff, TuePMOff, WedPMOff, ThuPMOff, FriPMOff, SatPMOff, SunAMOff]


    # Start the loop that will run until you stop the program or turn off your Raspberry Pi.

    while True:
button = GPIO.input(25)
print("Override")
global state
if button == 0:
    #print('button', button)
    state = 1
    print('State', state)
if state == 1:
    time.sleep(0.5)
    #GPIO.output(24, True)
    GPIO.output(21, True)
    time.sleep(3600) #3600
    state = 0
    #GPIO.output(24, False)
    GPIO.output(21, False)



        # get the current time in hours, minutes and seconds
        currTime = datetime.datetime.now()
        print(currTime)
        # get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
        currDay = datetime.date.today().weekday()

            #Check to see if it's time to run the appliance for the AM hours
        while (currTime.hour >= OnTimeAM[currDay].hour and currTime.hour <=                 OffTimeAM[currDay].hour):
            # set the GPIO pin to HIGH
            #GPIO.output(24, True)
    GPIO.output(21, True)
time.sleep(60)
    currTime = datetime.datetime.now()
    currDay = datetime.date.today().weekday()

else:
    if (currTime.hour >= OffTimeAM[currDay].hour - 1):
        #GPIO.output(24, False)
        GPIO.output(21, False)



#Check to see if it's time to run the appliance for the PM hours
while (currTime.hour >= OnTimePM[currDay].hour and currTime.hour <= OffTimePM[currDay].hour):
    #GPIO.output(24, True)
    GPIO.output(21, True)
time.sleep(60)
    currDay = datetime.date.today().weekday()
    currTime = datetime.datetime.now()
else:
    if (currTime.hour >= OffTimePM[currDay].hour - 1):
        #GPIO.output(24, False)
        GPIO.output(21, False)
  • 1
    Unfortunately formatting is very important in the Python language. Spaces are used to define the scope of loops etc. You will need to correct the script formatting as at the moment the script is invalid and will not run and makes no sense. – joan Nov 2 '18 at 22:22
  • 1
    "isn't working" is not particularly helpful. WHAT does it do? What is connected? Did you test hardware BEFORE writing this massive chunk of code. NOTE cron is a much better way of running regular tasks. – Milliways Nov 3 '18 at 0:48
1

I think this might be what you want. Try it out and ask me if you have any questions, and make sure you look at all the comments I made so you can learn what you did wrong.

# Raspberry Pi custom appliance timer

# This looks good, I just fixed a little white spacing (indentation, spaces, etc.) and a few other issues. 
# Make sure you look at all the comments I made, and I hope this helps.

# import GPIO module
import RPi.GPIO as GPIO


# set up GPIO pins as outputs
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Button
GPIO.setup(21, GPIO.OUT) # Appliance 5/25 volt relay
##GPIO.setup(24, GPIO.OUT)# LED
state = 0 # Do you need this variable???
button = GPIO.input(25)


# import date and time modules
import datetime
import time

# Enter the times you want the appliance to turn on and off for
# each day of the week.

MonAMOn  = datetime.time(hour=5)
#MonAMOff = datetime.time(hour=7)
#MonPMOn  = datetime.time(hour=16)
MonPMOff = datetime.time(hour=22)
TueAMOn  = datetime.time(hour=5)
#TueAMOff = datetime.time(hour=7)
#TuePMOn  = datetime.time(hour=16)
TuePMOff = datetime.time(hour=22)
WedAMOn  = datetime.time(hour=5)
#WedAMOff = datetime.time(hour=7)
#WedPMOn  = datetime.time(hour=16)
WedPMOff = datetime.time(hour=22)
ThuAMOn  = datetime.time(hour=5)
#ThuAMOff = datetime.time(hour=7)
#ThuPMOn  = datetime.time(hour=16)
ThuPMOff = datetime.time(hour=22)
FriAMOn  = datetime.time(hour=5)
#FriAMOff = datetime.time(hour=7)
#FriPMOn  = datetime.time(hour=16)
FriPMOff = datetime.time(hour=22)
SatAMOn  = datetime.time(hour=5)
#SatAMOff = datetime.time(hour=7)
#SatPMOn  = datetime.time(hour=16)
SatPMOff = datetime.time(hour=22)
SunAMOn  = datetime.time(hour=5)
#SunAMOff = datetime.time(hour=7)
#SunPMOn  = datetime.time(hour=16)
SunPMOff = datetime.time(hour=22)

# Store these times in an array for easy access later.
OnTimeAM = [MonAMOn, TueAMOn, WedAMOn, ThuAMOn, FriAMOn, SatAMOn,               SunPMOn]
OnTimePM = [MonPMOn, TuePMOn, WedPMOn, ThuPMOn, FriPMOn, SatPMOn, SunPMOn]
OffTimeAM = [MonAMOff, TueAMOff, WedAMOff, ThuAMOff, FriAMOff, SatAMOff, SunAMOff]
OffTimePM = [MonPMOff, TuePMOff, WedPMOff, ThuPMOff, FriPMOff, SatPMOff, SunAMOff]


# Start the loop that will run until you stop the program or turn off your Raspberry Pi.

# You are good up until here. Make sure you always get your whitespacing (indentation, spaces, etc.) correct, because python is very picky about it!

while True:
    # you do not need "global state" because because this while loop is technically still in the global context.
    # only use the "global" keyword within functions.
    button = GPIO.input(25)
    print("Override") # Do you really want this? It will be constantly printing "Override" whenever the appliance is not on.

    # For this next part, I'm not exactly sure what you want it to do:
    # When the button is pressed or depressed (depending on your circuit), this will turn on your appliance for 3600 seconds before resuming normal operation:
    # Is that what you want?
    if button == 0:
        #print('button', button)
        state = 1
        print('State', state)
    if state == 1:
        time.sleep(0.5)
        #GPIO.output(24, True)
        GPIO.output(21, True)
        time.sleep(3600) #3600
        state = 0
        #GPIO.output(24, False)
        GPIO.output(21, False)



    # get the current time in hours, minutes and seconds
    currTime = datetime.datetime.now()
    print(currTime)
    # get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
    currDay = datetime.date.today().weekday()

    #Check to see if it's time to run the appliance for the AM hours
    while currTime.hour >= OnTimeAM[currDay].hour and currTime.hour <= OffTimeAM[currDay].hour: # You don't need parenthesis in python
        # set the GPIO pin to HIGH
        #GPIO.output(24, True)
        GPIO.output(21, True)
        time.sleep(60)
        currTime = datetime.datetime.now()
        currDay = datetime.date.today().weekday()
    GPIO.output(21, False) # put this here so that as soon as it's time to shutdown, it turns off the appliance



    #Check to see if it's time to run the appliance for the PM hours
    while currTime.hour >= OnTimePM[currDay].hour and currTime.hour <= OffTimePM[currDay].hour: # No parenthesis
        #GPIO.output(24, True)
        GPIO.output(21, True)
        time.sleep(60)
        currDay = datetime.date.today().weekday()
        currTime = datetime.datetime.now()
    GPIO.output(24, False) # Don't use an "else" with a "while"! The while will only move on once it's time to shutdown and then this line will run, shutting down the relay.

Also, keep in mind what @Milliways mentions: Cron is a much better method for scheduling tasks on the raspberry pi. A very short tutorial can be found here

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.