Use local version of able

This commit is contained in:
Mark Qvist 2025-10-29 12:54:59 +01:00
parent 2e44d49d6b
commit 9b6a51a03e
67 changed files with 5305 additions and 0 deletions

View file

@ -0,0 +1,27 @@
[app]
title = Alert Mi
version = 1.1
package.name = alert_mi
package.domain = org.kivy
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
requirements = python3,kivy,android,able_recipe
android.accept_sdk_license = True
android.permissions =
BLUETOOTH,
BLUETOOTH_ADMIN,
BLUETOOTH_SCAN,
BLUETOOTH_CONNECT,
BLUETOOTH_ADVERTISE,
ACCESS_FINE_LOCATION
# android.api = 31
# android.minapi = 31
[buildozer]
warn_on_root = 1
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

View file

@ -0,0 +1,21 @@
<ErrorMessage>:
BoxLayout:
orientation: 'vertical'
padding: 10
spacing: 20
Label:
size_hint_y: None
font_size: '18sp'
height: '24sp'
text: 'Application has crashed, details: '
ScrollView:
size_hint: 1, 1
TextInput:
text: root.message
size_hint: 1, None
height: self.minimum_height
Button:
size_hint_y: None
height: '40sp'
text: 'OK, terminate'
on_press: root.dismiss()

View file

@ -0,0 +1,39 @@
import os
import traceback
from kivy.base import (
ExceptionHandler,
ExceptionManager,
stopTouchApp,
)
from kivy.properties import StringProperty
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.logger import Logger
Builder.load_file(os.path.join(os.path.dirname(__file__), 'error_message.kv'))
class ErrorMessageOnException(ExceptionHandler):
def handle_exception(self, exception):
Logger.exception('Unhandled Exception catched')
message = ErrorMessage(message=traceback.format_exc())
def raise_exception(*ar2gs, **kwargs):
stopTouchApp()
raise Exception("Exit due to errors")
message.bind(on_dismiss=raise_exception)
message.open()
return ExceptionManager.PASS
class ErrorMessage(Popup):
title = StringProperty('Bang!')
message = StringProperty('')
def install_exception_handler():
ExceptionManager.add_handler(ErrorMessageOnException())

View file

@ -0,0 +1,64 @@
"""Turn the alert on Mi Band device
"""
from kivy.app import App
from kivy.uix.button import Button
from able import BluetoothDispatcher, GATT_SUCCESS
from error_message import install_exception_handler
class BLE(BluetoothDispatcher):
device = alert_characteristic = None
def start_alert(self, *args, **kwargs):
if self.alert_characteristic: # alert service is already discovered
self.alert(self.alert_characteristic)
elif self.device: # device is already founded during the scan
self.connect_gatt(self.device) # reconnect
else:
self.stop_scan() # stop previous scan
self.start_scan() # start a scan for devices
def on_device(self, device, rssi, advertisement):
# some device is found during the scan
name = device.getName()
if name and name.startswith('MI'): # is a Mi Band device
self.device = device
self.stop_scan()
def on_scan_completed(self):
if self.device:
self.connect_gatt(self.device) # connect to device
def on_connection_state_change(self, status, state):
if status == GATT_SUCCESS and state: # connection established
self.discover_services() # discover what services a device offer
else: # disconnection or error
self.alert_characteristic = None
self.close_gatt() # close current connection
def on_services(self, status, services):
# 0x2a06 is a standard code for "Alert Level" characteristic
# https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.alert_level.xml
self.alert_characteristic = services.search('2a06')
self.alert(self.alert_characteristic)
def alert(self, characteristic):
self.write_characteristic(characteristic, [2]) # 2 is for "High Alert"
class AlertApp(App):
def build(self):
self.ble = None
return Button(text='Press to Alert Mi', on_press=self.start_alert)
def start_alert(self, *args, **kwargs):
if not self.ble:
self.ble = BLE()
self.ble.start_alert()
if __name__ == '__main__':
install_exception_handler()
AlertApp().run()