Beispiel #1
0
class DescriptorDotNet(Descriptor):
    """The Descriptor DotNet Class"""

    def __init__(self, characteristic, d_object, loop=None):
        super(DescriptorDotNet, self).__init__(characteristic)
        self.loop = loop if loop else asyncio.get_event_loop()
        self.characteristic = characteristic
        self.uuid = d_object.Uuid.ToString()
        self.d_object = d_object
        self._uwp_bluetooth = UWPBluetooth()

    async def read_value(self):
        """Read Characteristic Descriptor"""
        # print("Get Characteristics for {0}...".format(self.s_object.Uuid.ToString()))
        if not self.characteristic:
            raise Exception(
                "Characteristic {0} was not found!".format(self.uuid)
            )

        read_results = await wrap_dotnet_task(
            self._uwp_bluetooth.ReadDescriptorValueAsync(
                self.characteristic.c_object
            ),
            loop=self.loop,
        )
        if read_results.Item2:
            status, value = read_results.Item1, bytearray(read_results.Item2)
            if status == GattCommunicationStatus.Success:
                # print("Read Characteristic {0} : {1}".format(uuid, value))
                pass
            else:
                raise Exception(
                    "Could not read descriptor value for {0}: {1}",
                    self.characteristic.Uuid.ToString(),
                    status,
                )
        else:
            return None

        return list(value)
Beispiel #2
0
class DeviceDotNet(Device):
    """The Device Base Class"""
    def __init__(self, address, loop=None):
        super(DeviceDotNet, self).__init__(loop)
        self.loop = loop if loop else asyncio.get_event_loop()
        self.address_hex = hex(address)
        self.address = address
        self.properties = None
        # UWP .NET
        self._dotnet_task = None
        self._uwp_bluetooth = UWPBluetooth()
        self._devices = {}
        self.services_resolved = None
        self.is_services_resolved = False
        self.connect_succeeded = None
        self.disconnect_succeeded = None
        self.services_resolved = None

    @property
    def name(self):
        raise NotImplementedError()

    async def connect(self):
        """Connect to device"""

        # Initiate Connection
        self._dotnet_task = await wrap_dotnet_task(
            self._uwp_bluetooth.FromBluetoothAddressAsync(self.address),
            loop=self.loop)

        def _ConnectionStatusChanged_Handler(sender, args):
            print("_ConnectionStatusChanged_Handler: " + args.ToString())

        # Not Working for some reason?
        self._dotnet_task.ConnectionStatusChanged += _ConnectionStatusChanged_Handler

        # Discover Services
        await self.discover_services()

    async def disconnect(self):
        """Disconnect to device"""
        self._dotnet_task.Dispose()
        self._dotnet_task = None

    async def is_connected(self):
        if self._dotnet_task:
            return (self._dotnet_task.ConnectionStatus ==
                    BluetoothConnectionStatus.Connected)

        else:
            return False

    def _services_resolved(self):
        # Notify User that Services have been Discovered
        self.is_services_resolved = True
        if self.services_resolved != None:
            self.services_resolved()

    async def get_properties(self):
        """Get Device Properties"""
        raise NotImplementedError()

    async def discover_services(self):
        """Discover Device Services"""
        if self.services:
            return self.services
        else:
            # print("Get Services...")
            services = await wrap_dotnet_task(
                self._uwp_bluetooth.GetGattServicesAsync(self._dotnet_task),
                loop=self.loop,
            )
            if services.Status == GattCommunicationStatus.Success:
                self.services = [
                    Service(device=s.Device,
                            uuid=s.Uuid.ToString(),
                            s_object=s) for s in services.Services
                ]
            else:
                raise Exception("Could not get GATT services.")

            # Discover Characteristics for Each Service
            await asyncio.gather(*[
                asyncio.ensure_future(service.discover_characteristics(),
                                      loop=self.loop)
                for service in self.services
            ])
            self._services_resolved()

    async def read_char(self, uuid):
        """Read Service Char"""
        for s in self.services:
            for c in s.characteristics:
                if str(uuid) == c.uuid:
                    characteristic = c.c_object

        if not characteristic:
            raise Exception("Characteristic {0} was not found!".format(uuid))

        read_results = await wrap_dotnet_task(
            self._uwp_bluetooth.ReadCharacteristicValueAsync(characteristic),
            loop=self.loop,
        )
        status, value = read_results.Item1, bytearray(read_results.Item2)
        if status == GattCommunicationStatus.Success:
            # print("Read Characteristic {0} : {1}".format(uuid, value))
            pass
        else:
            raise Exception(
                "Could not read characteristic value for {0}: {1}",
                characteristic.Uuid.ToString(),
                status,
            )

        return list(value)

    async def write_char(self, uuid, data, response=False):
        """Write Service Char"""
        for s in self.services:
            for c in s.characteristics:
                if str(uuid) == c.uuid:
                    characteristic = c.c_object

        if not characteristic:
            raise Exception("Characteristic {0} was not found!".format(uuid))

        write_results = await wrap_dotnet_task(
            self._uwp_bluetooth.WriteCharacteristicValueAsync(
                characteristic, data, response),
            loop=self.loop,
        )
        if write_results == GattCommunicationStatus.Success:
            # print("Write Characteristic {0} : {1}".format(uuid, data))
            pass
        else:
            raise Exception(
                "Could not write value {0} to characteristic {1}: {2}",
                data,
                characteristic.Uuid.ToString(),
                write_results,
            )

    async def start_notify(self, uuid, callback: Callable[[str, Any], Any],
                           **kwargs):
        """Start Notification Subscription"""
        # Find the Characteristic object
        for s in self.services:
            for c in s.characteristics:
                if str(uuid) == c.uuid:
                    characteristic = c.c_object

        if self._notification_callbacks.get(str(uuid)):
            await self.stop_notify(uuid)

        dotnet_callback = TypedEventHandler[GattCharacteristic, Array[Byte]](
            _notification_wrapper(callback))
        status = await wrap_dotnet_task(
            self._uwp_bluetooth.StartNotify(characteristic, dotnet_callback),
            loop=self.loop,
        )
        if status != GattCommunicationStatus.Success:
            raise Exception(
                "Could not start notify on {0}: {1}",
                characteristic.Uuid.ToString(),
                status,
            )

    async def stop_notify(self, uuid):
        """Stop Notification Subscription"""
        # Find the Characteristic object
        for s in self.services:
            for c in s.characteristics:
                if str(uuid) == c.uuid:
                    characteristic = c.c_object
        # THIS IS NOT CURRENTLY STOPPING NOTIFICATION IMMEDIATELY
        status = await wrap_dotnet_task(
            self._uwp_bluetooth.StopNotify(characteristic), loop=self.loop)
        if status != GattCommunicationStatus.Success:
            raise Exception(
                "Could not start notify on {0}: {1}",
                characteristic.Uuid.ToString(),
                status,
            )

    async def read_descriptor(self, uuid):
        """Read Characteristic Descriptor"""
        for s in self.services:
            for c in s.characteristics:
                if str(uuid) == c.uuid:
                    characteristic = c.c_object

        if not characteristic:
            raise Exception("Characteristic {0} was not found!".format(uuid))

        read_results = await wrap_dotnet_task(
            self._uwp_bluetooth.ReadDescriptorValueAsync(characteristic),
            loop=self.loop)
        if read_results.Item2:
            status, value = read_results.Item1, bytearray(read_results.Item2)
            if status == GattCommunicationStatus.Success:
                # print("Read Characteristic {0} : {1}".format(uuid, value))
                pass
            else:
                raise Exception(
                    "Could not read descriptor value for {0}: {1}",
                    characteristic.Uuid.ToString(),
                    status,
                )
        else:
            return None

        return list(value)