Skip to content
Merged

1.2.0 #248

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
acc131b
add websocket connector backend and ipc protocol server
DennisMoschina Feb 24, 2026
7683295
wire connectors settings page into app navigation and startup
DennisMoschina Feb 24, 2026
04903bc
use wearableConnector for connections in websocket to share connected…
DennisMoschina Feb 25, 2026
e16d90f
feat: Implement command structure for wearable connector
DennisMoschina Feb 25, 2026
e5eb9ee
feat: Add AsyncScanCommand for asynchronous scanning and event streaming
DennisMoschina Feb 26, 2026
b20a623
feat: Add WebSocket IPC API documentation for OpenWearable connector
DennisMoschina Feb 26, 2026
48f37ea
feat(connectors_page.dart): Update WebSocket IPC terminology and add …
DennisMoschina Mar 2, 2026
33ed2e4
feat: Implement device IP address resolution and integrate into conne…
DennisMoschina Mar 2, 2026
b539be6
feat: Update iOS project settings and dependencies
DennisMoschina Mar 3, 2026
6374e47
feat: Update WebSocket IPC server to resolve device IP address and im…
DennisMoschina Mar 3, 2026
93394fc
feat(connectors): migrate websocket audio playback to flutter_sound
DennisMoschina Mar 9, 2026
b2efa88
feat(connectors): add websocket audio commands with codec configuration
DennisMoschina Mar 9, 2026
081c22e
docs(connectors): document websocket audio sources and codec options
DennisMoschina Mar 9, 2026
7c255c5
feat(connectors): switch websocket audio playback to audioplayers
DennisMoschina Mar 10, 2026
6496812
docs(connectors): remove websocket audio streaming API docs
DennisMoschina Mar 10, 2026
60aeaf8
refactor(connectors): remove websocket URL audio playback
DennisMoschina Mar 10, 2026
0e76599
feat(settings): add keep app in foreground setting to disable automat…
DennisMoschina Mar 11, 2026
bb96f1f
refactor: regenerate generated files after rebase
DennisMoschina Apr 21, 2026
319fb25
fix(dependencies): remove flutter_sound plugin references from genera…
DennisMoschina Apr 22, 2026
45219bd
feat(connectors): show active connector indicator
DennisMoschina Apr 23, 2026
76686f4
fix(connectors): center active connector indicator
DennisMoschina Apr 23, 2026
f8181a8
feat(connectors): compact active connector indicator
DennisMoschina Apr 23, 2026
300a4f4
refactor(connectors): unify connector branding
DennisMoschina Apr 23, 2026
c7ee97a
chore(deps): update Flutter dependencies
DennisMoschina Apr 24, 2026
d34e96c
fix(logging): enable app file logs in release
DennisMoschina Apr 24, 2026
649beeb
Add mock wearable and sensor simulation functionality that reads form…
Josua019 Feb 6, 2026
6e406e6
Fix formatting issues in mock wearable sensor configuration
Josua019 Feb 6, 2026
b5a2724
Renamed MockWearable with ThisDeviceWearable
DennisMoschina Feb 9, 2026
90f96ec
Integrate device_info_plus for enhanced device profile management and…
DennisMoschina Feb 10, 2026
25b7bb1
open_wearable/lib/models/this_device_wearable.dart: Refactor ThisDevi…
DennisMoschina Feb 10, 2026
6410e14
open_wearable/ios/Runner/Info.plist: added key for motion data
DennisMoschina Feb 10, 2026
b857847
open_wearable/lib/models/this_device_wearable.dart: added configurabl…
DennisMoschina Feb 10, 2026
9b64a8b
open_wearable/lib/modles/this_device_wearable.dart: fixed bug where c…
DennisMoschina Feb 10, 2026
046ef8e
lib/widgets/devices/connect_devices_page.dart: display this device in…
DennisMoschina Feb 10, 2026
5950e08
open_wearable/lib/models/this_device_wearable.dart: implemented disco…
DennisMoschina Feb 10, 2026
d1005d5
open_wearable/lib/models/this_device_wearable.dart: fixed issues with…
DennisMoschina Feb 10, 2026
f91ed3e
feat(this_device_wearable): added more frequency options
DennisMoschina Apr 23, 2026
0ff058c
fix(sensors): default phone sensor sampling to off
DennisMoschina Apr 23, 2026
0823d61
chore(ios): refresh pod lock dependencies
DennisMoschina Apr 23, 2026
09296a5
refactor(this_device_wearable): refactor sensor registration and enha…
DennisMoschina Apr 24, 2026
978b0fa
feat(devices): show phone icon for host device
DennisMoschina Apr 24, 2026
8a95f9b
refactor(this_device_wearable): reorder gyroscope sensor registration…
DennisMoschina Apr 27, 2026
442fec1
feat(devices): use phone image for host device
DennisMoschina Apr 27, 2026
6e0f41e
fix(devices): normalize Android host device brand casing
DennisMoschina Apr 27, 2026
b4a126e
feat(devices): enhance device name display for current device
DennisMoschina Apr 27, 2026
519b17d
feat(connectors): track websocket network reachability
DennisMoschina Apr 27, 2026
f28027e
feat(connectors): move status pill into app bars
DennisMoschina Apr 27, 2026
80bbcb0
feat(connectors): link websocket documentation
DennisMoschina Apr 27, 2026
b5b0a85
fix(connectors): update status messages for network availability
DennisMoschina Apr 27, 2026
9f52ea4
docs(connectors): clarify usage of open-wearables package for Python …
DennisMoschina Apr 27, 2026
ad0dcd4
feat(release): add 1.2.0 whats new page
DennisMoschina Apr 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions open_wearable/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "3297454732841b1a5a25d9f35f1fd5d7a4479e12"
channel: "main"
revision: "f5a8537f90d143abd5bb2f658fa69c388da9677b"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 3297454732841b1a5a25d9f35f1fd5d7a4479e12
base_revision: 3297454732841b1a5a25d9f35f1fd5d7a4479e12
create_revision: f5a8537f90d143abd5bb2f658fa69c388da9677b
base_revision: f5a8537f90d143abd5bb2f658fa69c388da9677b
- platform: ios
create_revision: 3297454732841b1a5a25d9f35f1fd5d7a4479e12
base_revision: 3297454732841b1a5a25d9f35f1fd5d7a4479e12
create_revision: f5a8537f90d143abd5bb2f658fa69c388da9677b
base_revision: f5a8537f90d143abd5bb2f658fa69c388da9677b

# User provided section

Expand Down
254 changes: 254 additions & 0 deletions open_wearable/docs/connectors/websocket-ipc-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
# WebSocket IPC API

This document describes how to communicate with the OpenWearable WebSocket connector.

Python clients can use the [`open-wearables`](https://pypi.org/project/open-wearables/)
package instead of implementing the JSON WebSocket protocol directly.

## Endpoint

Default endpoint:

- `ws://<device-ip>:8765/ws`

Notes:

- The app binds the websocket server on all IPv4 interfaces and advertises the current device IP for clients on the same network.
- Port and path are configurable in app settings.
- The API is JSON over WebSocket text frames.

## Message Envelopes

Request:

```json
{"id":1,"method":"ping","params":{}}
```

Success response:

```json
{"id":1,"result":{"ok":true}}
```

Error response:

```json
{
"id": 1,
"error": {
"message": "Unknown method: foo",
"type": "UnsupportedError",
"stack": "..."
}
}
```

## Server Events

On connect, the server sends:

```json
{
"event": "ready",
"methods": ["ping", "methods", "..."],
"endpoint": "ws://192.168.1.23:8765/ws"
}
```

`ready.endpoint` may be `null` when the app cannot determine a client-reachable
LAN IP address. The connector still runs in that case.

Other event messages:

- `scan`: broadcast when a device is discovered.
- `connecting`: broadcast when a connect attempt starts.
- `connected`: broadcast when a wearable is connected.
- `stream`: stream subscription data.
- `stream_error`: error for a stream subscription.
- `stream_done`: stream finished.

`stream` event format:

```json
{
"event": "stream",
"subscription_id": 1,
"stream": "sensor_values",
"device_id": "string",
"data": {}
}
```

## Top-Level Methods

| Method | Params | Result |
|---|---|---|
| `ping` | `{}` | `{"ok":true}` |
| `methods` | `{}` | `string[]` |
| `has_permissions` | `{}` | `bool` |
| `check_and_request_permissions` | `{}` | `bool` |
| `start_scan` | `{"check_and_request_permissions"?:bool}` | `{"started":true}` |
| `start_scan_async` | `{"check_and_request_permissions"?:bool}` | `{"started":true,"subscription_id":int,"stream":"scan","device_id":"scanner"}` |
| `get_discovered_devices` | `{}` | `DiscoveredDevice[]` |
| `connect` | `{"device_id":string,"connected_via_system"?:bool}` | `WearableSummary` |
| `connect_system_devices` | `{"ignored_device_ids"?:string[]}` | `WearableSummary[]` |
| `list_connected` | `{}` | `WearableSummary[]` |
| `disconnect` | `{"device_id":string}` | `{"disconnected":true}` |
| `store_sound` | `{"sound_id":string,"audio_base64":string,"codec"?:string,"sample_rate"?:int,"num_channels"?:int,"interleaved"?:bool,"buffer_size"?:int}` | `{"sound_id":string,"stored":true,"bytes":int,"config":object}` |
| `play_sound` | `{"sound_id":string,"volume"?:number,"codec"?:string,"sample_rate"?:int,"num_channels"?:int}` | `{"source":"sound_id","sound_id":string,"playing":true,"config":object}` |
| `subscribe` | `{"device_id":string,"stream":string,"args"?:object}` | `{"subscription_id":int,"stream":string,"device_id":string}` |
| `unsubscribe` | `{"subscription_id":int}` | `{"subscription_id":int,"cancelled":bool}` |
| `invoke_action` | `{"device_id":string,"action":string,"args"?:object}` | depends on action |

## Action Commands (`invoke_action`)

Current actions:

- `disconnect` (no `args`)
- `synchronize_time`
- `list_sensors`
- `list_sensor_configurations`
- `set_sensor_configuration` with args:
- `{"configuration_name":string,"value_key":string}`

Examples:

```json
{"id":10,"method":"invoke_action","params":{"device_id":"abc","action":"synchronize_time"}}
```

```json
{"id":11,"method":"invoke_action","params":{"device_id":"abc","action":"set_sensor_configuration","args":{"configuration_name":"Accelerometer","value_key":"100Hz"}}}
```

## Subscribe Streams

Supported values for `subscribe.params.stream`:

- `sensor_values` (requires one of below in `args`)
- `{"sensor_id":string}` (recommended)
- `{"sensor_index":int}`
- `{"sensor_name":string}`
- `sensor_configuration`
- `button_events`
- `battery_percentage`
- `battery_power_status`
- `battery_health_status`
- `battery_energy_status`

Note:

- `scan` is not a direct `subscribe` stream.
- Use `start_scan_async` to receive scan data via `stream` events.

## Audio Playback Over WebSocket

The connector supports distinct preloaded sounds (store once, play many times).

### 1) Distinct Preloaded Sounds

Store sound bytes in memory:

```json
{
"id": 20,
"method": "store_sound",
"params": {
"sound_id": "beep_ok",
"audio_base64": "<base64-encoded-audio-bytes>"
}
}
```

Play a stored sound:

```json
{
"id": 21,
"method": "play_sound",
"params": {
"sound_id": "beep_ok",
"volume": 1.0
}
}
```

`play_sound` requires `sound_id`.

## Data Shapes

### DiscoveredDevice

```json
{
"id": "string",
"name": "string",
"service_uuids": ["string"],
"manufacturer_data": [1, 2, 3],
"rssi": -56
}
```

### WearableSummary

```json
{
"device_id": "string",
"name": "string",
"type": "OpenEarableV2",
"capabilities": ["SensorManager", "SensorConfigurationManager"]
}
```

### `list_sensors` item

```json
{
"sensor_id": "accelerometer_0",
"sensor_index": 0,
"name": "Accelerometer",
"chart_title": "Accelerometer",
"short_chart_title": "ACC",
"axis_names": ["x", "y", "z"],
"axis_units": ["m/s²", "m/s²", "m/s²"],
"timestamp_exponent": -9
}
```

### `list_sensor_configurations` item

```json
{
"name": "Accelerometer",
"unit": "Hz",
"values": [
{
"key": "100Hz",
"frequency_hz": 100,
"options": ["streamSensorConfigOption"]
}
],
"off_value": "off"
}
```

## Suggested Workflows

### Scan and connect

1. Call `start_scan` or `start_scan_async`.
2. Use `get_discovered_devices` (or consume stream events from `start_scan_async`).
3. Call `connect` with selected `device_id`.

### Sensor streaming

1. `invoke_action` with `action="list_sensors"`.
2. Pick `sensor_id`.
3. `subscribe` with `stream="sensor_values"` and `args={"sensor_id":"..."}`.
4. `unsubscribe` when done.

### Distinct sound playback

1. `store_sound` with `sound_id` and `audio_base64`.
2. `play_sound` with the same `sound_id`.
2 changes: 0 additions & 2 deletions open_wearable/ios/Flutter/Profile.xcconfig

This file was deleted.

2 changes: 1 addition & 1 deletion open_wearable/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '13.0'
platform :ios, '16.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
26 changes: 19 additions & 7 deletions open_wearable/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ PODS:
- audioplayers_darwin (0.0.1):
- Flutter
- FlutterMacOS
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.9):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
Expand Down Expand Up @@ -55,16 +57,18 @@ PODS:
- Flutter
- permission_handler_apple (9.3.0):
- Flutter
- SDWebImage (5.21.5):
- SDWebImage/Core (= 5.21.5)
- SDWebImage/Core (5.21.5)
- SDWebImage (5.21.7):
- SDWebImage/Core (= 5.21.7)
- SDWebImage/Core (5.21.7)
- sensors_plus (0.0.1):
- Flutter
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftCBOR (0.4.7)
- SwiftProtobuf (1.33.3)
- SwiftProtobuf (1.37.0)
- SwiftyGif (5.4.5)
- universal_ble (0.0.1):
- Flutter
Expand All @@ -77,6 +81,7 @@ PODS:

DEPENDENCIES:
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/darwin`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- file_selector_ios (from `.symlinks/plugins/file_selector_ios/ios`)
- Flutter (from `Flutter`)
Expand All @@ -85,6 +90,7 @@ DEPENDENCIES:
- open_file_ios (from `.symlinks/plugins/open_file_ios/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- sensors_plus (from `.symlinks/plugins/sensors_plus/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- universal_ble (from `.symlinks/plugins/universal_ble/darwin`)
Expand All @@ -105,6 +111,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
audioplayers_darwin:
:path: ".symlinks/plugins/audioplayers_darwin/darwin"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
file_selector_ios:
Expand All @@ -121,6 +129,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/package_info_plus/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
sensors_plus:
:path: ".symlinks/plugins/sensors_plus/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
Expand All @@ -134,6 +144,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Expand All @@ -145,17 +156,18 @@ SPEC CHECKSUMS:
open_file_ios: 46184d802ee7959203f6392abcfa0dd49fdb5be0
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
sensors_plus: 6a11ed0c2e1d0bd0b20b4029d3bad27d96e0c65b
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
SwiftCBOR: 465775bed0e8bac7bfb8160bcf7b95d7f75971e4
SwiftProtobuf: e1b437c8e31a4c5577b643249a0bb62ed4f02153
SwiftProtobuf: 3fafd1b2fb97e6d95ad9c8adb2215da9afec7c83
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
universal_ble: ff19787898040d721109c6324472e5dd4bc86adc
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c

PODFILE CHECKSUM: 251cb053df7158f337c0712f2ab29f4e0fa474ce
PODFILE CHECKSUM: 1857a7cdb7dfafe45f2b0e9a9af44644190f7506

COCOAPODS: 1.16.2
Loading
Loading