moved device logic
This commit is contained in:
parent
cd7c5401b5
commit
8ef2c4c551
101
ble_interface.py
Normal file
101
ble_interface.py
Normal file
@ -0,0 +1,101 @@
|
||||
from asyncio import AbstractEventLoop
|
||||
import asyncio
|
||||
from typing import Dict
|
||||
|
||||
from bleak import BleakClient, BleakScanner
|
||||
from bleak.backends.characteristic import BleakGATTCharacteristic
|
||||
from bleak.backends.service import BleakGATTService
|
||||
from bleak.uuids import normalize_uuid_str
|
||||
|
||||
import logging
|
||||
import struct
|
||||
|
||||
import myUUIDs
|
||||
|
||||
class ble_interface:
|
||||
CURRENT = "current"
|
||||
VOLTAGE = "volts"
|
||||
CONFIGURATION = "conf"
|
||||
RFRSH_DELAY = "refresh_delay"
|
||||
ON_CONNECT = "on_connect"
|
||||
|
||||
def __init__(self, address, loop: AbstractEventLoop, logger : logging.Logger) -> None:
|
||||
self.address = address
|
||||
self.loop = loop
|
||||
self.client: BleakClient
|
||||
self.log = logger
|
||||
self.callbacks = {}
|
||||
self.services: Dict[str, BleakGATTService] = {}
|
||||
self.handlers = {
|
||||
self.CURRENT: self.__current_meas_handler,
|
||||
}
|
||||
|
||||
async def __connect(self):
|
||||
device = await BleakScanner.find_device_by_address(self.address, cb=dict(use_bdaddr=False))
|
||||
if device is None:
|
||||
self.log.error("could not find device with address")
|
||||
return
|
||||
|
||||
async with BleakClient(device) as client:
|
||||
self.log.info("Connected")
|
||||
self.client = client
|
||||
|
||||
self.call_callback(self.ON_CONNECT)
|
||||
|
||||
services = client.services.services
|
||||
|
||||
self.parse_services(services)
|
||||
|
||||
await asyncio.Event().wait()
|
||||
|
||||
def parse_services(self, services: Dict[int, BleakGATTService]):
|
||||
for i in services:
|
||||
s = services[i]
|
||||
if(s.uuid == normalize_uuid_str(myUUIDs.METROLOGY_SERVICE)):
|
||||
if(s.characteristics[0].uuid == normalize_uuid_str(myUUIDs.ELECTRIC_CURRENT_CHAR)):
|
||||
self.services[self.CURRENT] = s
|
||||
|
||||
if(s.characteristics[0].uuid == normalize_uuid_str(myUUIDs.VOLTAGE_CHAR)):
|
||||
self.services[self.VOLTAGE] = s
|
||||
|
||||
|
||||
if(s.uuid == normalize_uuid_str(myUUIDs.CONFIGURATION_SERVICE)):
|
||||
self.services[self.CONFIGURATION] = s
|
||||
|
||||
def connect(self):
|
||||
self.log.info("connecting")
|
||||
|
||||
self.loop.create_task(self.__connect())
|
||||
|
||||
def subscribe_to(self, to: str):
|
||||
self.loop.create_task(self.__subscribe_to(to))
|
||||
|
||||
async def __subscribe_to(self, to: str):
|
||||
self.log.info("subscribing to %s", to)
|
||||
for c in self.services[to].characteristics:
|
||||
await self.client.start_notify(c, self.handlers[to])
|
||||
|
||||
def add_callback(self, id: str, callback):
|
||||
if(not id in self.callbacks):
|
||||
self.callbacks[id] = []
|
||||
self.callbacks[id].append(callback)
|
||||
|
||||
def call_callback(self, id: str, *params):
|
||||
if(id in self.callbacks):
|
||||
for c in self.callbacks[id]:
|
||||
if(params):
|
||||
c(self, *params)
|
||||
else:
|
||||
c(self)
|
||||
|
||||
def __current_meas_handler(self, char: BleakGATTCharacteristic, data: bytearray):
|
||||
val = struct.unpack("<I", data)[0]
|
||||
handle = next(i for i,c in enumerate(self.services[self.CURRENT].characteristics) if c.handle == char.handle)
|
||||
|
||||
self.call_callback(self.CURRENT, handle, val)
|
||||
if(self.CURRENT in self.callbacks):
|
||||
for c in self.callbacks[self.CURRENT]:
|
||||
c(self, handle, val)
|
||||
|
||||
def update_refresh_delay(self, val: int):
|
||||
pass
|
59
main.py
59
main.py
@ -8,21 +8,27 @@ import time
|
||||
from bleak import BleakClient, BleakScanner
|
||||
from bleak.backends.characteristic import BleakGATTCharacteristic
|
||||
from bleak.uuids import normalize_uuid_str
|
||||
from ble_interface import ble_interface
|
||||
|
||||
import dearpygui.dearpygui as dpg
|
||||
|
||||
import myUUIDs
|
||||
from ble_interface import ble_interface
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
loop = None
|
||||
loop: asyncio.AbstractEventLoop
|
||||
device: ble_interface
|
||||
|
||||
current_meas = {}
|
||||
start_time = None
|
||||
|
||||
def current_meas_handler(characteristic: BleakGATTCharacteristic, data: bytearray):
|
||||
value = struct.unpack("<I", data)[0]
|
||||
handle = characteristic.handle
|
||||
def on_connect_handler(device: ble_interface):
|
||||
device.subscribe_to(device.CURRENT)
|
||||
|
||||
def current_meas_handler(device: ble_interface, input_handle: int, newval: int):
|
||||
value = newval
|
||||
handle = input_handle
|
||||
logger.info("%s: %f", handle, value * 1.0e-6)
|
||||
|
||||
global start_time
|
||||
@ -41,37 +47,13 @@ def current_meas_handler(characteristic: BleakGATTCharacteristic, data: bytearra
|
||||
current_meas[handle].append(((time.monotonic_ns() - start_time) * 1e-9, value * 1e-6))
|
||||
|
||||
dpg.set_value(f"serie{handle}", [ [v[0] for v in current_meas[handle]], [v[1] for v in current_meas[handle]] ])
|
||||
dpg.fit_axis_data("x_axis")
|
||||
dpg.fit_axis_data("y_axis")
|
||||
# dpg.fit_axis_data("x_axis")
|
||||
# dpg.fit_axis_data("y_axis")
|
||||
|
||||
|
||||
async def connect():
|
||||
logger.info("starting scan...")
|
||||
|
||||
device = await BleakScanner.find_device_by_address("84:F7:03:1B:C6:A2", cb=dict(use_bdaddr=False))
|
||||
if device is None:
|
||||
logger.error("could not find device with address")
|
||||
return
|
||||
|
||||
logger.info("connecting to device...")
|
||||
|
||||
async with BleakClient(device) as client:
|
||||
logger.info("Connected")
|
||||
|
||||
current_svc_handle = 0
|
||||
services = client.services.services
|
||||
metrology_svcs = [services[i] for i in services if services[i].uuid == normalize_uuid_str(myUUIDs.METROLOGY_SERVICE)]
|
||||
|
||||
current_meas_svc = next(s for s in metrology_svcs if s.get_characteristic(myUUIDs.ELECTRIC_CURRENT_CHAR))
|
||||
|
||||
for c in current_meas_svc.characteristics:
|
||||
await client.start_notify(c, current_meas_handler)
|
||||
|
||||
await asyncio.Event().wait()
|
||||
# await client.stop_notify(args.characteristic)
|
||||
|
||||
def start_connection():
|
||||
loop.create_task(connect())
|
||||
def update_refresh_rate(sender, app_data):
|
||||
logger.info("refresh rate %d", app_data)
|
||||
device.update_refresh_delay(app_data)
|
||||
|
||||
async def init_gui():
|
||||
dpg.create_context()
|
||||
@ -79,9 +61,10 @@ async def init_gui():
|
||||
dpg.setup_dearpygui()
|
||||
|
||||
with dpg.window(label="Controls", pos = [0, 0], width = dpg.get_viewport_width(), height = 100):
|
||||
dpg.add_button(label="Connect", callback=start_connection)
|
||||
dpg.add_button(label="Connect", callback=device.connect)
|
||||
dpg.add_input_int(label="Refresh Delay", callback=update_refresh_rate, on_enter=True, tag="refresh delay")
|
||||
|
||||
with dpg.window(label="Graphs", pos = [0, 100]):
|
||||
with dpg.window(label="Graphs", pos = [0, 100], width = dpg.get_viewport_width(), height = 500):
|
||||
with dpg.plot(label="Current", width = -1, height = -1):
|
||||
dpg.add_plot_legend()
|
||||
|
||||
@ -102,7 +85,13 @@ if __name__ == "__main__":
|
||||
level="INFO",
|
||||
format="%(asctime)-15s %(name)-8s %(levelname)s: %(message)s",
|
||||
)
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
device = ble_interface("84:F7:03:1B:C6:A2", loop, logger)
|
||||
device.add_callback(device.ON_CONNECT, on_connect_handler)
|
||||
device.add_callback(device.CURRENT, current_meas_handler)
|
||||
|
||||
loop.create_task(init_gui())
|
||||
loop.run_forever()
|
||||
|
Loading…
x
Reference in New Issue
Block a user