-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathglobals.py
170 lines (147 loc) · 4.35 KB
/
globals.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
import ujson
import machine
import _thread
GLOBALS = {
"Alarm": {
"Enabled": 0,
"Hour": 0,
"Minute": 0,
"DurationS": 300
},
"Time": {
"Year": 2023,
"Month": 1,
"Day": 1,
"Hour": 0,
"Minutes": 0,
"Seconds": 0
},
"Buzzer": {
"Frequency": 1500,
"DutyCycle%": 50,
"BeepUnitMs": 100,
"UsePwm": 1
},
"Pins": { # These do not correspond to the schematic shown in README
"LcdIAddr": 39,
"LcdIId": 0,
"LcdIsda": 0,
"LcdIscl": 1,
"Btn0": 10,
"Btn1": 11,
"Btn2": 12,
"BuzzerData": 16
},
"Ui": {
"AlarmReps": 4,
"LockMinutes": 15,
"InputDelay": 300,
"BacklightMs": 10000,
"AlarmGraceMs": 2500
},
"Fixed": {
"LcdICols": 16,
"LcdIRows": 2,
"LcdIFreq": 400000,
"BtnPullDown": 1
}
}
# Needs to be recalculated every time the globals definition is changed
GLOBALS_PERMUTATIONS = {
"GLOBALS": [0, 5, 4, 2, 1, 3],
"Alarm": [3, 0, 1, 2],
"Time": [4, 2, 0, 3, 5, 1],
"Buzzer": [1, 0, 3, 2],
"Ui": [0, 3, 2, 1, 4]
}
RTC = machine.RTC()
GLOBALS_DIRTY = {
"Dirty": False
}
GLOBAL_LOCKS = {
"Thread": _thread.allocate_lock()
}
def read_globals():
global GLOBALS
try:
with open("globals_stored.json", "r") as globals_file:
GLOBALS = ujson.loads(globals_file.read())
return True
except:
pass # Ignore
finally:
apply_time()
return False
def store_globals():
global GLOBALS
print("Storing globals.")
with open("globals_stored.json", "w") as globals_file:
globals_file.write(ujson.dumps(GLOBALS))
""" Reorders GLOBALS for a better UX (hardcoded) """
def permutate_list(name, key_list):
key_list_len = len(key_list)
if not (name in GLOBALS_PERMUTATIONS) or key_list_len == 0: return key_list
permutations = GLOBALS_PERMUTATIONS[name]
result = [None] * key_list_len
for source_index, target_index in enumerate(permutations):
if source_index < key_list_len and target_index < key_list_len:
result[target_index] = key_list[source_index]
for i, item in enumerate(result):
if item == None:
result[i] = key_list[i]
return result
def weekDay(year, month, day):
offset = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
afterFeb = 1
if month > 2: afterFeb = 0
aux = year - 1700 - afterFeb
# dayOfWeek for 1700/1/1 = 5, Friday
dayOfWeek = 5
# partial sum of days betweem current date and 1700/1/1
dayOfWeek += (aux + afterFeb) * 365
# leap year correction
dayOfWeek += aux / 4 - aux / 100 + (aux + 100) / 400
# sum monthly and day offsets
dayOfWeek += offset[month - 1] + (day - 1)
dayOfWeek %= 7
return int(dayOfWeek // 1)
def update_time():
current_time = RTC.datetime()
GLOBALS["Time"]["Year"] = current_time[0]
GLOBALS["Time"]["Month"] = current_time[1]
GLOBALS["Time"]["Day"] = current_time[2]
GLOBALS["Time"]["Hour"] = current_time[4]
GLOBALS["Time"]["Minutes"] = current_time[5]
GLOBALS["Time"]["Seconds"] = current_time[6]
def apply_time():
weekday = weekDay(GLOBALS["Time"]["Year"], GLOBALS["Time"]["Month"], GLOBALS["Time"]["Day"])
RTC.datetime((GLOBALS["Time"]["Year"], GLOBALS["Time"]["Month"], GLOBALS["Time"]["Day"], weekday, GLOBALS["Time"]["Hour"], GLOBALS["Time"]["Minutes"], GLOBALS["Time"]["Seconds"], 0))
def get_time():
return (GLOBALS["Time"]["Year"], GLOBALS["Time"]["Month"], GLOBALS["Time"]["Day"], GLOBALS["Time"]["Hour"], GLOBALS["Time"]["Minutes"], GLOBALS["Time"]["Seconds"])
def get_now_alarm_minutes():
alarm_hour = GLOBALS["Alarm"]["Hour"]
alarm_minute = GLOBALS["Alarm"]["Minute"]
now_time = get_time()
now_hour = now_time[3]
now_minute = now_time[4]
alarm_minutes = 60 * alarm_hour + alarm_minute
now_minutes = 60 * now_hour + now_minute
return (now_minutes, alarm_minutes)
def index_for_key(the_list, list_name, the_key):
keys = permutate_list(list_name, list(the_list.keys()))
for idx, key in enumerate(keys):
if key == the_key:
return idx
return -1
""" Return a next-state with queue. Keys is in format [(category_key, value_key)] """
def orchestrate_write_ui(keys, withDirty=True):
if len(keys) == 0:
return ["idle"]
keys = list(map(lambda x: (x[0], index_for_key(GLOBALS[x[0]], x[0], x[1])), keys))
first_el = keys.pop(0)
keys.append(None) # type: ignore
return ["write", first_el[0], first_el[1], keys, withDirty]
def toggle_alarm(on, withDirty=True):
GLOBALS["Alarm"]["Enabled"] = 1 if on else 0
if withDirty: # Disable dirty to prevent excessive writes damaging the flash
GLOBALS_DIRTY["Dirty"] = True