48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
from typing import Any, Dict, Iterable, List
|
|
from platypush.entities.bluetooth import BluetoothService
|
|
|
|
from ..._model import ServiceClass
|
|
|
|
|
|
# pylint: disable=too-few-public-methods
|
|
class BluetoothServicesBuilder:
|
|
"""
|
|
Builds a list of :class:`platypush.entities.bluetooth.BluetoothService`
|
|
entities from the list of dictionaries returned by
|
|
``bluetooth.find_services()``.
|
|
"""
|
|
|
|
@classmethod
|
|
def build(cls, services: Iterable[Dict[str, Any]]) -> List[BluetoothService]:
|
|
"""
|
|
Parse the services exposed by the device from the raw pybluez data.
|
|
"""
|
|
parsed_services = {}
|
|
|
|
for srv in services:
|
|
service_args = {
|
|
key: srv.get(key) for key in ['name', 'description', 'port', 'protocol']
|
|
}
|
|
|
|
classes = srv.get('service-classes', [])
|
|
versions = dict(srv.get('profiles', []))
|
|
|
|
for srv_cls in classes:
|
|
uuid = BluetoothService.to_uuid(srv_cls)
|
|
parsed_service = parsed_services[uuid] = BluetoothService(
|
|
id=f'{srv["host"]}::{srv_cls}',
|
|
uuid=uuid,
|
|
version=versions.get(srv_cls),
|
|
**service_args,
|
|
)
|
|
|
|
# Ensure that the service name is always set
|
|
if not parsed_service.name:
|
|
parsed_service.name = (
|
|
str(parsed_service.service_class)
|
|
if parsed_service.service_class != ServiceClass.UNKNOWN
|
|
else f'[{parsed_service.uuid}]'
|
|
)
|
|
|
|
return list(parsed_services.values())
|