-
Notifications
You must be signed in to change notification settings - Fork 0
/
hyperpixel4-backlight
executable file
·152 lines (124 loc) · 4.24 KB
/
hyperpixel4-backlight
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
#!/usr/bin/python3
try:
import RPi.GPIO
except ModuleNotFoundError:
pass # enables testing in GH
import os.path
import argparse
import logging
import re
import subprocess
import sys
import time
import unittest
import unittest.mock
"""
command line testing
pi@pascal:~ $ raspi-gpio set 19 op dl
pi@pascal:~ $ raspi-gpio set 19 op dh
pi@pascal:~ $ DISPLAY=:0 xscreensaver-command -watch
UNBLANK Sun Oct 4 14:48:25 2020
BLANK Sun Oct 4 14:48:37 2020
...or
LOCK Tue Jan 5 14:16:38 2021
"""
def init():
RPi.GPIO.setmode(RPi.GPIO.BCM)
RPi.GPIO.setwarnings(False)
RPi.GPIO.setup(19, RPi.GPIO.OUT)
def on():
init()
RPi.GPIO.output(19, RPi.GPIO.HIGH)
def off():
init()
RPi.GPIO.output(19, RPi.GPIO.LOW)
def toggle():
init()
RPi.GPIO.output(19, not RPi.GPIO.input(19))
def not_working():
import gpiozero
screen_backlight = gpiozero.OutputDevice(pin=19, active_high=True, initial_value=None)
screen_backlight.toggle()
# this calls cleanup which restores the state after the execution is done and class is removed from memory
screen_backlight.close()
def daemon():
logging.info('Starting to listen events in XScreenSaver')
with subprocess.Popen(['xscreensaver-command', '-watch'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p:
unblank = r'^UNBLANK.*'
blank = r'^(BLANK|LOCK)+'
while True:
line = p.stdout.readline().decode('utf-8')
if not line:
break
elif re.match(blank, line):
off()
elif re.match(unblank, line):
on()
print(line.strip())
line = p.stderr.readline().decode('utf-8')
if not line:
return
else:
print(f'STDERR: { line }')
logging.info('Display is not ready. Sleeping for 5 seconds.')
time.sleep(5)
sys.exit(-1)
class TestImplementation(unittest.TestCase):
def create_patch(self, name) -> unittest.mock.MagicMock:
patcher = unittest.mock.patch(name)
thing = patcher.start()
self.addCleanup(patcher.stop)
return thing
def test_grepping(self):
readline_stdout = [
b'UNBLANK Sun Oct 4 14:48:25 2020',
b'BLANK Sun Oct 4 14:48:37 2020',
b'LOCK Tue Jan 5 14:16:38 2021',
b'',
]
readline_stderr = [
b'xscreensaver-command: can\'t open display :0.0',
b'',
]
mock_popen = self.create_patch('subprocess.Popen')
mock_popen.return_value.__enter__.return_value.stdout.readline.side_effect = readline_stdout
mock_popen.return_value.__enter__.return_value.stderr.readline.side_effect = readline_stderr
mock_off = self.create_patch('__main__.off')
mock_on = self.create_patch('__main__.on')
mock_sys = self.create_patch('sys.exit')
daemon()
assert mock_sys.call_count == 1
assert mock_on.call_count == 1
assert mock_off.call_count == 2
if __name__ == '__main__':
"""
Parses command line input and starts up a daemon process, or executes a user action.
"""
app_name = os.path.basename(__file__)
parser = argparse.ArgumentParser(prog=app_name, description='Control the hyperpixel4 backlight.')
parser.add_argument('action', choices=['on', 'off', 'daemon', 'test'], default=None)
parser.add_argument('--debug', required=False, action='store_true')
args = parser.parse_args()
if args.debug:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
logging.getLogger().handlers[0].setFormatter(
logging.Formatter('%(message)s')
)
if not os.path.isfile('/usr/bin/hyperpixel4-init') and args.action != 'test':
print('Do you really have hyperpixel4 installed in this system?')
sys.exit(-1)
if args.action == 'on':
on()
elif args.action == 'off':
off()
elif args.action == 'daemon':
try:
daemon()
except KeyboardInterrupt:
pass
elif args.action == 'test':
print('Running tests:')
runner = unittest.TextTestRunner(stream=sys.stdout)
result = runner.run(unittest.makeSuite(TestImplementation))