Source code for toio.cube.api.indicator
# -*- coding: utf-8 -*-
# ************************************************************
#
# indicator.py
#
# Copyright 2022 Sony Interactive Entertainment Inc.
#
# ************************************************************
from __future__ import annotations
import struct
from dataclasses import dataclass
from typing_extensions import List, Sequence, Union
from ...device_interface import CubeInterface, GattReadData
from ...logger import get_toio_logger
from ...toio_uuid import ToioUuid
from ...utility import clip
from ..api.base_class import CubeCharacteristic, CubeCommand
from ..notification_handler_info import NotificationReceivedDevice
logger = get_toio_logger(__name__)
[docs]@dataclass
class Color:
"""
Indicator color in RGB
"""
r: int
"""R value (0 - 255)"""
g: int
"""G value (0 - 255)"""
b: int
"""B value (0 - 255)"""
[docs] def flatten(self):
"""
Return the tuple representation of this dataclass
"""
r = clip(self.r, 0, 255)
g = clip(self.g, 0, 255)
b = clip(self.b, 0, 255)
return r, g, b
[docs]@dataclass
class IndicatorParam:
"""
Indicator color and lighting period
"""
duration_ms: int
"""
| Duration of lighting:
| Any fraction less than 10ms will be truncated.
| 0 - 9: no time limit
| 10 - 2550: duration [ms]
"""
color: Color
"""
| RGB value
"""
[docs] @staticmethod
def from_int(duration_ms: int, r: int, g: int, b: int) -> IndicatorParam:
return IndicatorParam(duration_ms=duration_ms, color=Color(r=r, g=g, b=b))
[docs] def flatten(self):
duration = clip(int(self.duration_ms / 10), 0, 255)
return duration, 0x01, 0x01, *self.color.flatten()
[docs]class TurningOnAndOff(CubeCommand):
"""
Indicator turning on / off command
References:
https://toio.github.io/toio-spec/en/docs/ble_light#turning-the-indicator-on-and-off
"""
_payload_id = 0x03
_converter = struct.Struct("<BBBBBBB")
[docs] def __init__(self, param: IndicatorParam):
self.param = param
[docs] def __bytes__(self) -> bytes:
return self._converter.pack(self._payload_id, *self.param.flatten())
[docs]class RepeatedTurningOnAndOff(CubeCommand):
"""
Repeated indicator turning on /off command
References:
https://toio.github.io/toio-spec/en/docs/ble_light#repeated-turning-on-and-off-of-indicator
"""
_payload_id = 0x04
_converter = struct.Struct("<BBB")
REPEAT_INFINITE = 0
[docs] def __init__(
self,
repeat: int,
param_list: Sequence[IndicatorParam],
) -> None:
self.repeat = repeat
self.param_list = param_list
[docs] def __bytes__(self) -> bytes:
byte_representation = self._converter.pack(
self._payload_id, self.repeat, len(self.param_list)
)
for param in self.param_list:
byte_representation = byte_representation + struct.pack(
"<BBBBBB", *param.flatten()
)
return byte_representation
[docs]class TurnOffAll(CubeCommand):
"""
Indicator all off command
References:
https://toio.github.io/toio-spec/en/docs/ble_light#turn-off-all-indicators
"""
_payload_id = 0x01
[docs] def __init__(self) -> None:
pass
[docs] def __bytes__(self) -> bytes:
return bytes((self._payload_id,))
[docs]class TurnOff(CubeCommand):
"""
Indicator off command
References:
https://toio.github.io/toio-spec/en/docs/ble_light#turn-off-a-specific-indicator
"""
_payload_id = 0x02
_converter = struct.Struct("<BBB")
[docs] def __init__(self, indicator_id: int) -> None:
self.indicator_id = indicator_id
[docs] def __bytes__(self) -> bytes:
return self._converter.pack(self._payload_id, 0x01, self.indicator_id)
[docs]class Indicator(CubeCharacteristic):
"""
Indicator characteristic
References:
https://toio.github.io/toio-spec/en/docs/ble_light
"""
[docs] @staticmethod
def is_my_data(_payload: GattReadData) -> None:
return None
[docs] def __init__(self, interface: CubeInterface, device: NotificationReceivedDevice):
self.interface = interface
super().__init__(interface, ToioUuid.Light.value, device)
[docs] async def turn_on(self, param: Union[IndicatorParam, Sequence[int]]) -> None:
"""
Send indicator turn on / off command
Args:
param (Union[IndicatorParam, Sequence[int]]): Indicator parameter
References:
https://toio.github.io/toio-spec/en/docs/ble_light#repeated-turning-on-and-off-of-indicator
"""
if isinstance(param, Sequence):
param = IndicatorParam.from_int(*param)
turn_on = TurningOnAndOff(param)
await self._write(bytes(turn_on))
[docs] async def repeated_turn_on(
self,
repeat: int,
param_list: Union[Sequence[IndicatorParam], Sequence[Sequence[int]]],
) -> None:
"""
Send repeated indicator turning on / off command
Args:
repeat (int): Number of repetitions
param_list (Union[Sequence[IndicatorParam], Sequence[Sequence[int]]]): List of indicator parameters
References:
https://toio.github.io/toio-spec/en/docs/ble_light#repeated-turning-on-and-off-of-indicator
"""
params: List[IndicatorParam] = []
for param in param_list:
if isinstance(param, Sequence):
params.append(IndicatorParam.from_int(*param))
elif isinstance(param, IndicatorParam):
params.append(param)
else:
raise ValueError("wrong value is found in param_list: %s", str(param))
repeated = RepeatedTurningOnAndOff(repeat, params)
await self._write(bytes(repeated))
[docs] async def turn_off_all(self) -> None:
"""
Send all off command
References:
https://toio.github.io/toio-spec/en/docs/ble_light#turn-off-all-indicators
"""
turn_off = TurnOffAll()
await self._write(bytes(turn_off))
[docs] async def turn_off(self, indicator_id: int) -> None:
"""
Send off command
Args:
indicator_id (int): Indicator ID
References:
https://toio.github.io/toio-spec/en/docs/ble_light#turn-off-a-specific-indicator
"""
turn_off = TurnOff(indicator_id)
await self._write(bytes(turn_off))