Phone finder app
* Added phone finder app that works with Gadgetbridge * Fixed bug in ToggleButton * Moved send_cmd from music player to gadgetbridge.py for all apps to use Signed-off-by: Adam Blair adampblair@protonmail.com
This commit is contained in:
parent
99272f482f
commit
fd030eeff8
8 changed files with 122 additions and 15 deletions
|
@ -265,3 +265,7 @@ application (and the "blank" white screen is a torch application):
|
|||
.. image:: res/BeaconApp.png
|
||||
:alt: Flash the relatively powerful HRS LED repeatedly
|
||||
:width: 179
|
||||
|
||||
.. image:: res/FinderApp.png
|
||||
:alt: Find your phone by causing it to ring
|
||||
:width: 179
|
||||
|
|
96
apps/PhoneFinder.py
Normal file
96
apps/PhoneFinder.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
# Copyright (C) 2023 Adam Blair
|
||||
"""Phone finder application
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An application to find a phone connected via Gadgetbridge.
|
||||
|
||||
.. figure:: res/FinderApp.png
|
||||
:width: 179
|
||||
|
||||
Screenshot of the Phone Finder Application
|
||||
|
||||
"""
|
||||
|
||||
import wasp
|
||||
import fonts
|
||||
import widgets
|
||||
from gadgetbridge import send_cmd
|
||||
|
||||
# 2-bit RLE, 96x64, generated from res/phone_finder_icon.png, 403 bytes
|
||||
icon = (
|
||||
b'\x02'
|
||||
b'`@'
|
||||
b'?\xff\xff\x87@\xd0G?\x17C\x07C?\x12B\r'
|
||||
b'B?\x0fA\x11A?\rA\x13A?\x0bA\x15A'
|
||||
b'?\tA?\x1fA!\x80\xb4\x84:A\rG\r\x84'
|
||||
b'9A\x0cB\x07B?\tA\x0bA\x0bA?\x08A'
|
||||
b'\nA\rA\t\x848A\nA\x18\x848A\tA'
|
||||
b'\tD\x0c\x848A\x08A\x08B\x04B\n\x848A'
|
||||
b'\x08A\x06B\x08A\t\x848A\x07A\x06A\x14A'
|
||||
b'\x838A\x07A\x06A\x01A\x91B\x83A7A\x07'
|
||||
b'A\x05A\x01A\x98A7A\x06A\x05A\x01\x82\x16'
|
||||
b'\x827A\x06A\x04A\x02\x82\x04N\x04\x827A\x06'
|
||||
b'A\x04A\x02\x82\x04N\x04\x828A\x05A\x04A\x02'
|
||||
b'\x82\x04N\x04\x828A\x06A\x03A\x02\x82\x16\x829'
|
||||
b'A\x05A\x04A\x01\x82\x02R\x02\x82:A\x05A\x03'
|
||||
b'A\x01\x82\x02R\x02\x82;A\x05A\x03A\x82\x02R'
|
||||
b'\x02\x82<A\x05A\x02A\x82\x02R\x02\x82?\x07\x82'
|
||||
b'\x02R\x02\x82?\x07\x82\x02R\x02\x82?\x07\x82\x02R'
|
||||
b'\x02\x82?\x07\x82\x02R\x02\x82?\x07\x82\x02R\x02\x82'
|
||||
b'?\x07\x82\x02R\x02\x82?\x07\x82\x02R\x02\x82?\x07'
|
||||
b'\x82\x02R\x02\x82?\x07\x82\x02R\x02\x82?\x07\x82\x02'
|
||||
b'R\x02\x82?\x07\x82\x02R\x02\x82?\x07\x82\x02R\x02'
|
||||
b'\x82?\x07\x82\x02R\x02\x82?\x07\x82\x02R\x02\x82?'
|
||||
b'\x07\x82\x02R\x02\x82?\x07\x82\x02R\x02\x82?\x07\x82'
|
||||
b'\x02R\x02\x82?\x07\x82\x02R\x02\x82?\x07\x82\x02R'
|
||||
b'\x02\x82?\x07\x82\x16\x82?\x07\x82\x06J\x06\x82?\x07'
|
||||
b'\x82\x16\x82?\x07A\x98A?\x08A\x96A?\xff\xc1'
|
||||
)
|
||||
|
||||
class PhoneFinderApp():
|
||||
"""Allows the user to set a vibration alarm.
|
||||
"""
|
||||
NAME = 'Finder'
|
||||
ICON = icon
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the application."""
|
||||
pass
|
||||
|
||||
def foreground(self):
|
||||
"""Activate the application."""
|
||||
self.ring_btn = widgets.ToggleButton(20, 120, 200, 60, 'Ring')
|
||||
|
||||
self._draw()
|
||||
wasp.system.request_event(wasp.EventMask.TOUCH)
|
||||
wasp.system.request_tick(1000)
|
||||
|
||||
def background(self):
|
||||
"""De-activate the application."""
|
||||
self.ring_btn = None
|
||||
del self.ring_btn
|
||||
|
||||
def tick(self, ticks):
|
||||
"""Notify the application that its periodic tick is due."""
|
||||
wasp.system.bar.update()
|
||||
|
||||
def touch(self, event):
|
||||
"""Notify the application of a touchscreen touch event."""
|
||||
if self.ring_btn.touch(event):
|
||||
if self.ring_btn.state:
|
||||
send_cmd('{"t":"findPhone", "n":"true"} ')
|
||||
else:
|
||||
send_cmd('{"t":"findPhone", "n":"false"} ')
|
||||
|
||||
def _draw(self):
|
||||
"""Draw the display from scratch."""
|
||||
draw = wasp.watch.drawable
|
||||
draw.fill()
|
||||
sbar = wasp.system.bar
|
||||
sbar.clock = True
|
||||
sbar.draw()
|
||||
|
||||
draw.set_font(fonts.sans24)
|
||||
draw.string('Find phone', 60, 70, width=120)
|
||||
self.ring_btn.draw()
|
|
@ -55,6 +55,8 @@ Applications
|
|||
|
||||
.. automodule:: apps.flashlight
|
||||
|
||||
.. automodule:: PhoneFinder
|
||||
|
||||
.. automodule:: apps.gallery
|
||||
|
||||
.. automodule:: apps.haiku
|
||||
|
|
BIN
res/FinderApp.png
Normal file
BIN
res/FinderApp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
res/phone_finder_icon.png
Normal file
BIN
res/phone_finder_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 915 B |
|
@ -23,6 +23,7 @@ import icons
|
|||
import time
|
||||
|
||||
from micropython import const
|
||||
from gadgetbridge import send_cmd
|
||||
|
||||
# 2-bit RLE, generated from res/music_icon.png, 358 bytes
|
||||
icon = (
|
||||
|
@ -74,15 +75,6 @@ class MusicPlayerApp(object):
|
|||
self._track_changed = True
|
||||
self._artist_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(
|
||||
|
@ -151,9 +143,9 @@ class MusicPlayerApp(object):
|
|||
Notify the application of a touchscreen swipe event.
|
||||
"""
|
||||
if event[0] == wasp.EventType.UP:
|
||||
self._send_cmd('{"t":"music", "n":"volumeup"} ')
|
||||
send_cmd('{"t":"music", "n":"volumeup"} ')
|
||||
elif event[0] == wasp.EventType.DOWN:
|
||||
self._send_cmd('{"t":"music", "n":"volumedown"} ')
|
||||
send_cmd('{"t":"music", "n":"volumedown"} ')
|
||||
|
||||
def touch(self, event):
|
||||
if self._pauseplay.touch(event):
|
||||
|
@ -162,16 +154,16 @@ class MusicPlayerApp(object):
|
|||
self._musicstate = 'play'
|
||||
self._pauseplay.gfx = icons.pause
|
||||
self._pauseplay.draw()
|
||||
self._send_cmd('{"t":"music", "n":"play"} ')
|
||||
send_cmd('{"t":"music", "n":"play"} ')
|
||||
else:
|
||||
self._musicstate = 'pause'
|
||||
self._pauseplay.gfx = icons.play
|
||||
self._pauseplay.draw()
|
||||
self._send_cmd('{"t":"music", "n":"pause"} ')
|
||||
send_cmd('{"t":"music", "n":"pause"} ')
|
||||
elif self._back.touch(event):
|
||||
self._send_cmd('{"t":"music", "n":"previous"} ')
|
||||
send_cmd('{"t":"music", "n":"previous"} ')
|
||||
elif self._fwd.touch(event):
|
||||
self._send_cmd('{"t":"music", "n":"next"} ')
|
||||
send_cmd('{"t":"music", "n":"next"} ')
|
||||
|
||||
def draw(self):
|
||||
"""Redraw the display from scratch."""
|
||||
|
|
|
@ -22,6 +22,7 @@ import io
|
|||
import json
|
||||
import sys
|
||||
import wasp
|
||||
import time
|
||||
|
||||
# JSON compatibility
|
||||
null = None
|
||||
|
@ -66,3 +67,12 @@ def GB(cmd):
|
|||
sys.print_exception(e, msg)
|
||||
_error(msg.getvalue())
|
||||
msg.close()
|
||||
|
||||
def send_cmd(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(' ')
|
|
@ -282,6 +282,9 @@ class ToggleButton(Button):
|
|||
if super().touch(event):
|
||||
self.state = not self.state
|
||||
self.draw()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
class Checkbox():
|
||||
"""A simple (labelled) checkbox."""
|
||||
|
|
Loading…
Reference in a new issue