Skip to content

Commit b044c0c

Browse files
feat: add IPC WebSocket example and enhance IPC client with device discovery and actions
1 parent 14caef4 commit b044c0c

File tree

6 files changed

+497
-24
lines changed

6 files changed

+497
-24
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,33 @@ ppg_red = dataset.ppg["ppg.red"]
3434
audio_df = dataset.get_audio_dataframe()
3535
```
3636

37+
## IPC WebSocket Example
38+
39+
```python
40+
import asyncio
41+
from open_wearable import OpenWearableIPCClient
42+
43+
44+
async def main() -> None:
45+
async with OpenWearableIPCClient() as client:
46+
await client.start_scan()
47+
devices = await client.get_discovered_devices()
48+
wearable = client.wearable(devices[0].id)
49+
50+
await wearable.connect()
51+
await wearable.actions.synchronize_time()
52+
53+
sensors = await wearable.actions.list_sensors()
54+
stream = await wearable.streams.sensor_values(sensor_id=sensors[0].sensor_id)
55+
async for event in stream:
56+
print(event.data)
57+
break
58+
await stream.close()
59+
60+
61+
asyncio.run(main())
62+
```
63+
3764
## Documentation
3865

3966
- [Documentation index](docs/README.md)

docs/api-reference.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,63 @@ Primary internal package layers:
1313
- `open_wearable.data`
1414
- `open_wearable.ipc`
1515

16+
## IPC Client (`open_wearable.ipc`)
17+
18+
`OpenWearableIPCClient` is an async JSON-RPC style client for
19+
`ws://127.0.0.1:8765/ws` by default.
20+
21+
### Connection Lifecycle
22+
23+
```python
24+
async with OpenWearableIPCClient() as client:
25+
await client.ping()
26+
```
27+
28+
### Discovery and Connection
29+
30+
- `start_scan(check_and_request_permissions=True)`
31+
- `start_scan_async(check_and_request_permissions=True) -> dict`
32+
- `start_scan_stream(check_and_request_permissions=True) -> StreamSubscription`
33+
- `get_discovered_devices() -> list[DiscoveredDevice]`
34+
- `connect_device(device_id, connected_via_system=False) -> WearableSummary`
35+
- `connect_system_devices(ignored_device_ids=None) -> list[WearableSummary]`
36+
- `list_connected() -> list[WearableSummary]`
37+
- `disconnect(device_id)`
38+
39+
### Action Sugar
40+
41+
- `client.synchronize_time(device_id)`
42+
- `client.list_sensors(device_id) -> list[SensorInfo]`
43+
- `client.list_sensor_configurations(device_id) -> list[SensorConfiguration]`
44+
- `client.set_sensor_configuration(device_id, configuration_name=..., value_key=...)`
45+
46+
Per-device handle:
47+
48+
```python
49+
wearable = client.wearable(device_id)
50+
await wearable.connect()
51+
await wearable.actions.synchronize_time()
52+
```
53+
54+
### Stream Sugar
55+
56+
Use the typed stream helpers:
57+
58+
```python
59+
stream = await wearable.streams.sensor_values(sensor_id="accelerometer_0")
60+
async for event in stream:
61+
print(event.data)
62+
```
63+
64+
Other helpers:
65+
66+
- `wearable.streams.sensor_configuration()`
67+
- `wearable.streams.button_events()`
68+
- `wearable.streams.battery_percentage()`
69+
- `wearable.streams.battery_power_status()`
70+
- `wearable.streams.battery_health_status()`
71+
- `wearable.streams.battery_energy_status()`
72+
1673
## `SensorDataset`
1774

1875
High-level API for loading and analyzing a single `.oe` recording.

src/open_wearable/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,40 @@
11
from .data import SensorDataset, load_recordings
22
from .ipc import (
3+
DiscoveredDevice,
34
IPCClosedError,
45
IPCError,
56
IPCProtocolError,
67
IPCRemoteError,
78
IPCStreamError,
89
OpenWearableIPCClient,
10+
SensorConfiguration,
11+
SensorConfigurationValue,
12+
SensorInfo,
913
StreamEvent,
1014
StreamSubscription,
15+
Wearable,
16+
WearableActions,
17+
WearableStreams,
18+
WearableSummary,
1119
)
1220

1321
__all__ = [
22+
"DiscoveredDevice",
1423
"IPCClosedError",
1524
"IPCError",
1625
"IPCProtocolError",
1726
"IPCRemoteError",
1827
"IPCStreamError",
1928
"OpenWearableIPCClient",
2029
"SensorDataset",
30+
"SensorConfiguration",
31+
"SensorConfigurationValue",
32+
"SensorInfo",
2133
"StreamEvent",
2234
"StreamSubscription",
35+
"Wearable",
36+
"WearableActions",
37+
"WearableStreams",
38+
"WearableSummary",
2339
"load_recordings",
2440
]

src/open_wearable/ipc/__init__.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
1-
from .client import OpenWearableIPCClient, StreamSubscription
1+
from .client import (
2+
OpenWearableIPCClient,
3+
StreamSubscription,
4+
Wearable,
5+
WearableActions,
6+
WearableStreams,
7+
)
28
from .errors import (
39
IPCClosedError,
410
IPCError,
511
IPCProtocolError,
612
IPCRemoteError,
713
IPCStreamError,
814
)
9-
from .models import StreamEvent
15+
from .models import (
16+
DiscoveredDevice,
17+
SensorConfiguration,
18+
SensorConfigurationValue,
19+
SensorInfo,
20+
StreamEvent,
21+
WearableSummary,
22+
)
1023

1124
__all__ = [
25+
"DiscoveredDevice",
1226
"IPCClosedError",
1327
"IPCError",
1428
"IPCProtocolError",
1529
"IPCRemoteError",
1630
"IPCStreamError",
1731
"OpenWearableIPCClient",
32+
"SensorConfiguration",
33+
"SensorConfigurationValue",
34+
"SensorInfo",
1835
"StreamEvent",
1936
"StreamSubscription",
37+
"Wearable",
38+
"WearableActions",
39+
"WearableStreams",
40+
"WearableSummary",
2041
]

0 commit comments

Comments
 (0)