manager: Implement alarm callbacks for applications to use

Create a simple time queue where actions (functions or bound methods) can
be queued against the real time clock.

Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
This commit is contained in:
Daniel Thompson 2020-11-14 12:24:28 +00:00
parent d2357f2325
commit d0a99d5636
4 changed files with 56 additions and 6 deletions

@ -1 +1 @@
Subproject commit b442d82b8ca4e7062bfcafedbd6ea2788400ae69
Subproject commit d198d2907a0837cb82f4d38984bb2ba068cacf77

View file

@ -117,6 +117,9 @@ class RTC(object):
now = self.get_localtime()
return (now[3], now[4], now[5])
def time(self):
return time.time()
@property
def uptime(self):
return time.time() - self._epoch

View file

@ -103,6 +103,10 @@ class RTC(object):
localtime = self.get_localtime()
return localtime[3:6]
def time(self):
"""Get time in the same format as time.time"""
return self.offset + (self._uptime >> 3)
@property
def uptime(self):
"""Provide the current uptime in seconds."""

View file

@ -86,6 +86,14 @@ class PinHandler():
self._value = new_value
return new_value
def _key_app(d):
"""Get a sort key for apps."""
return d.NAME
def _key_alarm(d):
"""Get a sort key for alarms."""
return d[0]
class Manager():
"""Wasp-os system manager
@ -112,6 +120,7 @@ class Manager():
self.blank_after = 15
self._alarms = []
self._brightness = 2
self._button = PinHandler(watch.button)
self._charging = True
@ -142,7 +151,7 @@ class Manager():
self.quick_ring.append(app)
else:
self.launcher_ring.append(app)
self.launcher_ring.sort(key = lambda x: x.NAME)
self.launcher_ring.sort(key = _key_app)
@property
def brightness(self):
@ -159,7 +168,16 @@ class Manager():
"""
if self.app:
if 'background' in dir(self.app):
self.app.background()
try:
self.app.background()
except:
# Clear out the old app to ensure we don't recurse when
# we switch to to the CrashApp. It's a bit freaky but
# True has an empty directory this is better than
# None because it won't re-runt he system start up
# code.
self.app = True
raise
else:
# System start up...
watch.display.poweron()
@ -242,6 +260,23 @@ class Manager():
def set_music_info(self, info):
self.musicinfo = info
def set_alarm(self, time, action):
"""Queue an alarm.
:param int time: Time to trigger the alarm (use time.mktime)
:param function action: Action to perform when the alarm expires.
"""
self._alarms.append((time, action))
self._alarms.sort(key = _key_alarm)
def cancel_alarm(self, time, action):
"""Unqueue an alarm."""
try:
self._alarms.remove((time, action))
except:
return False
return True
def request_event(self, event_mask):
"""Subscribe to events.
@ -338,9 +373,19 @@ class Manager():
expiry point.
"""
rtc = watch.rtc
update = rtc.update()
alarms = self._alarms
if update and alarms:
now = rtc.time()
head = alarms[0]
if head[0] <= now:
alarms.remove(head)
head[1]()
if self.sleep_at:
if rtc.update() and self.tick_expiry:
if update and self.tick_expiry:
now = rtc.get_uptime_ms()
if self.tick_expiry <= now:
@ -363,8 +408,6 @@ class Manager():
gc.collect()
else:
watch.rtc.update()
if 1 == self._button.get_event() or \
self._charging != watch.battery.charging():
self.wake()