toio-py-fork 1.1.0.post2.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- toio/__init__.py +175 -0
- toio/coordinate_systems.py +76 -0
- toio/cube/__init__.py +387 -0
- toio/cube/api/__init__.py +70 -0
- toio/cube/api/base_class.py +207 -0
- toio/cube/api/battery.py +86 -0
- toio/cube/api/button.py +97 -0
- toio/cube/api/configuration.py +1137 -0
- toio/cube/api/id_information.py +166 -0
- toio/cube/api/indicator.py +286 -0
- toio/cube/api/motor.py +630 -0
- toio/cube/api/sensor.py +360 -0
- toio/cube/api/sound.py +316 -0
- toio/cube/multi_cubes.py +241 -0
- toio/cube/notification_handler_info.py +118 -0
- toio/device_interface/__init__.py +135 -0
- toio/device_interface/ble.py +273 -0
- toio/device_interface/dummy.py +60 -0
- toio/device_interface/pythonista3corebluetooth/CentralManagerDelegate.py +370 -0
- toio/device_interface/pythonista3corebluetooth/PeripheralDelegate.py +670 -0
- toio/device_interface/pythonista3corebluetooth/__init__.py +9 -0
- toio/device_interface/pythonista3corebluetooth/characteristic.py +125 -0
- toio/device_interface/pythonista3corebluetooth/client.py +409 -0
- toio/device_interface/pythonista3corebluetooth/descriptor.py +49 -0
- toio/device_interface/pythonista3corebluetooth/objc_types.py +63 -0
- toio/device_interface/pythonista3corebluetooth/scanner.py +173 -0
- toio/device_interface/pythonista3corebluetooth/service.py +49 -0
- toio/device_interface/pythonista3corebluetooth/utils.py +56 -0
- toio/logger.py +56 -0
- toio/position.py +440 -0
- toio/py.typed +0 -0
- toio/scanner/__init__.py +16 -0
- toio/scanner/ble.py +216 -0
- toio/scanner/platform/windows_ble.py +68 -0
- toio/simple/__init__.py +952 -0
- toio/simple/async_simple.py +740 -0
- toio/standard_id.py +116 -0
- toio/toio_uuid.py +33 -0
- toio/utility.py +23 -0
- toio_py_fork-1.1.0.post2.dev1.dist-info/METADATA +590 -0
- toio_py_fork-1.1.0.post2.dev1.dist-info/RECORD +43 -0
- toio_py_fork-1.1.0.post2.dev1.dist-info/WHEEL +4 -0
- toio_py_fork-1.1.0.post2.dev1.dist-info/licenses/LICENSE +7 -0
toio/__init__.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ************************************************************
|
|
3
|
+
#
|
|
4
|
+
# toio/__init__.py
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2022 Sony Interactive Entertainment Inc.
|
|
7
|
+
#
|
|
8
|
+
# ************************************************************
|
|
9
|
+
|
|
10
|
+
from .coordinate_systems import (
|
|
11
|
+
ToioRelativeCoordinateSystem,
|
|
12
|
+
VisualProgrammingCoordinateSystem,
|
|
13
|
+
)
|
|
14
|
+
from .cube import ToioCoreCube
|
|
15
|
+
from .cube.api import ToioCoreCubeLowLevelAPI
|
|
16
|
+
from .cube.api.battery import Battery, BatteryInformation, BatteryResponseType
|
|
17
|
+
from .cube.api.button import Button, ButtonInformation, ButtonResponseType, ButtonState
|
|
18
|
+
from .cube.api.configuration import (
|
|
19
|
+
Configuration,
|
|
20
|
+
ConfigurationResponseType,
|
|
21
|
+
MagneticSensorCondition,
|
|
22
|
+
MagneticSensorFunction,
|
|
23
|
+
MotorSpeedInformationAcquisitionState,
|
|
24
|
+
NotificationCondition,
|
|
25
|
+
PostureAngleDetectionCondition,
|
|
26
|
+
PostureAngleDetectionType,
|
|
27
|
+
ProtocolVersion,
|
|
28
|
+
ResponseIdMissedNotificationSettings,
|
|
29
|
+
ResponseIdNotificationSettings,
|
|
30
|
+
ResponseMagneticSensorSettings,
|
|
31
|
+
ResponseMotorSpeedInformationAcquisitionSettings,
|
|
32
|
+
ResponsePostureAngleDetectionSettings,
|
|
33
|
+
)
|
|
34
|
+
from .cube.api.id_information import (
|
|
35
|
+
IdInformation,
|
|
36
|
+
IdInformationResponseType,
|
|
37
|
+
PositionId,
|
|
38
|
+
PositionIdMissed,
|
|
39
|
+
StandardId,
|
|
40
|
+
StandardIdMissed,
|
|
41
|
+
)
|
|
42
|
+
from .cube.api.indicator import Color, Indicator, IndicatorParam
|
|
43
|
+
from .cube.api.motor import (
|
|
44
|
+
AccelerationDirection,
|
|
45
|
+
AccelerationPriority,
|
|
46
|
+
AccelerationRotation,
|
|
47
|
+
Motor,
|
|
48
|
+
MotorResponseCode,
|
|
49
|
+
MotorResponseType,
|
|
50
|
+
MovementType,
|
|
51
|
+
ResponseMotorControlMultipleTargets,
|
|
52
|
+
ResponseMotorControlTarget,
|
|
53
|
+
ResponseMotorSpeed,
|
|
54
|
+
RotationOption,
|
|
55
|
+
Speed,
|
|
56
|
+
SpeedChangeType,
|
|
57
|
+
TargetPosition,
|
|
58
|
+
WriteMode,
|
|
59
|
+
)
|
|
60
|
+
from .cube.api.sensor import (
|
|
61
|
+
MagneticSensorData,
|
|
62
|
+
MotionDetectionData,
|
|
63
|
+
Posture,
|
|
64
|
+
PostureAngleEulerData,
|
|
65
|
+
PostureAngleQuaternionsData,
|
|
66
|
+
PostureDataType,
|
|
67
|
+
Sensor,
|
|
68
|
+
SensorResponseType,
|
|
69
|
+
)
|
|
70
|
+
from .cube.api.sound import MidiNote, Note, Sound, SoundId
|
|
71
|
+
from .cube.multi_cubes import MultipleToioCoreCubes
|
|
72
|
+
from .cube.notification_handler_info import (
|
|
73
|
+
NotificationHandlerInfo,
|
|
74
|
+
NotificationHandlerTypes,
|
|
75
|
+
)
|
|
76
|
+
from .position import (
|
|
77
|
+
CoordinateSystemABC,
|
|
78
|
+
CubeLocation,
|
|
79
|
+
DefaultCoordinateSystem,
|
|
80
|
+
MatRect,
|
|
81
|
+
Point,
|
|
82
|
+
RelativeCubeLocation,
|
|
83
|
+
ToioMat,
|
|
84
|
+
)
|
|
85
|
+
from .scanner import BLEScanner
|
|
86
|
+
|
|
87
|
+
__all__ = [
|
|
88
|
+
# .coordinate_system
|
|
89
|
+
"ToioRelativeCoordinateSystem",
|
|
90
|
+
"VisualProgrammingCoordinateSystem",
|
|
91
|
+
# .cube
|
|
92
|
+
"ToioCoreCube",
|
|
93
|
+
# .cube.multi_cubes
|
|
94
|
+
"MultipleToioCoreCubes",
|
|
95
|
+
# .cube.notification_handler_info
|
|
96
|
+
"NotificationHandlerInfo",
|
|
97
|
+
"NotificationHandlerTypes",
|
|
98
|
+
# .cube.api
|
|
99
|
+
"ToioCoreCubeLowLevelAPI",
|
|
100
|
+
# .cube.api.battery
|
|
101
|
+
"BatteryResponseType",
|
|
102
|
+
"BatteryInformation",
|
|
103
|
+
"Battery",
|
|
104
|
+
# .cube.api.button
|
|
105
|
+
"ButtonResponseType",
|
|
106
|
+
"ButtonState",
|
|
107
|
+
"ButtonInformation",
|
|
108
|
+
"Button",
|
|
109
|
+
# .cube.api.configuration
|
|
110
|
+
"ConfigurationResponseType",
|
|
111
|
+
"NotificationCondition",
|
|
112
|
+
"MagneticSensorFunction",
|
|
113
|
+
"MagneticSensorCondition",
|
|
114
|
+
"MotorSpeedInformationAcquisitionState",
|
|
115
|
+
"PostureAngleDetectionType",
|
|
116
|
+
"PostureAngleDetectionCondition",
|
|
117
|
+
"ProtocolVersion",
|
|
118
|
+
"ResponseIdNotificationSettings",
|
|
119
|
+
"ResponseIdMissedNotificationSettings",
|
|
120
|
+
"ResponseMagneticSensorSettings",
|
|
121
|
+
"ResponseMotorSpeedInformationAcquisitionSettings",
|
|
122
|
+
"ResponsePostureAngleDetectionSettings",
|
|
123
|
+
"Configuration",
|
|
124
|
+
# .cube.api.id_information
|
|
125
|
+
"IdInformationResponseType",
|
|
126
|
+
"PositionId",
|
|
127
|
+
"StandardId",
|
|
128
|
+
"PositionIdMissed",
|
|
129
|
+
"StandardIdMissed",
|
|
130
|
+
"IdInformation",
|
|
131
|
+
# .cube.api.indicator
|
|
132
|
+
"Color",
|
|
133
|
+
"IndicatorParam",
|
|
134
|
+
"Indicator",
|
|
135
|
+
# .cube.api.motor
|
|
136
|
+
"MotorResponseType",
|
|
137
|
+
"MovementType",
|
|
138
|
+
"RotationOption",
|
|
139
|
+
"TargetPosition",
|
|
140
|
+
"SpeedChangeType",
|
|
141
|
+
"Speed",
|
|
142
|
+
"WriteMode",
|
|
143
|
+
"AccelerationRotation",
|
|
144
|
+
"AccelerationDirection",
|
|
145
|
+
"AccelerationPriority",
|
|
146
|
+
"MotorResponseCode",
|
|
147
|
+
"ResponseMotorControlTarget",
|
|
148
|
+
"ResponseMotorControlMultipleTargets",
|
|
149
|
+
"ResponseMotorSpeed",
|
|
150
|
+
"Motor",
|
|
151
|
+
# .cube.api.sensor
|
|
152
|
+
"SensorResponseType",
|
|
153
|
+
"PostureDataType",
|
|
154
|
+
"Posture",
|
|
155
|
+
"MotionDetectionData",
|
|
156
|
+
"PostureAngleEulerData",
|
|
157
|
+
"PostureAngleQuaternionsData",
|
|
158
|
+
"MagneticSensorData",
|
|
159
|
+
"Sensor",
|
|
160
|
+
# .cube.api.sound
|
|
161
|
+
"SoundId",
|
|
162
|
+
"Note",
|
|
163
|
+
"MidiNote",
|
|
164
|
+
"Sound",
|
|
165
|
+
# .position
|
|
166
|
+
"Point",
|
|
167
|
+
"CubeLocation",
|
|
168
|
+
"MatRect",
|
|
169
|
+
"CoordinateSystemABC",
|
|
170
|
+
"DefaultCoordinateSystem",
|
|
171
|
+
"RelativeCubeLocation",
|
|
172
|
+
"ToioMat",
|
|
173
|
+
# .scanner
|
|
174
|
+
"BLEScanner",
|
|
175
|
+
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ************************************************************
|
|
3
|
+
#
|
|
4
|
+
# coordinate_systems.py
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2023 Sony Interactive Entertainment Inc.
|
|
7
|
+
#
|
|
8
|
+
# ************************************************************
|
|
9
|
+
|
|
10
|
+
from typing import Union
|
|
11
|
+
|
|
12
|
+
from .position import CoordinateSystemABC, Point
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ToioRelativeCoordinateSystem(CoordinateSystemABC):
|
|
16
|
+
def __init__(self, origin: Point = Point(x=0, y=0)):
|
|
17
|
+
self.native_origin = origin
|
|
18
|
+
|
|
19
|
+
def set_origin(self, origin: Point) -> None:
|
|
20
|
+
self.native_origin = origin
|
|
21
|
+
|
|
22
|
+
def to_native_angle(self, angle: Union[int, float]) -> Union[int, float]:
|
|
23
|
+
return angle % 360
|
|
24
|
+
|
|
25
|
+
def to_native_x(self, x: Union[int, float]) -> Union[int, float]:
|
|
26
|
+
return x + self.native_origin.x
|
|
27
|
+
|
|
28
|
+
def to_native_y(self, y: Union[int, float]) -> Union[int, float]:
|
|
29
|
+
return y + self.native_origin.y
|
|
30
|
+
|
|
31
|
+
def from_native_angle(self, angle: Union[int, float]) -> Union[int, float]:
|
|
32
|
+
return angle
|
|
33
|
+
|
|
34
|
+
def from_native_x(self, x: Union[int, float]) -> Union[int, float]:
|
|
35
|
+
return x - self.native_origin.x
|
|
36
|
+
|
|
37
|
+
def from_native_y(self, y: Union[int, float]) -> Union[int, float]:
|
|
38
|
+
return y - self.native_origin.y
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class VisualProgrammingCoordinateSystem(CoordinateSystemABC):
|
|
42
|
+
def __init__(self, origin: Point = Point(x=0, y=0)):
|
|
43
|
+
self.native_origin = origin
|
|
44
|
+
|
|
45
|
+
def set_origin(self, origin: Point) -> None:
|
|
46
|
+
self.native_origin = origin
|
|
47
|
+
|
|
48
|
+
def to_native_angle(self, angle: Union[int, float]) -> Union[int, float]:
|
|
49
|
+
angle = angle % 360
|
|
50
|
+
native_angle = angle + 270
|
|
51
|
+
return native_angle % 360
|
|
52
|
+
|
|
53
|
+
def to_native_x(self, x: Union[int, float]) -> Union[int, float]:
|
|
54
|
+
return x + self.native_origin.x
|
|
55
|
+
|
|
56
|
+
def to_native_y(self, y: Union[int, float]) -> Union[int, float]:
|
|
57
|
+
return (-1 * y) + self.native_origin.y
|
|
58
|
+
|
|
59
|
+
def from_native_angle(self, angle: Union[int, float]) -> Union[int, float]:
|
|
60
|
+
angle = angle % 360
|
|
61
|
+
vp_angle = angle - 270
|
|
62
|
+
if vp_angle < -180:
|
|
63
|
+
vp_angle += 360
|
|
64
|
+
return vp_angle
|
|
65
|
+
|
|
66
|
+
def from_native_x(self, x: Union[int, float]) -> Union[int, float]:
|
|
67
|
+
return x - self.native_origin.x
|
|
68
|
+
|
|
69
|
+
def from_native_y(self, y: Union[int, float]) -> Union[int, float]:
|
|
70
|
+
return -1 * (y - self.native_origin.y)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
LocalCoordinateSystem = Union[
|
|
74
|
+
ToioRelativeCoordinateSystem,
|
|
75
|
+
VisualProgrammingCoordinateSystem,
|
|
76
|
+
]
|
toio/cube/__init__.py
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ************************************************************
|
|
3
|
+
#
|
|
4
|
+
# toio/cube/__init__.py
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2022 Sony Interactive Entertainment Inc.
|
|
7
|
+
#
|
|
8
|
+
# ************************************************************
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
from uuid import UUID
|
|
14
|
+
|
|
15
|
+
from typing_extensions import (
|
|
16
|
+
Any,
|
|
17
|
+
Iterable,
|
|
18
|
+
List,
|
|
19
|
+
Optional,
|
|
20
|
+
Sequence,
|
|
21
|
+
Tuple,
|
|
22
|
+
Type,
|
|
23
|
+
TypeAlias,
|
|
24
|
+
Union,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
from ..device_interface import (
|
|
28
|
+
CubeInfo,
|
|
29
|
+
CubeInterface,
|
|
30
|
+
GattNotificationHandler,
|
|
31
|
+
GattReadData,
|
|
32
|
+
GattWriteData,
|
|
33
|
+
ScannerInterface,
|
|
34
|
+
)
|
|
35
|
+
from ..scanner import UniversalBleScanner
|
|
36
|
+
from .api import ToioCoreCubeLowLevelAPI
|
|
37
|
+
from .api.battery import Battery, BatteryInformation, BatteryResponseType
|
|
38
|
+
from .api.button import Button, ButtonInformation, ButtonResponseType, ButtonState
|
|
39
|
+
from .api.configuration import (
|
|
40
|
+
Configuration,
|
|
41
|
+
ConfigurationResponseType,
|
|
42
|
+
MagneticSensorCondition,
|
|
43
|
+
MagneticSensorFunction,
|
|
44
|
+
MotorSpeedInformationAcquisitionState,
|
|
45
|
+
NotificationCondition,
|
|
46
|
+
PostureAngleDetectionCondition,
|
|
47
|
+
PostureAngleDetectionType,
|
|
48
|
+
ProtocolVersion,
|
|
49
|
+
ResponseIdMissedNotificationSettings,
|
|
50
|
+
ResponseIdNotificationSettings,
|
|
51
|
+
ResponseMagneticSensorSettings,
|
|
52
|
+
ResponseMotorSpeedInformationAcquisitionSettings,
|
|
53
|
+
ResponsePostureAngleDetectionSettings,
|
|
54
|
+
)
|
|
55
|
+
from .api.id_information import (
|
|
56
|
+
IdInformation,
|
|
57
|
+
IdInformationResponseType,
|
|
58
|
+
PositionId,
|
|
59
|
+
PositionIdMissed,
|
|
60
|
+
StandardId,
|
|
61
|
+
StandardIdMissed,
|
|
62
|
+
)
|
|
63
|
+
from .api.indicator import Color, Indicator, IndicatorParam
|
|
64
|
+
from .api.motor import (
|
|
65
|
+
AccelerationDirection,
|
|
66
|
+
AccelerationPriority,
|
|
67
|
+
AccelerationRotation,
|
|
68
|
+
Motor,
|
|
69
|
+
MotorResponseCode,
|
|
70
|
+
MotorResponseType,
|
|
71
|
+
MovementType,
|
|
72
|
+
ResponseMotorControlMultipleTargets,
|
|
73
|
+
ResponseMotorControlTarget,
|
|
74
|
+
ResponseMotorSpeed,
|
|
75
|
+
RotationOption,
|
|
76
|
+
Speed,
|
|
77
|
+
SpeedChangeType,
|
|
78
|
+
TargetPosition,
|
|
79
|
+
WriteMode,
|
|
80
|
+
)
|
|
81
|
+
from .api.sensor import (
|
|
82
|
+
MagneticSensorData,
|
|
83
|
+
MotionDetectionData,
|
|
84
|
+
Posture,
|
|
85
|
+
PostureAngleEulerData,
|
|
86
|
+
PostureAngleQuaternionsData,
|
|
87
|
+
PostureDataType,
|
|
88
|
+
Sensor,
|
|
89
|
+
SensorResponseType,
|
|
90
|
+
)
|
|
91
|
+
from .api.sound import MidiNote, Note, Sound, SoundId
|
|
92
|
+
from .multi_cubes import MultipleToioCoreCubes
|
|
93
|
+
from .notification_handler_info import NotificationHandlerInfo, NotificationHandlerTypes
|
|
94
|
+
|
|
95
|
+
CubeInitializer: TypeAlias = Union[CubeInterface, CubeInfo]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class ToioCoreCube(CubeInterface):
|
|
99
|
+
"""
|
|
100
|
+
Access to toio Core Cube
|
|
101
|
+
|
|
102
|
+
Note:
|
|
103
|
+
- self.protocol_version is set after connecting to the cube.
|
|
104
|
+
- self.protocol_version and self.max_retry_to_get_protocol_version is supported since v1.1.0.
|
|
105
|
+
- basic scan function is supported since v1.1.0.
|
|
106
|
+
|
|
107
|
+
When Toio is initialized with no arguments, the scan() function can search for a cubes.
|
|
108
|
+
scan() can be followed by a call to the connect() function to connect
|
|
109
|
+
to multiple cubes.
|
|
110
|
+
|
|
111
|
+
If you initialize ToioCoreCube with a CubeInfo or a CubeInterface,
|
|
112
|
+
you can connect to specified cube by calling the connect() function.
|
|
113
|
+
In this case, the scan() function does not work.
|
|
114
|
+
|
|
115
|
+
ToioCoreCube is an asynchronous context manager.
|
|
116
|
+
When 'async with' is used, '__aenter__' handles the process up to connection,
|
|
117
|
+
and '__aexit__' handles the disconnection.
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Attributes:
|
|
121
|
+
interface (CubeInterface): control interface (e.g. BleCube)
|
|
122
|
+
name (str): cube name (optional)
|
|
123
|
+
api (ToioCoreCubeLowLevelAPI): API class
|
|
124
|
+
protocol_version (Optional[ProtocolVersion]): protocol version of the cube
|
|
125
|
+
max_retry_to_get_protocol_version (int): number of retries to get protocol version
|
|
126
|
+
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
SUPPORTED_MAJOR_VERSION: int = 2
|
|
130
|
+
SUPPORTED_MINOR_VERSION: int = 5
|
|
131
|
+
_LOCK: Optional[asyncio.Lock] = None
|
|
132
|
+
|
|
133
|
+
@staticmethod
|
|
134
|
+
def create(initializer: Union[CubeInitializer, Sequence]) -> ToioCoreCube:
|
|
135
|
+
"""
|
|
136
|
+
Supported toio.py versions: v1.1.0 or later
|
|
137
|
+
|
|
138
|
+
Create a ToioCoreCube instance from a CubeInterface or CubeInfo
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
initializer (CubeInitializer): initializer
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Optional[ToioCoreCube]:
|
|
145
|
+
"""
|
|
146
|
+
if (
|
|
147
|
+
isinstance(initializer, Sequence)
|
|
148
|
+
and not isinstance(initializer, CubeInterface)
|
|
149
|
+
and not isinstance(initializer, CubeInfo)
|
|
150
|
+
):
|
|
151
|
+
if len(initializer) < 1:
|
|
152
|
+
raise ValueError("no initializer")
|
|
153
|
+
first_initializer = initializer[0]
|
|
154
|
+
else:
|
|
155
|
+
first_initializer = initializer
|
|
156
|
+
|
|
157
|
+
if isinstance(first_initializer, CubeInterface):
|
|
158
|
+
return ToioCoreCube(interface=first_initializer)
|
|
159
|
+
elif isinstance(first_initializer, CubeInfo):
|
|
160
|
+
return ToioCoreCube(
|
|
161
|
+
interface=first_initializer.interface, name=first_initializer.name
|
|
162
|
+
)
|
|
163
|
+
else:
|
|
164
|
+
raise ValueError("wrong initializer: " + str(type(first_initializer)))
|
|
165
|
+
|
|
166
|
+
@staticmethod
|
|
167
|
+
def create_cubes(initializers: Iterable[CubeInitializer]) -> List[ToioCoreCube]:
|
|
168
|
+
"""
|
|
169
|
+
Supported toio.py versions: v1.1.0 or later
|
|
170
|
+
|
|
171
|
+
Create a ToioCoreCube instance list from a CubeInterface or CubeInfo list
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
initializers (Iterable[CubeInitializer]): initializers
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
List[ToioCoreCube]:
|
|
178
|
+
"""
|
|
179
|
+
cubes = []
|
|
180
|
+
for initializer in initializers:
|
|
181
|
+
cube = ToioCoreCube.create(initializer)
|
|
182
|
+
cubes.append(cube)
|
|
183
|
+
return cubes
|
|
184
|
+
|
|
185
|
+
def __init__(
|
|
186
|
+
self,
|
|
187
|
+
interface: Optional[CubeInitializer] = None,
|
|
188
|
+
name: Optional[str] = None,
|
|
189
|
+
scanner: Type[ScannerInterface] = UniversalBleScanner,
|
|
190
|
+
scanner_args: Sequence[Any] = (),
|
|
191
|
+
**kwargs: Any,
|
|
192
|
+
):
|
|
193
|
+
"""
|
|
194
|
+
Initialize a ToioCoreCube instance.
|
|
195
|
+
|
|
196
|
+
When keyword arguments are specified, they are passed to the scanner's scan() function.
|
|
197
|
+
|
|
198
|
+
Example:
|
|
199
|
+
>>> async with ToioCoreCube(strategy="quick") as cube:
|
|
200
|
+
>>> cube.api....()
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
interface (Optional[CubeInitializer]): cube interface, cube info, or None
|
|
204
|
+
name (Optional[str]): cube name
|
|
205
|
+
scanner (Type[ScannerInterface]): scanner interface
|
|
206
|
+
scanner_args (Sequence[Any]): arguments given to the scanner.scan() function
|
|
207
|
+
**kwargs (Any): keyword arguments given to the scanner.scan() function
|
|
208
|
+
"""
|
|
209
|
+
if ToioCoreCube._LOCK is None:
|
|
210
|
+
ToioCoreCube._LOCK = asyncio.Lock()
|
|
211
|
+
|
|
212
|
+
if interface is None:
|
|
213
|
+
self._scanning_required = True
|
|
214
|
+
self.interface = None
|
|
215
|
+
else:
|
|
216
|
+
self._scanning_required = False
|
|
217
|
+
if isinstance(interface, CubeInfo):
|
|
218
|
+
self.interface = interface.interface
|
|
219
|
+
if name is None:
|
|
220
|
+
name = interface.name
|
|
221
|
+
else:
|
|
222
|
+
self.interface = interface
|
|
223
|
+
self.name = name
|
|
224
|
+
self._scanner = scanner
|
|
225
|
+
self._scanner_args = scanner_args
|
|
226
|
+
self._scanner_kwargs = kwargs
|
|
227
|
+
|
|
228
|
+
self.protocol_version: Optional[ProtocolVersion] = None
|
|
229
|
+
self.max_retry_to_get_protocol_version: int = 10
|
|
230
|
+
|
|
231
|
+
async def __aenter__(self):
|
|
232
|
+
assert ToioCoreCube._LOCK is not None
|
|
233
|
+
async with ToioCoreCube._LOCK:
|
|
234
|
+
await self.scan()
|
|
235
|
+
await self.connect()
|
|
236
|
+
return self
|
|
237
|
+
|
|
238
|
+
async def __aexit__(self, exc_type, exc, tb):
|
|
239
|
+
await self.disconnect()
|
|
240
|
+
|
|
241
|
+
async def scan(self):
|
|
242
|
+
if self._scanning_required and self.interface is None:
|
|
243
|
+
device_list = await self._scanner().scan(
|
|
244
|
+
1, *self._scanner_args, **self._scanner_kwargs
|
|
245
|
+
)
|
|
246
|
+
if len(device_list):
|
|
247
|
+
self.interface = device_list[0].interface
|
|
248
|
+
if self.name is None:
|
|
249
|
+
self.name = device_list[0].name
|
|
250
|
+
|
|
251
|
+
async def connect(self) -> bool:
|
|
252
|
+
assert self.interface is not None
|
|
253
|
+
self.api = ToioCoreCubeLowLevelAPI(interface=self.interface, root_device=self)
|
|
254
|
+
connect_result = await self.interface.connect()
|
|
255
|
+
while not self.interface.is_connect():
|
|
256
|
+
await asyncio.sleep(0.1)
|
|
257
|
+
if connect_result is True:
|
|
258
|
+
self.protocol_version = None
|
|
259
|
+
await self.api.configuration.request_protocol_version()
|
|
260
|
+
retry_count = 0
|
|
261
|
+
while (
|
|
262
|
+
self.protocol_version is None
|
|
263
|
+
and retry_count < self.max_retry_to_get_protocol_version
|
|
264
|
+
):
|
|
265
|
+
retry_count += 1
|
|
266
|
+
received_data = await self.api.configuration._read()
|
|
267
|
+
if ProtocolVersion.is_myself(received_data):
|
|
268
|
+
self.protocol_version = ProtocolVersion(received_data)
|
|
269
|
+
await asyncio.sleep(0.1)
|
|
270
|
+
if self.protocol_version is not None:
|
|
271
|
+
if (
|
|
272
|
+
self.protocol_version._major != self.SUPPORTED_MAJOR_VERSION
|
|
273
|
+
or self.protocol_version._minor < self.SUPPORTED_MINOR_VERSION
|
|
274
|
+
):
|
|
275
|
+
import warnings
|
|
276
|
+
|
|
277
|
+
warnings.warn(
|
|
278
|
+
"protocol version %s is not supported by toio.py\n"
|
|
279
|
+
% self.protocol_version.version
|
|
280
|
+
+ "update cube firmware to latest version",
|
|
281
|
+
UserWarning,
|
|
282
|
+
)
|
|
283
|
+
return connect_result
|
|
284
|
+
|
|
285
|
+
async def disconnect(self) -> bool:
|
|
286
|
+
assert self.interface is not None
|
|
287
|
+
return await self.interface.disconnect()
|
|
288
|
+
|
|
289
|
+
async def read(self, char_uuid: UUID) -> GattReadData:
|
|
290
|
+
assert self.interface is not None
|
|
291
|
+
return await self.interface.read(char_uuid)
|
|
292
|
+
|
|
293
|
+
async def write(self, char_uuid: UUID, data: GattWriteData, response: bool = False):
|
|
294
|
+
assert self.interface is not None
|
|
295
|
+
return await self.interface.write(char_uuid, data, response)
|
|
296
|
+
|
|
297
|
+
async def register_notification_handler(
|
|
298
|
+
self, char_uuid: UUID, notification_handler: GattNotificationHandler
|
|
299
|
+
) -> bool:
|
|
300
|
+
assert self.interface is not None
|
|
301
|
+
return await self.interface.register_notification_handler(
|
|
302
|
+
char_uuid, notification_handler
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
async def unregister_notification_handler(self, char_uuid: UUID) -> bool:
|
|
306
|
+
assert self.interface is not None
|
|
307
|
+
return await self.interface.unregister_notification_handler(char_uuid)
|
|
308
|
+
|
|
309
|
+
def is_connect(self) -> bool:
|
|
310
|
+
assert self.interface is not None
|
|
311
|
+
return self.interface.is_connect()
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
__all__: Tuple[str, ...] = (
|
|
315
|
+
"CubeInitializer",
|
|
316
|
+
"ToioCoreCube",
|
|
317
|
+
"NotificationHandlerInfo",
|
|
318
|
+
"NotificationHandlerTypes",
|
|
319
|
+
"MultipleToioCoreCubes",
|
|
320
|
+
# .api
|
|
321
|
+
"ToioCoreCubeLowLevelAPI",
|
|
322
|
+
# .api.battery
|
|
323
|
+
"BatteryResponseType",
|
|
324
|
+
"BatteryInformation",
|
|
325
|
+
"Battery",
|
|
326
|
+
# .api.button
|
|
327
|
+
"ButtonResponseType",
|
|
328
|
+
"ButtonState",
|
|
329
|
+
"ButtonInformation",
|
|
330
|
+
"Button",
|
|
331
|
+
# .api.configuration
|
|
332
|
+
"ConfigurationResponseType",
|
|
333
|
+
"NotificationCondition",
|
|
334
|
+
"MagneticSensorFunction",
|
|
335
|
+
"MagneticSensorCondition",
|
|
336
|
+
"MotorSpeedInformationAcquisitionState",
|
|
337
|
+
"PostureAngleDetectionType",
|
|
338
|
+
"PostureAngleDetectionCondition",
|
|
339
|
+
"ProtocolVersion",
|
|
340
|
+
"ResponseIdNotificationSettings",
|
|
341
|
+
"ResponseIdMissedNotificationSettings",
|
|
342
|
+
"ResponseMagneticSensorSettings",
|
|
343
|
+
"ResponseMotorSpeedInformationAcquisitionSettings",
|
|
344
|
+
"ResponsePostureAngleDetectionSettings",
|
|
345
|
+
"Configuration",
|
|
346
|
+
# .api.id_information
|
|
347
|
+
"IdInformationResponseType",
|
|
348
|
+
"PositionId",
|
|
349
|
+
"StandardId",
|
|
350
|
+
"PositionIdMissed",
|
|
351
|
+
"StandardIdMissed",
|
|
352
|
+
"IdInformation",
|
|
353
|
+
# .api.indicator
|
|
354
|
+
"Color",
|
|
355
|
+
"IndicatorParam",
|
|
356
|
+
"Indicator",
|
|
357
|
+
# .api.motor
|
|
358
|
+
"MotorResponseType",
|
|
359
|
+
"MovementType",
|
|
360
|
+
"RotationOption",
|
|
361
|
+
"TargetPosition",
|
|
362
|
+
"SpeedChangeType",
|
|
363
|
+
"Speed",
|
|
364
|
+
"WriteMode",
|
|
365
|
+
"AccelerationRotation",
|
|
366
|
+
"AccelerationDirection",
|
|
367
|
+
"AccelerationPriority",
|
|
368
|
+
"MotorResponseCode",
|
|
369
|
+
"ResponseMotorControlTarget",
|
|
370
|
+
"ResponseMotorControlMultipleTargets",
|
|
371
|
+
"ResponseMotorSpeed",
|
|
372
|
+
"Motor",
|
|
373
|
+
# .api.sensor
|
|
374
|
+
"SensorResponseType",
|
|
375
|
+
"PostureDataType",
|
|
376
|
+
"Posture",
|
|
377
|
+
"MotionDetectionData",
|
|
378
|
+
"PostureAngleEulerData",
|
|
379
|
+
"PostureAngleQuaternionsData",
|
|
380
|
+
"MagneticSensorData",
|
|
381
|
+
"Sensor",
|
|
382
|
+
# .api.sound
|
|
383
|
+
"SoundId",
|
|
384
|
+
"Note",
|
|
385
|
+
"MidiNote",
|
|
386
|
+
"Sound",
|
|
387
|
+
)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ************************************************************
|
|
3
|
+
#
|
|
4
|
+
# toio/cube/api/__init__.py
|
|
5
|
+
#
|
|
6
|
+
# Copyright 2022 Sony Interactive Entertainment Inc.
|
|
7
|
+
#
|
|
8
|
+
# ************************************************************
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing_extensions import TypeAlias, Union
|
|
13
|
+
|
|
14
|
+
from ...device_interface import CubeInterface
|
|
15
|
+
from ..notification_handler_info import NotificationReceivedDevice
|
|
16
|
+
from .battery import Battery
|
|
17
|
+
from .button import Button
|
|
18
|
+
from .configuration import Configuration
|
|
19
|
+
from .id_information import IdInformation
|
|
20
|
+
from .indicator import Indicator
|
|
21
|
+
from .motor import Motor
|
|
22
|
+
from .sensor import Sensor
|
|
23
|
+
from .sound import Sound
|
|
24
|
+
|
|
25
|
+
API_VERSION = "2.4.0"
|
|
26
|
+
|
|
27
|
+
CubeApi: TypeAlias = Union[
|
|
28
|
+
Battery, Button, Configuration, IdInformation, Indicator, Motor, Sensor, Sound
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ToioCoreCubeLowLevelAPI:
|
|
33
|
+
"""
|
|
34
|
+
Control APIs
|
|
35
|
+
This class has control APIs for each characteristic.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
battery (api.Battery): Interface to `battery characteristic <https://toio.github.io/toio-spec/en/docs/ble_battery>`_
|
|
39
|
+
button (api.Button): Interface to `button characteristic <https://toio.github.io/toio-spec/en/docs/ble_button>`_
|
|
40
|
+
configuration (api.Configuration): Interface to `configuration characteristic <https://toio.github.io/toio-spec/en/docs/ble_configuration>`_
|
|
41
|
+
id_information (api.IdInformation): Interface to `id information characteristic <https://toio.github.io/toio-spec/en/docs/ble_id>`_
|
|
42
|
+
indicator (api.IdInformation): Interface to `indicator characteristic <https://toio.github.io/toio-spec/en/docs/ble_light>`_
|
|
43
|
+
motor (api.Motor): Interface to `motor characteristic <https://toio.github.io/toio-spec/en/docs/ble_motor>`_
|
|
44
|
+
sensor (api.Sensor): Interface to sensor characteristic (
|
|
45
|
+
`Motion <https://toio.github.io/toio-spec/en/docs/ble_sensor>`_
|
|
46
|
+
`Posture <https://toio.github.io/toio-spec/en/docs/ble_high_precision_tilt_sensor>`_
|
|
47
|
+
`Magnet <https://toio.github.io/toio-spec/en/docs/ble_magnetic_sensor>`_
|
|
48
|
+
)
|
|
49
|
+
sound (api.Sound): Interface to `sound characteristic <https://toio.github.io/toio-spec/en/docs/ble_sound>`_
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self, interface: CubeInterface, root_device: NotificationReceivedDevice
|
|
54
|
+
):
|
|
55
|
+
self._version = API_VERSION
|
|
56
|
+
self.battery = Battery(interface, root_device)
|
|
57
|
+
self.button = Button(interface, root_device)
|
|
58
|
+
self.configuration = Configuration(interface, root_device)
|
|
59
|
+
self.id_information = IdInformation(interface, root_device)
|
|
60
|
+
self.indicator = Indicator(interface, root_device)
|
|
61
|
+
self.motor = Motor(interface, root_device)
|
|
62
|
+
self.sensor = Sensor(interface, root_device)
|
|
63
|
+
self.sound = Sound(interface, root_device)
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def version(self) -> str:
|
|
67
|
+
DeprecationWarning(
|
|
68
|
+
"use ToioCoreCube.SUPPORTED_MAJOR_VERSION and ToioCoreCube.SUPPORTED_MINOR_VERSION"
|
|
69
|
+
)
|
|
70
|
+
return self._version
|