@voltras/node-sdk 0.1.2 → 0.2.0
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.
- package/README.md +122 -31
- package/dist/cjs/bluetooth/adapters/native.js +36 -34
- package/dist/cjs/bluetooth/adapters/native.js.map +1 -1
- package/dist/cjs/bluetooth/adapters/node.js +9 -7
- package/dist/cjs/bluetooth/adapters/node.js.map +1 -1
- package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js +6 -4
- package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js.map +1 -1
- package/dist/cjs/bluetooth/adapters/web.js +7 -5
- package/dist/cjs/bluetooth/adapters/web.js.map +1 -1
- package/dist/cjs/bluetooth/controllers/scanner-controller.js +0 -2
- package/dist/cjs/bluetooth/controllers/scanner-controller.js.map +1 -1
- package/dist/cjs/index.js +19 -10
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/hooks.js +2 -6
- package/dist/cjs/react/hooks.js.map +1 -1
- package/dist/cjs/sdk/notification-dispatcher.js +47 -0
- package/dist/cjs/sdk/notification-dispatcher.js.map +1 -0
- package/dist/cjs/sdk/reconnect-handler.js +61 -0
- package/dist/cjs/sdk/reconnect-handler.js.map +1 -0
- package/dist/cjs/sdk/voltra-client.js +206 -72
- package/dist/cjs/sdk/voltra-client.js.map +1 -1
- package/dist/cjs/shared/index.js +5 -1
- package/dist/cjs/shared/index.js.map +1 -1
- package/dist/cjs/shared/logger.js +54 -0
- package/dist/cjs/shared/logger.js.map +1 -0
- package/dist/cjs/voltra/index.js +15 -12
- package/dist/cjs/voltra/index.js.map +1 -1
- package/dist/cjs/voltra/models/device.js +13 -0
- package/dist/cjs/voltra/models/device.js.map +1 -1
- package/dist/cjs/voltra/protocol/commands.js +127 -210
- package/dist/cjs/voltra/protocol/commands.js.map +1 -1
- package/dist/cjs/voltra/protocol/constants/ble-config.js +24 -0
- package/dist/cjs/voltra/protocol/constants/ble-config.js.map +1 -0
- package/dist/cjs/voltra/protocol/constants/connection-commands.js +55 -0
- package/dist/cjs/voltra/protocol/constants/connection-commands.js.map +1 -0
- package/dist/cjs/voltra/protocol/constants/enums.js +117 -0
- package/dist/cjs/voltra/protocol/constants/enums.js.map +1 -0
- package/dist/cjs/voltra/protocol/constants/index.js +32 -0
- package/dist/cjs/voltra/protocol/constants/index.js.map +1 -0
- package/dist/cjs/voltra/protocol/constants/message-types.js +70 -0
- package/dist/cjs/voltra/protocol/constants/message-types.js.map +1 -0
- package/dist/cjs/voltra/protocol/constants/timing.js +21 -0
- package/dist/cjs/voltra/protocol/constants/timing.js.map +1 -0
- package/dist/cjs/voltra/protocol/data/protocol-data.generated.js +7 -0
- package/dist/cjs/voltra/protocol/data/protocol-data.generated.js.map +1 -0
- package/dist/cjs/voltra/protocol/telemetry-decoder.js +122 -6
- package/dist/cjs/voltra/protocol/telemetry-decoder.js.map +1 -1
- package/dist/cjs/voltra/protocol/types.js +9 -0
- package/dist/cjs/voltra/protocol/types.js.map +1 -0
- package/dist/esm/bluetooth/adapters/native.js +36 -34
- package/dist/esm/bluetooth/adapters/native.js.map +1 -1
- package/dist/esm/bluetooth/adapters/node.js +9 -7
- package/dist/esm/bluetooth/adapters/node.js.map +1 -1
- package/dist/esm/bluetooth/adapters/web-bluetooth-base.js +6 -4
- package/dist/esm/bluetooth/adapters/web-bluetooth-base.js.map +1 -1
- package/dist/esm/bluetooth/adapters/web.js +7 -5
- package/dist/esm/bluetooth/adapters/web.js.map +1 -1
- package/dist/esm/bluetooth/controllers/scanner-controller.js +0 -2
- package/dist/esm/bluetooth/controllers/scanner-controller.js.map +1 -1
- package/dist/esm/index.js +3 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/hooks.js +1 -5
- package/dist/esm/react/hooks.js.map +1 -1
- package/dist/esm/sdk/notification-dispatcher.js +44 -0
- package/dist/esm/sdk/notification-dispatcher.js.map +1 -0
- package/dist/esm/sdk/reconnect-handler.js +57 -0
- package/dist/esm/sdk/reconnect-handler.js.map +1 -0
- package/dist/esm/sdk/voltra-client.js +204 -70
- package/dist/esm/sdk/voltra-client.js.map +1 -1
- package/dist/esm/shared/index.js +1 -0
- package/dist/esm/shared/index.js.map +1 -1
- package/dist/esm/shared/logger.js +49 -0
- package/dist/esm/shared/logger.js.map +1 -0
- package/dist/esm/voltra/index.js +3 -8
- package/dist/esm/voltra/index.js.map +1 -1
- package/dist/esm/voltra/models/device.js +13 -0
- package/dist/esm/voltra/models/device.js.map +1 -1
- package/dist/esm/voltra/protocol/commands.js +117 -209
- package/dist/esm/voltra/protocol/commands.js.map +1 -1
- package/dist/esm/voltra/protocol/constants/ble-config.js +18 -0
- package/dist/esm/voltra/protocol/constants/ble-config.js.map +1 -0
- package/dist/esm/voltra/protocol/constants/connection-commands.js +49 -0
- package/dist/esm/voltra/protocol/constants/connection-commands.js.map +1 -0
- package/dist/esm/voltra/protocol/constants/enums.js +114 -0
- package/dist/esm/voltra/protocol/constants/enums.js.map +1 -0
- package/dist/esm/voltra/protocol/constants/index.js +12 -0
- package/dist/esm/voltra/protocol/constants/index.js.map +1 -0
- package/dist/esm/voltra/protocol/constants/message-types.js +64 -0
- package/dist/esm/voltra/protocol/constants/message-types.js.map +1 -0
- package/dist/esm/voltra/protocol/constants/timing.js +18 -0
- package/dist/esm/voltra/protocol/constants/timing.js.map +1 -0
- package/dist/esm/voltra/protocol/data/protocol-data.generated.js +5 -0
- package/dist/esm/voltra/protocol/data/protocol-data.generated.js.map +1 -0
- package/dist/esm/voltra/protocol/telemetry-decoder.js +124 -8
- package/dist/esm/voltra/protocol/telemetry-decoder.js.map +1 -1
- package/dist/esm/voltra/protocol/types.js +8 -0
- package/dist/esm/voltra/protocol/types.js.map +1 -0
- package/dist/types/bluetooth/adapters/native.d.ts.map +1 -1
- package/dist/types/bluetooth/adapters/node.d.ts.map +1 -1
- package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts.map +1 -1
- package/dist/types/bluetooth/adapters/web.d.ts.map +1 -1
- package/dist/types/bluetooth/controllers/scanner-controller.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/react/hooks.d.ts.map +1 -1
- package/dist/types/sdk/index.d.ts +2 -1
- package/dist/types/sdk/index.d.ts.map +1 -1
- package/dist/types/sdk/notification-dispatcher.d.ts +29 -0
- package/dist/types/sdk/notification-dispatcher.d.ts.map +1 -0
- package/dist/types/sdk/reconnect-handler.d.ts +55 -0
- package/dist/types/sdk/reconnect-handler.d.ts.map +1 -0
- package/dist/types/sdk/types.d.ts +35 -0
- package/dist/types/sdk/types.d.ts.map +1 -1
- package/dist/types/sdk/voltra-client.d.ts +77 -2
- package/dist/types/sdk/voltra-client.d.ts.map +1 -1
- package/dist/types/shared/index.d.ts +1 -0
- package/dist/types/shared/index.d.ts.map +1 -1
- package/dist/types/shared/logger.d.ts +39 -0
- package/dist/types/shared/logger.d.ts.map +1 -0
- package/dist/types/voltra/index.d.ts +3 -3
- package/dist/types/voltra/index.d.ts.map +1 -1
- package/dist/types/voltra/models/device.d.ts +11 -1
- package/dist/types/voltra/models/device.d.ts.map +1 -1
- package/dist/types/voltra/protocol/commands.d.ts +47 -87
- package/dist/types/voltra/protocol/commands.d.ts.map +1 -1
- package/dist/types/voltra/protocol/constants/ble-config.d.ts +16 -0
- package/dist/types/voltra/protocol/constants/ble-config.d.ts.map +1 -0
- package/dist/types/voltra/protocol/constants/connection-commands.d.ts +37 -0
- package/dist/types/voltra/protocol/constants/connection-commands.d.ts.map +1 -0
- package/dist/types/voltra/protocol/constants/enums.d.ts +72 -0
- package/dist/types/voltra/protocol/constants/enums.d.ts.map +1 -0
- package/dist/types/voltra/protocol/constants/index.d.ts +12 -0
- package/dist/types/voltra/protocol/constants/index.d.ts.map +1 -0
- package/dist/types/voltra/protocol/constants/message-types.d.ts +52 -0
- package/dist/types/voltra/protocol/constants/message-types.d.ts.map +1 -0
- package/dist/types/voltra/protocol/constants/timing.d.ts +18 -0
- package/dist/types/voltra/protocol/constants/timing.d.ts.map +1 -0
- package/dist/types/voltra/protocol/data/protocol-data.generated.d.ts +3 -0
- package/dist/types/voltra/protocol/data/protocol-data.generated.d.ts.map +1 -0
- package/dist/types/voltra/protocol/telemetry-decoder.d.ts +15 -2
- package/dist/types/voltra/protocol/telemetry-decoder.d.ts.map +1 -1
- package/dist/types/voltra/protocol/types.d.ts +247 -0
- package/dist/types/voltra/protocol/types.d.ts.map +1 -0
- package/package.json +8 -7
- package/dist/cjs/voltra/protocol/constants.js +0 -136
- package/dist/cjs/voltra/protocol/constants.js.map +0 -1
- package/dist/cjs/voltra/protocol/data/chains.json +0 -830
- package/dist/cjs/voltra/protocol/data/eccentric.json +0 -1598
- package/dist/cjs/voltra/protocol/data/protocol.json +0 -54
- package/dist/cjs/voltra/protocol/data/weights.json +0 -62
- package/dist/esm/voltra/protocol/constants.js +0 -130
- package/dist/esm/voltra/protocol/constants.js.map +0 -1
- package/dist/esm/voltra/protocol/data/chains.json +0 -830
- package/dist/esm/voltra/protocol/data/eccentric.json +0 -1598
- package/dist/esm/voltra/protocol/data/protocol.json +0 -54
- package/dist/esm/voltra/protocol/data/weights.json +0 -62
- package/dist/types/voltra/protocol/constants.d.ts +0 -103
- package/dist/types/voltra/protocol/constants.d.ts.map +0 -1
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for the consolidated protocol.json structure.
|
|
3
|
+
*
|
|
4
|
+
* These types define the shape of the public protocol data used for
|
|
5
|
+
* command lookup and notification parsing.
|
|
6
|
+
*/
|
|
7
|
+
import type { TrainingMode } from './constants';
|
|
8
|
+
/**
|
|
9
|
+
* Root protocol data structure.
|
|
10
|
+
*/
|
|
11
|
+
export interface ProtocolData {
|
|
12
|
+
/** Protocol version (semver) */
|
|
13
|
+
version: string;
|
|
14
|
+
/** BLE configuration */
|
|
15
|
+
ble: BleConfig;
|
|
16
|
+
/** Command definitions */
|
|
17
|
+
commands: CommandConfig;
|
|
18
|
+
/** Telemetry parsing configuration */
|
|
19
|
+
telemetry: TelemetryConfig;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* BLE service and characteristic UUIDs.
|
|
23
|
+
*/
|
|
24
|
+
export interface BleConfig {
|
|
25
|
+
/** Main service UUID for Voltra devices */
|
|
26
|
+
serviceUuid: string;
|
|
27
|
+
/** Characteristic UUID for receiving notifications */
|
|
28
|
+
notifyCharUuid: string;
|
|
29
|
+
/** Characteristic UUID for writing commands */
|
|
30
|
+
writeCharUuid: string;
|
|
31
|
+
/** Device name prefix for scanning (e.g., "VTR-") */
|
|
32
|
+
deviceNamePrefix: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* All command definitions.
|
|
36
|
+
*/
|
|
37
|
+
export interface CommandConfig {
|
|
38
|
+
/** Authentication commands */
|
|
39
|
+
auth: AuthCommands;
|
|
40
|
+
/** Initialization sequence */
|
|
41
|
+
init: string[];
|
|
42
|
+
/** Workout control commands */
|
|
43
|
+
workout: WorkoutCommands;
|
|
44
|
+
/** Training mode commands (mode name -> hex string) */
|
|
45
|
+
modes: ModeCommands;
|
|
46
|
+
/** Weight commands (lbs -> hex string) */
|
|
47
|
+
weights: Record<string, string>;
|
|
48
|
+
/** Chains commands (lbs -> hex string) */
|
|
49
|
+
chains: Record<string, string>;
|
|
50
|
+
/** Eccentric commands (value -> hex string) */
|
|
51
|
+
eccentric: Record<string, string>;
|
|
52
|
+
/** Inverse chains commands (lbs -> hex string) */
|
|
53
|
+
inverseChains: Record<string, string>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Training mode commands.
|
|
57
|
+
*/
|
|
58
|
+
export interface ModeCommands {
|
|
59
|
+
/** Idle mode (0x0000) */
|
|
60
|
+
idle: string;
|
|
61
|
+
/** Weight training mode (0x0001) */
|
|
62
|
+
weightTraining: string;
|
|
63
|
+
/** Resistance band mode (0x0002) */
|
|
64
|
+
resistanceBand: string;
|
|
65
|
+
/** Rowing mode (0x0003) */
|
|
66
|
+
rowing: string;
|
|
67
|
+
/** Damper mode (0x0004) */
|
|
68
|
+
damper: string;
|
|
69
|
+
/** Custom curves mode (0x0006) */
|
|
70
|
+
customCurves: string;
|
|
71
|
+
/** Isokinetic mode (0x0007) */
|
|
72
|
+
isokinetic: string;
|
|
73
|
+
/** Isometric mode (0x0008) */
|
|
74
|
+
isometric: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Authentication device IDs.
|
|
78
|
+
*/
|
|
79
|
+
export interface AuthCommands {
|
|
80
|
+
/** iPhone device ID (41-byte hex) */
|
|
81
|
+
iphone: string;
|
|
82
|
+
/** iPad device ID (41-byte hex) */
|
|
83
|
+
ipad: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Workout control commands.
|
|
87
|
+
*/
|
|
88
|
+
export interface WorkoutCommands {
|
|
89
|
+
/** Prepare for workout */
|
|
90
|
+
prepare: string;
|
|
91
|
+
/** Setup workout mode */
|
|
92
|
+
setup: string;
|
|
93
|
+
/** Start resistance (go) */
|
|
94
|
+
go: string;
|
|
95
|
+
/** Stop resistance */
|
|
96
|
+
stop: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Telemetry parsing configuration.
|
|
100
|
+
*/
|
|
101
|
+
export interface TelemetryConfig {
|
|
102
|
+
/** Message type identifiers (first 4 bytes) */
|
|
103
|
+
messageTypes: MessageTypeConfig;
|
|
104
|
+
/** Byte offsets for parsing telemetry stream */
|
|
105
|
+
offsets: OffsetConfig;
|
|
106
|
+
/** Movement phase values */
|
|
107
|
+
phases: PhaseConfig;
|
|
108
|
+
/** Notification type parsing configurations */
|
|
109
|
+
notifications: NotificationsConfig;
|
|
110
|
+
/** Known parameter IDs */
|
|
111
|
+
paramIds: ParamIdsConfig;
|
|
112
|
+
/** Training mode values */
|
|
113
|
+
trainingModes: TrainingModesConfig;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Message type header bytes (4-byte hex strings).
|
|
117
|
+
*/
|
|
118
|
+
export interface MessageTypeConfig {
|
|
119
|
+
/** Real-time telemetry stream (~11 Hz) */
|
|
120
|
+
stream: string;
|
|
121
|
+
/** Rep completion summary */
|
|
122
|
+
repSummary: string;
|
|
123
|
+
/** Set completion summary */
|
|
124
|
+
setSummary: string;
|
|
125
|
+
/** Status update */
|
|
126
|
+
statusUpdate: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Byte offsets for parsing telemetry stream messages.
|
|
130
|
+
*/
|
|
131
|
+
export interface OffsetConfig {
|
|
132
|
+
/** Sequence number (2 bytes, little-endian) */
|
|
133
|
+
sequence: number;
|
|
134
|
+
/** Movement phase (1 byte) */
|
|
135
|
+
phase: number;
|
|
136
|
+
/** Position (2 bytes, little-endian unsigned) */
|
|
137
|
+
position: number;
|
|
138
|
+
/** Force (2 bytes, little-endian signed) */
|
|
139
|
+
force: number;
|
|
140
|
+
/** Velocity (2 bytes, little-endian unsigned) */
|
|
141
|
+
velocity: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Movement phase byte values.
|
|
145
|
+
*/
|
|
146
|
+
export interface PhaseConfig {
|
|
147
|
+
/** Idle state */
|
|
148
|
+
idle: number;
|
|
149
|
+
/** Concentric phase (pulling/muscle shortening) */
|
|
150
|
+
concentric: number;
|
|
151
|
+
/** Hold phase (top of rep/transition) */
|
|
152
|
+
hold: number;
|
|
153
|
+
/** Eccentric phase (lowering/muscle lengthening) */
|
|
154
|
+
eccentric: number;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Configuration for parsing a specific notification type.
|
|
158
|
+
*/
|
|
159
|
+
export interface NotificationTypeConfig {
|
|
160
|
+
/** Header bytes to identify this notification type (hex string) */
|
|
161
|
+
header: string;
|
|
162
|
+
/** Expected message length in bytes */
|
|
163
|
+
length?: number;
|
|
164
|
+
/** Offset of parameter ID field */
|
|
165
|
+
paramIdOffset?: number;
|
|
166
|
+
/** Offset of value field */
|
|
167
|
+
valueOffset?: number;
|
|
168
|
+
/** Offset of integrity check value */
|
|
169
|
+
crcOffset?: number;
|
|
170
|
+
/** Offset of parameter count field (for multi-param messages) */
|
|
171
|
+
paramCountOffset?: number;
|
|
172
|
+
/** Offset of first parameter (for multi-param messages) */
|
|
173
|
+
firstParamOffset?: number;
|
|
174
|
+
/** Size of each param+value pair in bytes */
|
|
175
|
+
paramSize?: number;
|
|
176
|
+
/** Offset of battery level field */
|
|
177
|
+
batteryOffset?: number;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* All notification type configurations.
|
|
181
|
+
*/
|
|
182
|
+
export interface NotificationsConfig {
|
|
183
|
+
/** Mode change confirmation (0x12) */
|
|
184
|
+
modeConfirmation: NotificationTypeConfig;
|
|
185
|
+
/** Multi-parameter message (0x16) */
|
|
186
|
+
multiParam: NotificationTypeConfig;
|
|
187
|
+
/** Settings update with all parameters (0x2e) */
|
|
188
|
+
settingsUpdate: NotificationTypeConfig;
|
|
189
|
+
/** Device initialization info (0x23) */
|
|
190
|
+
deviceInit: NotificationTypeConfig;
|
|
191
|
+
/** Status/battery update (0x34) */
|
|
192
|
+
statusBattery: NotificationTypeConfig;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Known parameter IDs (hex strings, little-endian).
|
|
196
|
+
*/
|
|
197
|
+
export interface ParamIdsConfig {
|
|
198
|
+
/** Base weight parameter (0x863e) */
|
|
199
|
+
baseWeight: string;
|
|
200
|
+
/** Chains weight parameter (0x873e) */
|
|
201
|
+
chains: string;
|
|
202
|
+
/** Eccentric setting parameter (0x883e) */
|
|
203
|
+
eccentric: string;
|
|
204
|
+
/** Training mode parameter (0xb04f) */
|
|
205
|
+
trainingMode: string;
|
|
206
|
+
/** Inverse chains parameter (0xb053) */
|
|
207
|
+
inverseChains: string;
|
|
208
|
+
/** Unknown parameter observed in notifications */
|
|
209
|
+
unknown893e: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Training mode values.
|
|
213
|
+
*/
|
|
214
|
+
export interface TrainingModesConfig {
|
|
215
|
+
/** Idle state */
|
|
216
|
+
idle: number;
|
|
217
|
+
/** Weight training mode */
|
|
218
|
+
weightTraining: number;
|
|
219
|
+
/** Resistance band mode */
|
|
220
|
+
resistanceBand: number;
|
|
221
|
+
/** Rowing mode */
|
|
222
|
+
rowing: number;
|
|
223
|
+
/** Damper mode */
|
|
224
|
+
damper: number;
|
|
225
|
+
/** Custom curves mode */
|
|
226
|
+
customCurves: number;
|
|
227
|
+
/** Isokinetic mode */
|
|
228
|
+
isokinetic: number;
|
|
229
|
+
/** Isometric mode */
|
|
230
|
+
isometric: number;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Parsed device settings from notifications.
|
|
234
|
+
*/
|
|
235
|
+
export interface DeviceSettings {
|
|
236
|
+
/** Base weight in lbs */
|
|
237
|
+
baseWeight?: number;
|
|
238
|
+
/** Chains weight in lbs */
|
|
239
|
+
chains?: number;
|
|
240
|
+
/** Eccentric setting */
|
|
241
|
+
eccentric?: number;
|
|
242
|
+
/** Current training mode */
|
|
243
|
+
trainingMode?: TrainingMode;
|
|
244
|
+
/** Inverse chains setting */
|
|
245
|
+
inverseChains?: number;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/voltra/protocol/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltras/node-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "SDK for connecting to and controlling Voltra fitness devices",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
45
45
|
"typecheck": "tsc --noEmit",
|
|
46
46
|
"docs:api": "typedoc --out docs/api src/index.ts",
|
|
47
|
+
"generate:protocol": "npx tsx ../voltra-private/generators/encode-protocol.ts",
|
|
47
48
|
"clean": "rm -rf dist",
|
|
48
49
|
"prepublishOnly": "npm run clean && npm run build && npm run test",
|
|
49
50
|
"prepare": "husky"
|
|
@@ -64,18 +65,18 @@
|
|
|
64
65
|
"webbluetooth": "^3.4.0"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
|
-
"@commitlint/cli": "^
|
|
68
|
-
"@commitlint/config-conventional": "^
|
|
69
|
-
"@types/node": "^
|
|
68
|
+
"@commitlint/cli": "^20.4.1",
|
|
69
|
+
"@commitlint/config-conventional": "^20.4.1",
|
|
70
|
+
"@types/node": "^25.2.3",
|
|
70
71
|
"@types/react": "^19.0.0",
|
|
71
72
|
"@types/web-bluetooth": "^0.0.21",
|
|
72
73
|
"@vitest/coverage-v8": "^4.0.0",
|
|
73
74
|
"eslint": "^9.18.0",
|
|
74
75
|
"husky": "^9.1.0",
|
|
75
|
-
"lint-staged": "^
|
|
76
|
+
"lint-staged": "^16.2.7",
|
|
76
77
|
"prettier": "^3.4.0",
|
|
77
|
-
"typedoc": "^0.
|
|
78
|
-
"typescript": "~5.
|
|
78
|
+
"typedoc": "^0.28.17",
|
|
79
|
+
"typescript": "~5.9.3",
|
|
79
80
|
"typescript-eslint": "^8.21.0",
|
|
80
81
|
"vitest": "^4.0.17"
|
|
81
82
|
},
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Voltra Protocol Constants
|
|
4
|
-
*
|
|
5
|
-
* BLE configuration, authentication, and command constants for
|
|
6
|
-
* Beyond Power Voltra resistance training devices.
|
|
7
|
-
*/
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.PhaseNames = exports.MovementPhase = exports.TelemetryOffsets = exports.MessageTypes = exports.Workout = exports.Init = exports.Auth = exports.Timing = exports.BLE = void 0;
|
|
13
|
-
const utils_1 = require("../../shared/utils");
|
|
14
|
-
const protocol_json_1 = __importDefault(require("./data/protocol.json"));
|
|
15
|
-
// =============================================================================
|
|
16
|
-
// BLE Configuration
|
|
17
|
-
// =============================================================================
|
|
18
|
-
exports.BLE = {
|
|
19
|
-
/** Main service UUID for Voltra devices */
|
|
20
|
-
SERVICE_UUID: protocol_json_1.default.ble.service_uuid,
|
|
21
|
-
/** Characteristic for receiving notifications */
|
|
22
|
-
NOTIFY_CHAR_UUID: protocol_json_1.default.ble.notify_char_uuid,
|
|
23
|
-
/** Characteristic for writing commands */
|
|
24
|
-
WRITE_CHAR_UUID: protocol_json_1.default.ble.write_char_uuid,
|
|
25
|
-
/** Device name prefix for scanning (e.g., "VTR-") */
|
|
26
|
-
DEVICE_NAME_PREFIX: protocol_json_1.default.ble.device_name_prefix,
|
|
27
|
-
};
|
|
28
|
-
// =============================================================================
|
|
29
|
-
// Timing Configuration
|
|
30
|
-
// =============================================================================
|
|
31
|
-
exports.Timing = {
|
|
32
|
-
/** Delay between init commands (ms) */
|
|
33
|
-
INIT_COMMAND_DELAY_MS: 20,
|
|
34
|
-
/** Delay between dual commands like chains/eccentric (ms) */
|
|
35
|
-
DUAL_COMMAND_DELAY_MS: 500,
|
|
36
|
-
/** Timeout for authentication response (ms) */
|
|
37
|
-
AUTH_TIMEOUT_MS: 3000,
|
|
38
|
-
/** Minimum responses expected during auth */
|
|
39
|
-
MIN_AUTH_RESPONSES: 2,
|
|
40
|
-
/** Minimum responses expected after commands */
|
|
41
|
-
MIN_COMMAND_RESPONSES: 4,
|
|
42
|
-
};
|
|
43
|
-
// =============================================================================
|
|
44
|
-
// Authentication
|
|
45
|
-
// =============================================================================
|
|
46
|
-
/**
|
|
47
|
-
* Device authentication identifiers.
|
|
48
|
-
*
|
|
49
|
-
* 41-byte device IDs that identify the connecting app.
|
|
50
|
-
* Both iPhone and iPad IDs work - the Voltra doesn't care which.
|
|
51
|
-
*/
|
|
52
|
-
exports.Auth = {
|
|
53
|
-
/** iPhone identity from Beyond+ app */
|
|
54
|
-
DEVICE_ID: (0, utils_1.hexToBytes)(protocol_json_1.default.auth.iphone),
|
|
55
|
-
/** iPad identity (alternative) */
|
|
56
|
-
DEVICE_ID_IPAD: (0, utils_1.hexToBytes)(protocol_json_1.default.auth.ipad),
|
|
57
|
-
};
|
|
58
|
-
// =============================================================================
|
|
59
|
-
// Initialization
|
|
60
|
-
// =============================================================================
|
|
61
|
-
/**
|
|
62
|
-
* Minimal 2-command init sequence (reduced from 22+ in Beyond+ app).
|
|
63
|
-
*/
|
|
64
|
-
exports.Init = {
|
|
65
|
-
SEQUENCE: protocol_json_1.default.init.commands.map(utils_1.hexToBytes),
|
|
66
|
-
};
|
|
67
|
-
// =============================================================================
|
|
68
|
-
// Workout Commands
|
|
69
|
-
// =============================================================================
|
|
70
|
-
/**
|
|
71
|
-
* Workout control commands.
|
|
72
|
-
*
|
|
73
|
-
* To start: set weight -> PREPARE -> SETUP -> GO
|
|
74
|
-
* To stop: STOP
|
|
75
|
-
*/
|
|
76
|
-
exports.Workout = {
|
|
77
|
-
/** Prepare for workout (b04f=01) */
|
|
78
|
-
PREPARE: (0, utils_1.hexToBytes)(protocol_json_1.default.workout.prepare),
|
|
79
|
-
/** Setup workout mode (823e setup) */
|
|
80
|
-
SETUP: (0, utils_1.hexToBytes)(protocol_json_1.default.workout.setup),
|
|
81
|
-
/** Start resistance (893e=05) */
|
|
82
|
-
GO: (0, utils_1.hexToBytes)(protocol_json_1.default.workout.go),
|
|
83
|
-
/** Stop resistance (893e=04) */
|
|
84
|
-
STOP: (0, utils_1.hexToBytes)(protocol_json_1.default.workout.stop),
|
|
85
|
-
};
|
|
86
|
-
// =============================================================================
|
|
87
|
-
// Telemetry Message Types (loaded from protocol.json)
|
|
88
|
-
// =============================================================================
|
|
89
|
-
/**
|
|
90
|
-
* Message type identifiers (first 4 bytes of notifications).
|
|
91
|
-
* Values loaded from protocol.json for single source of truth.
|
|
92
|
-
*/
|
|
93
|
-
exports.MessageTypes = {
|
|
94
|
-
/** Real-time telemetry stream (~11 Hz) */
|
|
95
|
-
TELEMETRY_STREAM: (0, utils_1.hexToBytes)(protocol_json_1.default.telemetry.message_types.stream),
|
|
96
|
-
/** Rep completion summary */
|
|
97
|
-
REP_SUMMARY: (0, utils_1.hexToBytes)(protocol_json_1.default.telemetry.message_types.rep_summary),
|
|
98
|
-
/** Set completion summary */
|
|
99
|
-
SET_SUMMARY: (0, utils_1.hexToBytes)(protocol_json_1.default.telemetry.message_types.set_summary),
|
|
100
|
-
/** Status update */
|
|
101
|
-
STATUS_UPDATE: (0, utils_1.hexToBytes)(protocol_json_1.default.telemetry.message_types.status_update),
|
|
102
|
-
};
|
|
103
|
-
/**
|
|
104
|
-
* Byte offsets for parsing telemetry stream messages.
|
|
105
|
-
* Values loaded from protocol.json for single source of truth.
|
|
106
|
-
*/
|
|
107
|
-
exports.TelemetryOffsets = {
|
|
108
|
-
SEQUENCE: protocol_json_1.default.telemetry.offsets.sequence, // 2 bytes, little-endian
|
|
109
|
-
PHASE: protocol_json_1.default.telemetry.offsets.phase, // 1 byte
|
|
110
|
-
POSITION: protocol_json_1.default.telemetry.offsets.position, // 2 bytes, little-endian unsigned
|
|
111
|
-
FORCE: protocol_json_1.default.telemetry.offsets.force, // 2 bytes, little-endian signed
|
|
112
|
-
VELOCITY: protocol_json_1.default.telemetry.offsets.velocity, // 2 bytes, little-endian unsigned
|
|
113
|
-
};
|
|
114
|
-
/**
|
|
115
|
-
* Movement phase during workout.
|
|
116
|
-
* Values match protocol.json telemetry.phases.
|
|
117
|
-
*/
|
|
118
|
-
var MovementPhase;
|
|
119
|
-
(function (MovementPhase) {
|
|
120
|
-
MovementPhase[MovementPhase["IDLE"] = 0] = "IDLE";
|
|
121
|
-
MovementPhase[MovementPhase["CONCENTRIC"] = 1] = "CONCENTRIC";
|
|
122
|
-
MovementPhase[MovementPhase["HOLD"] = 2] = "HOLD";
|
|
123
|
-
MovementPhase[MovementPhase["ECCENTRIC"] = 3] = "ECCENTRIC";
|
|
124
|
-
MovementPhase[MovementPhase["UNKNOWN"] = -1] = "UNKNOWN";
|
|
125
|
-
})(MovementPhase || (exports.MovementPhase = MovementPhase = {}));
|
|
126
|
-
/**
|
|
127
|
-
* Human-readable phase names.
|
|
128
|
-
*/
|
|
129
|
-
exports.PhaseNames = {
|
|
130
|
-
[MovementPhase.IDLE]: 'Idle',
|
|
131
|
-
[MovementPhase.CONCENTRIC]: 'Pulling',
|
|
132
|
-
[MovementPhase.HOLD]: 'Hold',
|
|
133
|
-
[MovementPhase.ECCENTRIC]: 'Lowering',
|
|
134
|
-
[MovementPhase.UNKNOWN]: 'Unknown',
|
|
135
|
-
};
|
|
136
|
-
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/voltra/protocol/constants.ts"],"names":[],"mappings":"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"}
|