-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtree.py
143 lines (110 loc) · 4.16 KB
/
tree.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
from blinkstick import blinkstick
from time import sleep
from random import randint
from datetime import datetime, time, timedelta
import requests
import logging
RED = (255, 0, 0)
WHITE = (255, 255, 255)
STANDUP_TIME = time(10, 15)
def christmas_colours(max_rgb):
colours = ((max_rgb, 0, 0), (0, max_rgb, 0), (0, 0, max_rgb))
while True:
yield colours[randint(0, len(colours) - 1)]
def morph(colours, steps=100):
r_start, g_start, b_start = 0, 0, 0
for r_end, g_end, b_end in colours:
yield (r_start, g_start, b_start)
for n in range(1, steps):
d = 1.0 * n / steps
r = (r_start * (1 - d)) + (r_end * d)
g = (g_start * (1 - d)) + (g_end * d)
b = (b_start * (1 - d)) + (b_end * d)
yield (r, g, b)
r_start, g_start, b_start = r_end, g_end, b_end
def flash(colour, speed=20):
def colours():
while True:
yield 0, 0, 0
yield colour
return morph(colours(), speed)
def single_colour(colour):
while True:
yield colour
class BuildStatus(object):
def __init__(self, branch):
self.url = 'http://buildbot.eng.velocix.com/cgi-bin/results.py?page=recentbuilds&type=json&branch=%s&limit=1' % branch
self.last_poll = datetime(1970, 1, 1)
self.build_info = {}
def failing(self):
time_since_last_poll = datetime.now() - self.last_poll
if time_since_last_poll.seconds > 300:
logging.info("Polling build")
try:
response = requests.get(self.url, timeout=5)
response.raise_for_status()
self.build_info = response.json()[0]
logging.info("Build status: %s", self.build_info)
except requests.exceptions.RequestException:
logging.exception(
"Unable to connect to buildbot for build status")
self.last_poll = datetime.now()
return self.build_info.get('result', 0) != 0
class Tree(object):
def __init__(self, led_count=10, brightness=255):
self.bstick = None
self.led_count = led_count
self.colours = [morph(christmas_colours(brightness)) for _ in range(led_count)]
self.red_flash = [flash(RED) for _ in range(led_count)]
self.red = [single_colour((brightness, 0, 0)) for _ in range(led_count)]
self.white_flash = [flash(WHITE) for _ in range(led_count)]
self.alert_since = None
self.build = BuildStatus('unicorn')
def connect(self):
self.bstick = blinkstick.BlinkStickPro(r_led_count=self.led_count)
self.bstick.connect()
def alert(self):
alert_condition = self.build.failing()
if alert_condition and self.alert_since is None:
self.alert_since = datetime.now()
if not alert_condition and self.alert_since is not None:
self.alert_since = None
return alert_condition
def alert_duration(self):
if self.alert_since is None:
return timedelta()
return datetime.now() - self.alert_since
def alarm(self):
now = datetime.now().time()
alarm_active = (STANDUP_TIME.hour == now.hour and
STANDUP_TIME.minute == now.minute)
if alarm_active:
logging.warning("Alarm: Daily Stand-Up")
return alarm_active
def select_colours(self):
if self.alert():
if self.alert_duration().seconds < 10:
return self.red_flash
return self.red
if self.alarm():
return self.white_flash
return self.colours
def loop(self):
try:
while True:
colours = self.select_colours()
for index in range(self.led_count):
r, g, b = next(colours[index])
self.bstick.set_color(channel=0, index=index, r=r, g=g, b=b)
self.bstick.send_data_all()
sleep(0.05)
finally:
if self.bstick:
self.bstick.off()
def main():
logging.basicConfig(level=logging.INFO)
tree = Tree()
tree.connect()
tree.loop()
if __name__ == '__main__':
main()