Skip to content

Commit e535046

Browse files
committed
Initial version of new API
1 parent cf9966c commit e535046

File tree

3 files changed

+327
-166
lines changed

3 files changed

+327
-166
lines changed

esp32/modules/appglue.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ def start_ota():
2121
esp.rtcmem_write(1,254)
2222
deepsleep.reboot()
2323

24-
def start_bpp():
24+
def start_bpp(duration):
25+
print("[BPP] Duration = "+str(duration))
2526
esp.rtcmem_write(0,2)
2627
esp.rtcmem_write(1,253)
2728
deepsleep.reboot()

esp32/modules/services.py

Lines changed: 213 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,232 @@
1-
import uos
2-
31
# File: services.py
2+
# Version: 2
3+
# API version: 1
44
# Description: Background services for SHA2017 badge
55
# License: MIT
66
# Authors: Renze Nicolai <renze@rnplus.nl>
77
# Thomas Roos <?>
88

9-
def setup():
9+
import uos, ujson, easywifi, easyrtc, time, appglue, deepsleep, ugfx, badge
10+
11+
services = [] #List containing all the service objects
12+
loopCallbacks = {} #Dict containing: {<FUNCTION>:<Wifi required on next run>}
13+
drawCallbacks = [] #List containing draw functions
14+
15+
def setup(pmCb=False, drawCb=False):
1016
global services
17+
global loopCallbacks
18+
global drawCallbacks
19+
20+
if pmCb:
21+
print("[SERVICES] Power management callback registered")
22+
global pmCallback
23+
pmCallback = pmCb
24+
25+
if drawCb:
26+
print("[SERVICES] Draw callback registered")
27+
global drawCallback
28+
drawCallback = drawCb #This might need a better name...
29+
30+
# Status of wifi
31+
wifiFailed = False
32+
33+
#Check if lib folder exists and get application list, else stop
1134
try:
1235
apps = uos.listdir('lib')
1336
except OSError:
14-
print("[SERVICES] Can't setup services: no lib folder!")
15-
return False
16-
found = False
37+
return [False, False]
38+
39+
#For each app...
1740
for app in apps:
41+
print("APP: "+app)
1842
try:
19-
files = uos.listdir('lib/'+app)
20-
except OSError:
21-
print("[SERVICES] Listing app files for app '"+app+"' failed!")
22-
23-
for f in files:
24-
if (f=="service.py"):
25-
found = True
26-
print("[SERVICES] Found service "+app+"...")
27-
try:
28-
srv = __import__('lib/'+app+'/service')
29-
services.append(srv) #Add to global list
30-
srv.setup()
31-
except BaseException as msg:
32-
print("Exception in service setup "+app+": ", msg)
33-
break
34-
return found
43+
#Try to open and read the json description
44+
fd = open('/lib/'+app+'/service.json')
45+
description = ujson.loads(fd.read())
46+
fd.close()
47+
except:
48+
print("[SERVICES] No description found for "+app)
49+
continue #Or skip the app
50+
51+
print("DESC FOUND FOR: "+app)
52+
53+
try:
54+
#Try to open the service itself
55+
fd = open('/lib/'+app+'/service.py')
56+
fd.close()
57+
except:
58+
print("[SERVICES] No script found for "+app)
59+
continue #Or skip the app
60+
61+
print("SCRIPT FOUND FOR: "+app)
62+
63+
rtcRequired = False # True if RTC should be set before starting service
64+
loopEnabled = False # True if loop callback is requested
65+
drawEnabled = False # True if draw callback is requested
66+
67+
wifiInSetup = False # True if wifi needed in setup
68+
wifiInLoop = False # True if wifi needed in loop
69+
70+
try:
71+
if description['apiVersion']!=1:
72+
print("[SERVICES] Service for "+app+" is not compatible with current firmware")
73+
continue #Skip the app
74+
wifiInSetup = description['wifi']['setup']
75+
wifiInLoop = description['wifi']['setup']
76+
rtcRequired = description['rtc']
77+
loopEnabled = description['loop']
78+
drawEnabled = description['draw']
79+
except:
80+
print("[SERVICES] Could not parse description of app "+app)
81+
continue #Skip the app
82+
83+
print("[SERVICES] Found service for "+app)
84+
85+
# Import the service.py script
86+
try:
87+
srv = __import__('lib/'+app+'/service')
88+
except:
89+
print("[SERVICES] Could not import service of app "+app)
90+
continue #Skip the app
91+
92+
if wifiInSetup:
93+
if wifiFailed:
94+
print("[SERVICES] Service of app "+app+" requires wifi and wifi failed so the service has been disabled.")
95+
continue
96+
if not easywifi.status():
97+
if not easywifi.enable():
98+
wifiFailed = True
99+
print("[SERVICES] Could not connect to wifi!")
100+
continue # Skip the app
35101

36-
def loop(lcnt):
37-
noSleep = False
38-
global services
39-
for srv in services:
102+
if rtcRequired and time.time() < 1482192000:
103+
if not wifiFailed:
104+
print("[SERVICES] RTC required, configuring...")
105+
easyrtc.configure()
106+
else:
107+
print("[SERVICES] RTC required but not available. Skipping service.")
108+
continue # Skip the app (because wifi failed and rtc not available)
109+
110+
try:
111+
srv.setup()
112+
except BaseException as msg:
113+
print("[SERVICES] Exception in service setup "+app+": ", msg)
114+
continue
115+
116+
if loopEnabled:
117+
try:
118+
loopCallbacks[srv.loop] = 0
119+
except:
120+
print("[SERVICES] Loop requested but not defined in service "+app)
121+
122+
if drawEnabled and drawCb:
123+
try:
124+
drawCallbacks[srv.draw] = 0
125+
except:
126+
print("[SERVICES] Draw requested but not defined in service "+app)
127+
128+
# Add the script to the global service list
129+
services.append(srv)
130+
131+
# Create loop timer
132+
hasLoopTimer = False
133+
global loopTimer
134+
if len(loopCallbacks)>0:
135+
print("[SERVICES] There are loop callbacks, starting loop timer!")
136+
loopTimer = machine.Timer(0) #TODO: how to get this number?!?
137+
loop_timer_callback(loopTimer)
138+
hasLoopTimer = True
139+
140+
# Create draw timer
141+
hasDrawTimer = False
142+
global drawTimer
143+
if len(drawCallbacks)>0 and drawCb:
144+
print("[SERVICES] There are draw callbacks, starting draw timer!")
145+
drawTimer = machine.Timer(1) #TODO: how to get this number?!?
146+
draw_timer_callback(drawTimer)
147+
hasDrawTimer = True
148+
return [hasLoopTimer, hasDrawTimer]
149+
150+
def loop_timer_callback(tmr):
151+
global loopCallbacks
152+
requestedInterval = 99999999
153+
newLoopCallbacks = loopCallbacks
154+
for cb in loopCallbacks:
155+
rqi = 0
40156
try:
41-
if (srv.loop(lcnt)):
42-
noSleep = True
157+
rqi = cb()
43158
except BaseException as msg:
44-
print("[SERVICES] Service loop exception: ", msg)
45-
return noSleep
159+
print("[SERVICES] Exception in service loop: ", msg)
160+
newLoopCallbacks.pop(cb)
161+
continue
162+
if rqi>0 and rqi<requestedInterval:
163+
# Service wants to loop again in rqi seconds
164+
requestedInterval = rqi
165+
elif rqi<=0:
166+
# Service doesn't want to loop again until next wakeup
167+
newLoopCallbacks.pop(cb)
168+
loopCallbacks = newLoopCallbacks
169+
del(newLoopCallbacks)
170+
171+
try:
172+
if pmCallback(requestedInterval):
173+
print("[SERVICES] Loop timer (re-)started")
174+
tmr.init(period=requestedInterval*1000, mode=machine.Timer.ONE_SHOT, callback=loop_timer_callback)
175+
except:
176+
print("[SERVICES] Error in power management callback!")
46177

47-
def draw():
48-
global services
49-
x = 0
50-
y = 64
51-
for srv in services:
178+
def draw_timer_callback(tmr):
179+
global drawCallback #The function that allows us to hook into our host
180+
global drawCallbacks #The functions of the services
181+
requestedInterval = 99999999
182+
y = ugfx.height()
183+
184+
drawCallback(False) # Prepare draw
185+
186+
newDrawCallbacks = drawCallbacks
187+
for cb in drawCallback:
188+
rqi = 0
52189
try:
53-
space_used = srv.draw(x,y)
54-
if (space_used>0):
55-
y = y + abs(space_used)
190+
[rqi, space_used] = cb(y)
191+
y = y - space_used
56192
except BaseException as msg:
57-
print("[SERVICES] Service draw exception: ", msg)
193+
print("[SERVICES] Exception in service draw: ", msg)
194+
newDrawCallbacks.pop(cb)
195+
continue
196+
if rqi>0 and rqi<requestedInterval:
197+
# Service wants to loop again in rqi seconds
198+
requestedInterval = rqi
199+
elif rqi<=0:
200+
# Service doesn't want to draw again until next wakeup
201+
newDrawCallbacks.pop(cb)
202+
drawCallbacks = newDrawCallbacks
203+
del(newDrawCallbacks)
204+
205+
badge.eink_busy_wait()
206+
207+
if len(drawCallbacks)>0:
208+
print("[SERVICES] New draw requested in "+str(requestedInterval)+".")
209+
tmr.init(period=requestedInterval*1000, mode=machine.Timer.ONE_SHOT, callback=draw_timer_callback)
210+
211+
drawCallback(True) # Complete draw
58212

59-
services = []
213+
def force_draw(disableTimer):
214+
if disableTimer:
215+
print("[SERVICES] Drawing services one last time before sleep...")
216+
global drawTimer
217+
try:
218+
drawTimer.deinit()
219+
except:
220+
pass
221+
else:
222+
print("[SERVICES] Drawing at boot...")
223+
global drawCallbacks
224+
if len(drawCallbacks)>0:
225+
y = ugfx.height()
226+
for cb in drawCallback:
227+
try:
228+
[rqi, space_used] = cb(y)
229+
y = y - space_used
230+
except BaseException as msg:
231+
print("[SERVICES] Exception in service draw: ", msg)
232+
newDrawCallbacks.pop(cb)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy