-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
159 lines (139 loc) · 4.89 KB
/
main.py
File metadata and controls
159 lines (139 loc) · 4.89 KB
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
import os
import re
import sys
import tempfile
from datetime import timedelta
from os import path
from random import choice
from Mplayer import Mplayer
__all__ = "alarm"
__author__ = "Elias Keis"
__version_info__ = (0, 1)
__version__ = "{0}.{1}".format(*__version_info__)
__license__ = "GNU General Public License v3 (GPLv3)"
# noinspection PyUnresolvedReferences
def add_gpio_listener(pin_nr, callback, bounce_time=200):
try:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin_nr, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(pin_nr, GPIO.FALLING, callback=callback, bouncetime=bounce_time)
except RuntimeError:
print_help("Failed to add pin listener, are we on an Raspberry Pi? If not, use --no-gpio!")
return
def parse_time(time_str):
regex = re.compile(r'((?P<hours>\d+?)hr)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?')
parts = regex.match(time_str)
if not parts:
return
parts = parts.groupdict()
time_params = {}
for (name, param) in parts.items():
if param:
time_params[name] = int(param)
return timedelta(**time_params)
def print_help(error: str = "") -> None:
if not error == "":
print(error + "\n")
print("Plays a sound for given time. Can stop playing when getting an event from GPIO pins.\n\n" +
"Parameters (all optional):\n" +
"--version\t-v\tprint version\n" +
"--help\t\t-h\tprint this message\n" +
"--song <s>\t-s <s>\tplays sound from file stored at <s>\n" +
"--playlist <p>\t-p <p>\tplays random sound from playlist stored at <p>\n" +
"--duration <t>\t-d <t>\thow long the song is played (default 5min).\n" +
"\t\t\tExamples: 5s, 3h:4min:2s, ...\n" +
"--no-gpio\t\tDisables GPIO-Pins\n" +
"--pin <p>\t-p <p>\tNumber of the GPIO-Pin to use")
def songs_in_playlist(playlist):
songs = []
with open(playlist) as f:
for line in f.readlines():
song = line.strip()
if not path.isabs(song):
song = path.join(path.dirname(playlist), song)
songs.append(song)
return songs
def main() -> None:
args = sys.argv
args.pop(0)
alarm_sounds = []
alarm_duration = timedelta(minutes=5)
no_gpio = False
pin_nr = 7
cur_arg_i = 0
while cur_arg_i < len(args):
cur_arg = args[cur_arg_i]
cur_arg_i += 1
if cur_arg == "--version" or cur_arg == "-v":
print("Version: %s" % __version__)
return
elif cur_arg == "--help" or cur_arg == "-h":
print_help()
return
elif cur_arg == "--song" or cur_arg == "-s":
if cur_arg_i >= len(args):
print_help("Missing argument: song file")
return
else:
alarm_sounds.append(args[cur_arg_i])
cur_arg_i += 1
elif cur_arg == "--playlist" or cur_arg == "-p":
if cur_arg_i >= len(args):
print_help("Missing argument: playlist file")
return
else:
alarm_playlist = args[cur_arg_i]
cur_arg_i += 1
try:
alarm_sounds.extend(songs_in_playlist(alarm_playlist))
except IOError:
print_help("Invalid playlist file")
elif cur_arg == "--duration" or cur_arg == "-d":
if cur_arg_i >= len(args):
print_help("Missing argument: duration")
return
else:
alarm_duration = parse_time(args[cur_arg_i])
cur_arg_i += 1
elif cur_arg == "--no-gpio":
no_gpio = True
elif cur_arg == "--pin" or cur_arg == "-p":
if cur_arg_i >= len(args):
print_help("Missing argument: pin number")
return
else:
pin_nr = int(args[cur_arg_i])
cur_arg_i += 1
else:
print_help("Unknown parameter '%s'" % cur_arg)
return
if len(alarm_sounds) < 1:
print_help("You should provide at least one song or playlist file")
return
alarm_sound = choice(alarm_sounds)
pipe_dir = tempfile.mkdtemp("", "AlarmMPlayerPipe")
pipe_file = os.path.join(pipe_dir, "pipe")
player = Mplayer()
player.start(alarm_sound, alarm_duration)
if not no_gpio:
def got_pin_input(changed_pin):
if changed_pin == pin_nr:
player.stop()
add_gpio_listener(pin_nr, got_pin_input)
try:
import time
while player.running:
time.sleep(1)
except KeyboardInterrupt:
player.stop()
try:
os.remove(pipe_file)
except OSError:
pass # file did not exist
try:
os.rmdir(pipe_dir)
except OSError:
pass # dir did not exist
if __name__ == "__main__":
main()