Skip to content

Commit

Permalink
Merge pull request #18 from svhoy/17-ss-twr--ds-twr
Browse files Browse the repository at this point in the history
17 ss twr  ds twr
  • Loading branch information
svhoy authored Feb 15, 2024
2 parents 8a3cb1d + 49fee37 commit ceb8b3a
Show file tree
Hide file tree
Showing 10 changed files with 444 additions and 104 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ jobs:
poetry install --no-interaction --no-root
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
poetry run pylint $(git ls-files '*.py')
black:
runs-on: windows-2022
steps:
- uses: actions/checkout@v2
- uses: psf/black@stable
with:
options: "--check --verbose --exclude old_test "
options: "--check --verbose"
50 changes: 25 additions & 25 deletions apps/sit_gateway/adapter/ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from bleak.backends.device import BLEDevice



LOG_CONFIG_PATH = "settings/logging.conf"

logging.config.fileConfig(LOG_CONFIG_PATH)
Expand All @@ -23,40 +22,41 @@ class Ble:
def __init__(self, gateway) -> None:
self._gateway = gateway

self._client: BleakClient
self._isConnected: bool = False
self._connected_device: BLEDevice
self._client: BleakClient | None
self._is_connected: bool = False
self._connected_device: BLEDevice | None
self._callback: Callable

def _set_client(self, device: BLEDevice):
self._client = BleakClient(device.address, self._on_disconnect)
self._connected_device = device

async def connect_device(self, device: BLEDevice):
if self._isConnected:
if self._is_connected:
return
self._set_client(device=device)
logger.info("Im Connector {}: {}".format(device.name, device.address))
logger.info(f"Im Connector {device.name}: {device.address}")
try:
await self._client.connect()
self._isConnected = self._client.is_connected
if self._isConnected:
self._is_connected = self._client.is_connected
if self._is_connected:
logger.info(f"Connected to {device.name}")
for service in self._client.services:
logger.info("Services: {}".format(service))
logger.info(f"Services: {service}")
for char in service.characteristics:
logger.info("Char: {}".format(char))
logger.info(f"Char: {char}")
while True:
if not self._isConnected:
if not self._is_connected:
break
await asyncio.sleep(5.0)
except Exception as e:
logger.error("Exeption: {}".format(e))
logger.error(f"Exeption: {e}")
self._connected_device = None
self._client = None

async def disconnect_device(self):
await self._client.disconnect()
self._isConnected = False
self._is_connected = False

async def cleanup(self):
if self._client is not None:
Expand All @@ -65,22 +65,21 @@ async def cleanup(self):
async def _on_disconnect(self, client: BleakClient):
logger.info(f"Disconnected from {self._connected_device.name}!")
self._connected_device = None
self._isConnected = False
self._is_connected = False

async def write_command(self, uuid: str, byte_data):
try:
await self._client.write_gatt_char(uuid, byte_data)
logger.info(f"Send {byte_data} to Periphal")
except Exception as e:
logger.error("Exeption: {}".format(e))
logger.error(f"Exeption: {e}")

async def getNotification(self, uuid: str, callback: Callable) -> None:
async def get_notification(self, uuid: str, callback: Callable) -> None:
self._callback = callback
await self._client.start_notify(uuid, self.on_distance_notification)

async def on_distance_notification(self, sender: int, data: bytearray):
logger.info(f"Daten in Notfiy Function: {data}")

try:
logger.info(struct.calcsize("15s 15s H I I f H f f"))
logger.info(len(data))
Expand All @@ -100,11 +99,11 @@ async def on_distance_notification(self, sender: int, data: bytearray):
logger.info("Test")
except Exception as e:
logger.error(f"Execption: {e}")
msg_type = msg_type_b.decode("utf-8")
state = state_b.decode("utf-8")
# logger.info("From Handle {} Msg_Type: {}".format(sender, msg_type))
# logger.info("From Handle {} Sequence: {}".format(sender, sequence))
# logger.info(
# msg_type = msg_type_b.decode("utf-8")
# state = state_b.decode("utf-8")
# logger.debug("From Handle {} Msg_Type: {}".format(sender, msg_type))
# logger.debug("From Handle {} Sequence: {}".format(sender, sequence))
# logger.debug(
# "From Handle {} Measurements: {}".format(sender, measurements)
# )
# logger.debug("From Handle {} Distance: {}".format(sender, distance))
Expand All @@ -115,9 +114,10 @@ async def on_distance_notification(self, sender: int, data: bytearray):
responder, sequence, measurements, distance, nlos, rssi, fpi
)

def isConnected(self):
return self._isConnected
def is_connected(self):
return self._is_connected

def getDeviceName(self) -> str:
def get_device_name(self) -> str:
if self._connected_device is not None:
return self._connected_device.name
return ""
3 changes: 3 additions & 0 deletions apps/sit_gateway/domain/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class DisconnectBleDevice(Command):
class StartDistanceMeasurement(Command):
initiator: str
responder: list[str]
measurement_type: str = "ds_3_twr"
rx_ant_dly: int = 16385
tx_ant_dly: int = 16385

Expand All @@ -62,6 +63,7 @@ class StartTestMeasurement(Command):
responder: list[str]
min_measurement: int
max_measurement: int
measurement_type: str = "ds_3_twr"
rx_ant_dly: int = 0
tx_ant_dly: int = 0

Expand All @@ -71,6 +73,7 @@ class StartCalibrationMeasurement(Command):
calibration_id: int
devices: list[str]
max_measurement: int
measurement_type: str = "ds_3_twr"
rx_ant_dly: int = 0
tx_ant_dly: int = 0

Expand Down
3 changes: 3 additions & 0 deletions apps/sit_gateway/domain/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class DistanceMeasurement(Event):
initiator: str
responder: str
sequence: int
measurement_type: str
measurement: int
distance: float
nlos: int
Expand All @@ -61,6 +62,7 @@ class TestMeasurement(Event):
test_id: int
initiator: str
responder: str
measurement_type: str
sequence: int
measurement: int
distance: float
Expand All @@ -74,6 +76,7 @@ class CalibrationMeasurement(Event):
claibration_id: int
initiator: str
responder: str
measurement_type: str
sequence: int
measurement: int
distance: float
Expand Down
29 changes: 17 additions & 12 deletions apps/sit_gateway/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def __init__(self) -> None:
self.test_id = None
self.calibration_id: int = 0
self._distance_notify_tasks = set()
self.measurement_type = "ss_twr"
self.initiator_device: str
self.responder_devices: list[str]

def set_dependencies(self, tg, bus):
self.taskGroup = tg
Expand All @@ -50,7 +53,7 @@ async def start_ble_gateway(self, device_id: str) -> None:
if ble is not None:
await asyncio.sleep(5.0)
# TODO
if ble.isConnected():
if ble.is_connected():
self.ble_list.append(ble)
await self.bus.handle(
events.BleDeviceConnected(device_id=device_id)
Expand Down Expand Up @@ -85,12 +88,11 @@ async def scan(self, timeout: float = 10.0) -> list[BLEDevice]:

async def connect_ble(self, device_name) -> Ble | None:
devices = await self.scan(20)
logger.info(devices)
for device in devices:
if device_name in device.name:
ble = Ble(self)
logger.info("{}: {}".format(device.name, device.address))
logger.info("UUIDs: {}".format(device.metadata["uuids"]))
logger.info(f"{device.name}: {device.address}")
logger.info(f"UUIDs: {device.metadata['uuids']}")
task_name = (
"Ble Task " + device_name
) # BLE TASK with Device Name to identify the Task
Expand Down Expand Up @@ -120,8 +122,6 @@ async def start_measurement(
"6ba1de6b-3ab6-4d77-9ea1-cb6422720003", command, initiator_device
)

# TODO Notify für alle Devices Erstellen und dann in ein Set Speichern
# beachte die Hinweiße hier: https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task
self.taskGroup.create_task(
self.enable_notify(initiator_device),
name="BLE Notify" + initiator_device,
Expand Down Expand Up @@ -150,7 +150,7 @@ async def enable_notify(self, initiator_device):
enable_notify = False
device = self.get_device(initiator_device)
while 1:
if device.isConnected() and not enable_notify:
if device.is_connected() and not enable_notify:
await device.getNotification(
"6ba1de6b-3ab6-4d77-9ea1-cb6422720001",
self.distance_notifcation,
Expand All @@ -161,13 +161,13 @@ async def enable_notify(self, initiator_device):
async def distance_notifcation(
self, responder, sequence, measurement, distance, nlos, rssi, fpi
):
print(f"Test: {distance}")
if self.test_id is not None:
await self.bus.handle(
events.TestMeasurement(
test_id=self.test_id,
initiator=self.initiator_device,
responder=self.get_responder(responder),
measurement_type=self.measurement_type,
sequence=sequence,
measurement=measurement,
distance=distance,
Expand All @@ -182,6 +182,7 @@ async def distance_notifcation(
claibration_id=self.calibration_id,
initiator=self.initiator_device,
responder=self.get_responder(responder),
measurement_type=self.measurement_type,
sequence=sequence,
measurement=measurement,
distance=distance,
Expand All @@ -200,6 +201,7 @@ async def distance_notifcation(
events.DistanceMeasurement(
initiator=self.initiator_device,
responder=self.get_responder(responder),
measurement_type=self.measurement_type,
sequence=sequence,
measurement=measurement,
distance=distance,
Expand Down Expand Up @@ -232,16 +234,16 @@ async def setup_calibration(
"responder": 1,
"min_measurement": 0,
"max_measurement": calibration_setup.max_measurement,
"measurement_type": calibration_setup.measurement_type,
"rx_ant_dly": calibration_setup.rx_ant_dly,
"tx_ant_dly": calibration_setup.tx_ant_dly,
}
await self.bus.handle(commands.StartSingleCalibrationMeasurement())

async def start_calibration(self):
print("Test")
print(f"Cali Round: {self.cali_rounds}")
print(f"Cali Liste: {self.cali_device_list}")
print(f"Cali Finished Len: {len(self.cali_finished_list)}")
logger.info(f"Cali Round: {self.cali_rounds}")
logger.info(f"Cali Liste: {self.cali_device_list}")
logger.info(f"Cali Finished Len: {len(self.cali_finished_list)}")
if self.cali_rounds > len(self.cali_finished_list):
cali_devices = self.cali_device_list.pop(0)
self.cali_setup["initiator_device"] = cali_devices[0]
Expand Down Expand Up @@ -293,6 +295,9 @@ async def ble_send_int(
logger.error("Cound't write Int Command")

# Utils Gateway Functions
async def set_measurement_type(self, measurement_type: str) -> None:
self.measurement_type = measurement_type

def get_device_index(self, device_name: str) -> int | None:
index = 0
for device in self.ble_list:
Expand Down
2 changes: 2 additions & 0 deletions apps/sit_gateway/service_layer/handler/command_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ async def start_measurement(
"responder": len(command.responder),
"min_measurement": 0,
"max_measurement": 0,
"measurement_type": command.measurement_type,
"rx_ant_dly": command.rx_ant_dly,
"tx_ant_dly": command.tx_ant_dly,
}
Expand All @@ -63,6 +64,7 @@ async def start_measurement(
"6ba1de6b-3ab6-4d77-9ea1-cb6422720004", setup, responder
)
await asyncio.sleep(3)
await gateway.set_measurement_type(command.measurement_type)
await gateway.start_measurement(
initiator_device=command.initiator,
responder_devices=command.responder,
Expand Down
11 changes: 8 additions & 3 deletions apps/sit_gateway/service_layer/handler/event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ async def send_distance_measurement(
"data": {
"initiator": event.initiator,
"responder": event.responder,
"measurement_type": event.measurement_type,
"sequence": event.sequence,
"measurement": event.measurement,
"distance": event.distance,
Expand All @@ -56,6 +57,7 @@ async def send_test_measurement(
"test_id": event.test_id,
"initiator": event.initiator,
"responder": event.responder,
"measurement_type": event.measurement_type,
"sequence": event.sequence,
"measurement": event.measurement,
"distance": event.distance,
Expand All @@ -76,6 +78,7 @@ async def send_calibration_measurement(
"calibration_id": event.claibration_id,
"initiator": event.initiator,
"responder": event.responder,
"measurement_type": event.measurement_type,
"sequence": event.sequence,
"measurement": event.measurement,
"distance": event.distance,
Expand All @@ -88,9 +91,11 @@ async def send_calibration_measurement(


async def redirect_event(
event: events.BleDeviceConnectFailed
| events.BleDeviceConnectError
| events.CalibrationMeasurementFinished,
event: (
events.BleDeviceConnectFailed
| events.BleDeviceConnectError
| events.CalibrationMeasurementFinished
),
ws: websocket.Websocket,
):
message = event.json
Expand Down
20 changes: 17 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# Standard Library
import asyncio
import logging
import logging.config

# Library
from apps.sit_gateway import bootstrap
Expand All @@ -10,23 +12,35 @@
from apps.sit_gateway.service_layer import uow
from apps.sit_gateway.service_layer.utils import cancel_task

LOG_CONFIG_PATH = "settings/logging.conf"

# Load logging configuration
logging.config.fileConfig(LOG_CONFIG_PATH)
logger = logging.getLogger("main")

gateway = SITGateway()
ws = websocket.Websocket()
bus = bootstrap.bootstrap(uow.UnitOfWork(), ws, gateway)


async def main():
"""
Main function of the application.
It creates a TaskGroup to run multiple asynchronous tasks concurrently.
It sets the dependencies for the gateway and creates the main Websocket task.
It also handles exceptions and performs cleanup when the application is stopped.
"""
async with asyncio.TaskGroup() as tg:
gateway.set_dependencies(tg, bus)
try:
task = tg.create_task(ws.connect(bus), name="Websocket Main Task")
await task
except KeyboardInterrupt:
print()
print("User stopped program.")
logger.info("User stopped program.")
except Exception as e:
logger.error(f"An error occurred: {e}")
finally:
print("Disconnecting...")
logger.info("Disconnecting...")
cancel_task("Notify Task")
cancel_task("Websocket Main Task")
await gateway.cleanup()
Expand Down
Loading

0 comments on commit ceb8b3a

Please sign in to comment.