-
Notifications
You must be signed in to change notification settings - Fork 0
/
handheld_night_light.py
157 lines (115 loc) · 4.42 KB
/
handheld_night_light.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
#Copyright Thomas TEMPE 2020
#DWTFYL License
#INSTRUCTIONS:
#set the desired on/off hours in self.times
#set your WIFI password in do_connect_tt.py
#set the pins here, as well as in main.py
neopixel_data_pin = 12
button_pin_1 = 25
button_pin_2 = 26
#set your timezone here:
GMT=0
timezone = GMT+8
#see my instructions for building the whole device on Instructables.com
import time
import machine
import network
from machine import Pin
from neopixel import NeoPixel
import math
import micropython
micropython.alloc_emergency_exception_buf(100) #for catching exceptions in the interrupt callback
red = (25, 0, 0)
yellow = (50, 50, 0)
night_light = (200,100,0)
white = (150, 200, 255)
green = (0,255,0)
blue = (0,0,255)
off = (0,0,0)
rtc = machine.RTC()
def localtime():
'Returns the time of day, as a float representing the number of hours'
return (rtc.datetime()[4]+timezone)%24+rtc.datetime()[5]/60
def dim(color, k):
"apply a coefficient to a light triplet"
a, b, c = color
return ( round(a*k), round(b*k), round(c*k))
class Flashing_lights:
'Controls two neopixels that flash continuously'
def __init__(self, neopixel_pin):
self.n = NeoPixel(Pin(neopixel_pin, Pin.OUT),2)
self.n[0]=(0,0,0)
self.n[1]=(0,0,0)
self.n.write()
self.brightness_max = 1
self.brightness_min = .03
self.color = (100,0,0)
self.progress=0
self.epoch = time.ticks_ms()
self.breath = 27
def set_color(self, color, brightness_min=0.03):
self.color = color
self.epoch = localtime()
self.brightness_min=brightness_min
def loop(self):
k = ((math.cos((time.ticks_ms()-self.epoch)/450)+1)/2.8)*(self.brightness_max-self.brightness_min)+self.brightness_min
self.n[1]=self.n[0]=dim(self.color, k)
self.n.write()
class Handheld_night_light:
def __init__(self, button_in_pin, button_pw_pin, fl):
self.interrupted=0
self.fl = fl
self.light_sustain_duration = 10*60*1000 #milliseconds
self.light_fade_duration = 15*60*1000
self.light_fade_coeff = float(red[0])/night_light[0]
self.LED = Pin(2, Pin.OUT)
#until 7AM, flash red, with minimum coef of 0.03; when presses, turn to night_light for 25 minutes
self.times = [(7, red, 0.03, night_light, 25),
(8, yellow, 0.2, off, 120),
(9, white, 0.4, off, 60),
(20, off, 0, red, 1),
(20+55/60, yellow, 0.2, red, 60),
(25,red, 0.03, night_light, 25)]
#Push button setup
self.pw_pin=Pin(button_pw_pin, Pin.OUT) #drain
self.pw_pin.value(0)
self.button_pin = Pin(button_in_pin, Pin.IN, Pin.PULL_UP) #read button state
self.button_pin.irq(trigger=Pin.IRQ_FALLING, handler=self.button_callback)
def button_callback(self, p):
self.interrupted = 1
#self.LED.value(not self.LED.value())
def light(self, color, how_long):
"turn on the light mode. Returns when the light is turned off"
self.fl.set_color(color, .4)
self.light_sustain_duration=how_long*.4*60*1000
self.light_fade_duration=how_long*.6*60*1000
start = time.ticks_ms()
time.sleep_ms(200)#debounce
duration = 0
while((not self.interrupted) and (duration < self.light_sustain_duration+self.light_fade_duration)):
duration = time.ticks_ms()-start
if duration > self.light_sustain_duration: #fade-out
k = (self.light_fade_duration-(duration-self.light_sustain_duration))/(self.light_fade_duration)*(1-self.light_fade_coeff)+self.light_fade_coeff
self.fl.set_color(dim(color, k))
self.fl.loop()
print("light off")
self.interrupted=0
time.sleep_ms(200)#debounce
return
def loop(self):
for t, c, k, cc, hl in self.times:
if t>localtime():
# print(t, ">", localtime(), "=> ", c, cc)
if self.interrupted:
print("light on")
self.interrupted=0
self.light(cc, hl)
else:
self.fl.set_color(c, k)
break
self.fl.loop()
fl = Flashing_lights(neopixel_data_pin)
hnl = Handheld_night_light(button_pin_1, button_pin_2,fl)
while(1):
hnl.loop()
time.sleep_ms(50)