1
0
Fork 0
pull/197/merge
Tait Berlette 2021-06-03 20:53:25 +01:00 committed by GitHub
commit 09d44f6b0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 202 additions and 0 deletions

View File

@ -167,6 +167,10 @@ simulator:
:alt: Software selection app running on the wasp-os simulator :alt: Software selection app running on the wasp-os simulator
:width: 179 :width: 179
.. image:: res/PhoneApp.png
:alt: Phone application running on the wasp-os simulator
:width: 179
wasp-os also contains a library of additional applications for you to choose. wasp-os also contains a library of additional applications for you to choose.
These are disabled by default but can be easily enabled using the Software These are disabled by default but can be easily enabled using the Software

View File

@ -36,6 +36,8 @@ Built-in
.. automodule:: apps.pager .. automodule:: apps.pager
.. automodule:: apps.phone
Applications Applications
------------ ------------

BIN
res/PhoneApp.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
res/hangup.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

BIN
res/phone.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

150
wasp/apps/phone.py 100644
View File

@ -0,0 +1,150 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2020 Daniel Thompson
# Copyright (C) 2020 Carlos Gil
"""Phone for GadgetBridge and wasp-os companion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. figure:: res/PhoneApp.png
:width: 179
Screenshot of the Phone application
Phone Controller:
* Touch: answer/end
* Event BACK: ignore/close
"""
import wasp
import icons
import time
from micropython import const
DISPLAY_WIDTH = const(240)
ICON_SIZE = const(72)
CENTER_AT = const((DISPLAY_WIDTH - ICON_SIZE) // 2)
class PhoneApp(object):
""" Phone application."""
NAME = 'Phone'
def __init__(self):
self._anwser = wasp.widgets.GfxButton(24, CENTER_AT, icons.phone)
self._end = wasp.widgets.GfxButton(DISPLAY_WIDTH - ICON_SIZE - 24, CENTER_AT, icons.hangup)
self._state = "end"
self._name = ''
self._number = ''
self._state_changed = True
self._name_changed = True
self._number_changed = True
def _send_cmd(self, cmd):
print('\r')
for i in range(1):
for i in range(0, len(cmd), 20):
print(cmd[i: i + 20], end='')
time.sleep(0.2)
print(' ')
print(' ')
def _fill_space(self, key):
if key == 'top':
wasp.watch.drawable.fill(
x=0, y=0, w=DISPLAY_WIDTH, h=CENTER_AT)
elif key == 'down':
wasp.watch.drawable.fill(x=0, y=CENTER_AT + ICON_SIZE,
w=DISPLAY_WIDTH,
h=DISPLAY_WIDTH - (CENTER_AT + ICON_SIZE))
def foreground(self):
"""Activate the application."""
number = wasp.system.phonestate.get('number')
name = wasp.system.phonestate.get('name')
state = wasp.system.phonestate.get('cmd')
if number:
self._number = number
if name:
self._name = name
if state:
self._state = state
wasp.watch.drawable.fill()
self.draw()
wasp.system.request_tick(1000)
wasp.system.request_event(wasp.EventMask.TOUCH)
def background(self):
"""De-activate the application (without losing state)."""
self._state_changed = True
self._name_changed = True
self._number_changed = True
def tick(self, ticks):
wasp.system.keep_awake()
state_now = wasp.system.phonestate.get('cmd')
name_now = wasp.system.phonestate.get('name')
number_now = wasp.system.phonestate.get('number')
if state_now:
if state_now != self._state:
self._state = state_now
self._state_changed = True
else:
self._state_changed = False
if name_now:
if name_now != self._name:
self._name = name_now
self._name_changed = True
else:
self._name_changed = False
if number_now:
if number_now != self._number:
self._number = number_now
self._number_changed = True
else:
self._number_changed = False
wasp.system.phonestate = {}
self._update()
def touch(self, event):
if self._anwser.touch(event):
self._send_cmd('{"t":"call", "n":"ACCEPT"} ')
wasp.system.navigate(wasp.EventType.BACK)
elif self._end.touch(event):
self._send_cmd('{"t":"call", "n":"REJECT"} ')
wasp.system.navigate(wasp.EventType.BACK)
def draw(self):
"""Redraw the display from scratch."""
self._draw()
def _draw(self):
"""Redraw the updated zones."""
if self._state_changed:
self._anwser.draw()
if self._name_changed:
self._draw_label(self._name, 24 + 144)
if self._number_changed:
self._draw_label(self._number, 12)
self._end.draw()
def _draw_label(self, label, pos):
"""Redraw label info"""
if label:
draw = wasp.watch.drawable
chunks = draw.wrap(label, 240)
self._fill_space(pos)
for i in range(len(chunks)-1):
sub = label[chunks[i]:chunks[i+1]].rstrip()
draw.string(sub, 0, pos + 24 * i, 240)
def _update(self):
if(self._state == "start" or self._state == "incoming"):
wasp.watch.vibrator.pulse(ms=wasp.system.notify_duration)
def update(self):
pass

View File

@ -17,6 +17,7 @@ manifest = (
'apps/launcher.py', 'apps/launcher.py',
'apps/pager.py', 'apps/pager.py',
'apps/play2048.py', 'apps/play2048.py',
'apps/phone.py',
'apps/settings.py', 'apps/settings.py',
'apps/software.py', 'apps/software.py',
'apps/steps.py', 'apps/steps.py',

View File

@ -13,6 +13,12 @@ wasp.system.set_music_info({
'artist': 'Dreams of Bamboo', 'artist': 'Dreams of Bamboo',
}) })
wasp.system.set_phone_state({
'cmd': 'end',
'name': '5555555555',
'number': 'Unknown Caller',
})
# Increase the display blanking time to avoid spamming the console # Increase the display blanking time to avoid spamming the console
# with backlight activations. # with backlight activations.

View File

@ -11,3 +11,5 @@ settings = 'Default settings icon'
torch = 'Default torch or flashlight icon' torch = 'Default torch or flashlight icon'
up_arrow = 'Small (16x9) up arrow' up_arrow = 'Small (16x9) up arrow'
down_arrow = 'Small (16x9) down arrow' down_arrow = 'Small (16x9) down arrow'
phone = 'A phone icon rotated to look as if it is picked up'
hangup = 'A phone icon'

View File

@ -56,6 +56,8 @@ def GB(cmd):
wasp.system.toggle_music(cmd) wasp.system.toggle_music(cmd)
elif task == 'musicinfo': elif task == 'musicinfo':
wasp.system.set_music_info(cmd) wasp.system.set_music_info(cmd)
elif task == 'call':
wasp.system.set_phone_state(cmd)
else: else:
pass pass
#_info('Command "{}" is not implemented'.format(cmd)) #_info('Command "{}" is not implemented'.format(cmd))

View File

@ -303,3 +303,29 @@ checkbox = (
b'Z\xc7X\xe4\x01\xde\x03\xdc\x02' b'Z\xc7X\xe4\x01\xde\x03\xdc\x02'
) )
# 2-bit RLE, generated from res/phone.png, 126 bytes
phone = (
b'\x02'
b'HH'
b'?\xff\xff\xa8\xc4?\x03\xc7?\x01\xc9>\xcb<\xcc;'
b'\xce:\xcf8\xd07\xd26\xd26\xd25\xd44\xd44'
b'\xd44\xd35\xd35\xd26\xd17\xcf9\xce:\xcd<'
b'\xcc<\xcc<\xcc=\xcb=\xcc<\xcd<\xcc<\xcd<'
b"\xcc<\xcd<\xcd<\xcd<\xcd\x0e\xc5(\xce\x0c\xc8'"
b'\xce\n\xcb&\xce\x07\xce&\xd0\x03\xd0&\xe3&\xe3&'
b"\xe3&\xe2'\xe1(\xe0)\xdf*\xdd,\xdc.\xd90"
b'\xd63\xd47\xcf<\xc9?\xff\xff\xa9'
)
# 2-bit RLE, generated from res/hangup.png, 104 bytes
hangup = (
b'\x02'
b'HH'
b'?\xff\xff\xff\xff\xff8\xd40\xdc)\xe3"\xe7 \xea'
b'\x1c\xee\x19\xf0\x17\xf2\x15\xf4\x13\xf6\x11\xda\x05\xd8\x11\xd4'
b'\x10\xd4\x0f\xd2\x15\xd2\x0f\xd1\x17\xd2\x0e\xd1\x17\xd2\r\xd2'
b'\x17\xd2\r\xd2\x17\xd2\r\xd2\x17\xd2\r\xd2\x17\xd2\r\xd2'
b'\x17\xd2\r\xd2\x17\xd2\r\xd2\x18\xd1\r\xd1\x19\xd1\r\xd1'
b'\x1a\xd0\r\xd0\x1d\xce\x0e\xcd!\xcb\x10\xc8?\xff\xff\xff'
b'\xff\xff\xff\xffP'
)

View File

@ -30,6 +30,7 @@ from apps.settings import SettingsApp
from apps.steps import StepCounterApp from apps.steps import StepCounterApp
from apps.software import SoftwareApp from apps.software import SoftwareApp
from apps.stopwatch import StopwatchApp from apps.stopwatch import StopwatchApp
from apps.phone import PhoneApp
class EventType(): class EventType():
"""Enumerated interface actions. """Enumerated interface actions.
@ -117,6 +118,8 @@ class Manager():
self.notifications = {} self.notifications = {}
self.musicstate = {} self.musicstate = {}
self.musicinfo = {} self.musicinfo = {}
self.call = PhoneApp()
self.phonestate = {}
self._theme = ( self._theme = (
b'\x7b\xef' # ble b'\x7b\xef' # ble
@ -320,6 +323,12 @@ class Manager():
def set_music_info(self, info): def set_music_info(self, info):
self.musicinfo = info self.musicinfo = info
def set_phone_state(self, info):
self.phonestate = info
if(self.phonestate.get("cmd") == "start" or self.phonestate.get("cmd") == "incoming"):
self.wake()
self.switch(self.call)
def set_alarm(self, time, action): def set_alarm(self, time, action):
"""Queue an alarm. """Queue an alarm.