-
Notifications
You must be signed in to change notification settings - Fork 0
/
lcdui.py
197 lines (158 loc) · 5.53 KB
/
lcdui.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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/python
# -*- coding: utf-8 -*-
import curses
from threading import Timer
from datetime import timedelta, datetime, time
from lib.libhue import modify_temperature, modify_brightness, set_state, toggle
from presets import turn_off_after, show_preset
import settings
from lib.net import wait_until_network, get_ip_address
stdscr = None
try:
from lib.Adafruit_CharLCDPlate import Adafruit_CharLCDPlate as LCD
# Initialize the LCD plate. Should auto-detect correct I2C bus. If not,
# pass '0' for early 256 MB Model B boards or '1' for all later versions
lcd = LCD()
except ImportError:
lcd = None
def _t(s, l):
return unicode(s).ljust(l)[:l]
# ╔════════════════╗
# ║20:08 a06:00 10m║
# ║b100% Showers ║
# ╚════════════════╝
BACKLIGHT_TIMER = None
def display_message(msg, colour="GREEN"):
global stdscr
if lcd:
global BACKLIGHT_TIMER
lcd.clear()
lcd.backlight(getattr(lcd, colour))
lcd.message(msg)
if BACKLIGHT_TIMER and BACKLIGHT_TIMER.is_alive():
BACKLIGHT_TIMER.cancel()
BACKLIGHT_TIMER = Timer(2, lcd.backlight, (lcd.OFF, ))
BACKLIGHT_TIMER.start()
if stdscr:
lines = msg.split("\n")[:2]
if len(lines) < 2:
lines.append("")
stdscr.addstr(0, 0, "-"*18)
for i, line in enumerate(lines):
stdscr.addstr(i+1, 0, "|%s|" % _t(line,16))
stdscr.addstr(3, 0, "-"*18)
class Status(object):
def __init__(self):
self.next_alarm = None
self.turn_off = 0
self.brightness = 0
self.weather = ""
def display(self, line1=None, line2=None, colour="GREEN"):
if line1 is None:
formatted_time = unicode(datetime.now().time())
if self.turn_off:
if self.turn_off >= 3660:
formatted_turn_off = "%sh" % int(round(self.turn_off/3600))
elif self.turn_off >= 60:
formatted_turn_off = "%sm" % int(round(self.turn_off/60))
else:
formatted_turn_off = "%ss" % int(self.turn_off)
else:
formatted_turn_off = ""
if self.next_alarm:
line1 = "%s a%s %s" % (_t(formatted_time,5), _t(self.next_alarm.time(), 5), _t(formatted_turn_off, 3))
else:
line1 = "%s xx:xx %s" % (_t(formatted_time,5), _t(formatted_turn_off, 3))
if line2 is None:
formatted_brightness = unicode(int(round(self.brightness * 100)))
line2 = "%s%% %s" % (_t(formatted_brightness, 3), _t(self.weather, 11))
display_message("%s\n%s" % (line1, line2), colour)
STATUS = Status()
def adjust_brightness(amount):
b = [modify_brightness(B, amount) for B in settings.BULBS]
STATUS.brightness = (float(sum(b))/len(b))/255.0
def adjust_temperature(amount):
t = [modify_temperature(B, amount) for B in settings.BULBS]
TURNOFF_TIME = None
def adjust_turnoff(d):
global TURNOFF_TIME
[set_state(B, {'on': True }) for B in settings.BULBS]
if settings.DEBUG:
diff = timedelta(seconds=d)
else:
diff = timedelta(minutes=d)
if TURNOFF_TIME:
TURNOFF_TIME += diff
else:
TURNOFF_TIME = datetime.now() + diff
time_to_go = (TURNOFF_TIME - datetime.now()).total_seconds()
[turn_off_after(B, time_to_go) for B in settings.BULBS]
STATUS.turn_off = time_to_go
def _clear_clock():
global TURNOFF_TIME
TURNOFF_TIME = None
t = Timer(time_to_go, _clear_clock)
t.start()
def start_ui():
global turnoff_time
global stdscr
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.keypad(1)
curses.curs_set(0) #invisible cursor
"""
Keypad:
91 32 93
27 UP 113
LT 10 RT
48 DN 127
49 50 51
52 53 54
55 56 57
"""
try:
while True:
charcode = stdscr.getch()
try:
char = chr(charcode)
except ValueError:
char = None
if charcode in [ord('x')]:
[show_preset('off', B) for B in settings.BULBS]
display_message("All off.")
# exit()
elif char == '1':
[show_preset('relax', B) for B in settings.BULBS]
elif char == '2':
[show_preset('sunrise', B) for B in settings.BULBS]
elif char == '3':
[show_preset('reading', B) for B in settings.BULBS]
elif charcode == curses.KEY_UP:
adjust_brightness(+26)
elif charcode == curses.KEY_DOWN:
adjust_brightness(-26)
elif charcode == curses.KEY_LEFT:
adjust_temperature(-35)
elif charcode == curses.KEY_RIGHT:
adjust_temperature(35)
elif charcode == 91:
adjust_turnoff(-5)
elif charcode == 93:
adjust_turnoff(5)
elif char == ' ':
[toggle(B) for B in settings.BULBS]
if charcode and char != '9':
STATUS.display()
stdscr.refresh()
finally:
curses.nocbreak()
stdscr.keypad(0)
curses.echo()
curses.endwin()
if __name__ == "__main__":
display_message("waiting for\nnetwork...", "RED")
wait_until_network()
host_ip = get_ip_address()
display_message("connected:\n%s" % host_ip, "VIOLET")
start_ui()