-
Notifications
You must be signed in to change notification settings - Fork 1
/
runshow.py
163 lines (130 loc) · 4.27 KB
/
runshow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
"""
Show Runner script for the PiLit holiday lighting controller
Author: Tim Poulsen, @skypanther
License: MIT
This script runs on your Raspberry Pi, reads in a show.json
file, and turns on/off the relays to perform your show.
Setup:
1. Make sure you have gpiozero installed on your Pi with:
> sudo apt-get update
> sudo apt-get install python3-gpiozero python-gpiozero
2. Update the gpio_pins list below with the pin numbers you're
using on your Pi. If you're using less than 16 pins, simply
delete any extra numbers from the sample line below.
NOTE: You must use the BCM (Broadcom) numbers for the pins
and NOT their physical pin numbers!
3. Run it (manually or from cron) with a command in the form:
> python3 runshow.py show.json HH:MM
where show.json is the name of your show file (in same
directory as this file) and HH:MM is the hours and minutes
of when to end the show.
For example:
> python3 runshow.py show.json 22:30
Runs the show.json show till 10:30 PM tonight.
"""
import sys
from datetime import datetime
from time import sleep
import json
import os.path
from gpiozero import LED
# CONFIGURE THESE VARIABLES TO SUIT YOUR ACTUAL SETUP
# USE BCM (BROADCOM) NOT PHYSICAL PIN NUMBERS
# don't use GPIO 14 / pin 8 on a Pi B+ as it's the "hard drive light" pin
gpio_pins = [2, 3, 4, 7, 15, 17, 18, 27, 22, 23, 24, 10, 9, 25, 11, 8]
# board_pins 3, 5, 7, 26, 10, 11, 12, 13, 15, 16, 18, 19, 21, 22, 23, 24
# DON'T CHANGE THESE VARIABLES
midnight = datetime.today().replace(hour=23, minute=59, second=59, microsecond=999999)
args = sys.argv[1:]
pins = []
def main():
if len(args) == 0:
# prompt for show name, duration
show_name = input("Enter the show name: ")
the_time = input("When should the show end? (time as HH:MM):")
if "." not in show_name:
show_name += ".json"
if the_time == "":
end_time = midnight
else:
end_time = format_end_time(the_time)
elif len(args) == 1 and args[0] == "off":
# turn all lights off then exit
all_off()
exit()
elif len(args) == 1 and args[0] == "on":
# turn all lights on then exit
all_on()
exit()
elif len(args) == 1:
show_name = args[0]
end_time = midnight
if "." not in show_name:
show_name += ".json"
else:
show_name = args[0]
end_time = format_end_time(args[1])
if "." not in show_name:
show_name += ".json"
if not os.path.isfile(show_name):
print("No show file by that name")
exit()
run_show(show_name, end_time)
def run_show(show_name, end_time):
# Runs the actual show
with open(show_name) as json_file:
show_file = json.load(json_file)
if "show" not in show_file:
print("Bad show file")
exit()
show = show_file["show"]
delay = show_file["interval"] if "interval" in show_file else 500
delay = delay / 1000.0
now = datetime.now()
while now < end_time:
for channel in show:
control_channel(channel)
sleep(delay)
now = datetime.now()
def format_end_time(the_time):
# Formats an HH:MM time string into an actual datetime
input_time = the_time.split(":")
end_time = datetime.today().replace(
hour=int(input_time[0]), minute=int(input_time[1])
)
return end_time
def all_on():
# Turns on all relays
for pin in pins:
pin.on()
def all_off():
# Turns off all relays
for pin in pins:
pin.off()
def control_channel(channel):
"""
Turns on or off the relays for a specific channel in the show file
"""
if len(channel) != len(pins):
msg = """
Error:
You must make sure the number of items in the gpio_pins
list in runshow.py is the same as each channel in the show
list defined in your show.json file
"""
sys.exit(msg)
for index, relay_state in enumerate(channel):
if relay_state == 1:
pins[index].off()
else:
pins[index].on()
def setup_pins():
"""
Creates the LED instances for each of the pins to which
you have relays connected and stores them in the pins list
"""
for pin_number in gpio_pins:
pins.append(LED(pin_number))
if __name__ == "__main__":
setup_pins()
main()