@voltras/node-sdk 0.1.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.
Files changed (203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +272 -0
  3. package/dist/cjs/bluetooth/adapters/base.js +116 -0
  4. package/dist/cjs/bluetooth/adapters/base.js.map +1 -0
  5. package/dist/cjs/bluetooth/adapters/index.js +58 -0
  6. package/dist/cjs/bluetooth/adapters/index.js.map +1 -0
  7. package/dist/cjs/bluetooth/adapters/native.js +473 -0
  8. package/dist/cjs/bluetooth/adapters/native.js.map +1 -0
  9. package/dist/cjs/bluetooth/adapters/node.js +228 -0
  10. package/dist/cjs/bluetooth/adapters/node.js.map +1 -0
  11. package/dist/cjs/bluetooth/adapters/types.js +11 -0
  12. package/dist/cjs/bluetooth/adapters/types.js.map +1 -0
  13. package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js +187 -0
  14. package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js.map +1 -0
  15. package/dist/cjs/bluetooth/adapters/web.js +112 -0
  16. package/dist/cjs/bluetooth/adapters/web.js.map +1 -0
  17. package/dist/cjs/bluetooth/controllers/scanner-controller.js +145 -0
  18. package/dist/cjs/bluetooth/controllers/scanner-controller.js.map +1 -0
  19. package/dist/cjs/bluetooth/index.js +27 -0
  20. package/dist/cjs/bluetooth/index.js.map +1 -0
  21. package/dist/cjs/bluetooth/models/connection.js +68 -0
  22. package/dist/cjs/bluetooth/models/connection.js.map +1 -0
  23. package/dist/cjs/bluetooth/models/device.js +26 -0
  24. package/dist/cjs/bluetooth/models/device.js.map +1 -0
  25. package/dist/cjs/bluetooth/models/environment.js +106 -0
  26. package/dist/cjs/bluetooth/models/environment.js.map +1 -0
  27. package/dist/cjs/errors.js +167 -0
  28. package/dist/cjs/errors.js.map +1 -0
  29. package/dist/cjs/index.js +116 -0
  30. package/dist/cjs/index.js.map +1 -0
  31. package/dist/cjs/react/hooks.js +262 -0
  32. package/dist/cjs/react/hooks.js.map +1 -0
  33. package/dist/cjs/react/index.js +18 -0
  34. package/dist/cjs/react/index.js.map +1 -0
  35. package/dist/cjs/sdk/index.js +14 -0
  36. package/dist/cjs/sdk/index.js.map +1 -0
  37. package/dist/cjs/sdk/types.js +8 -0
  38. package/dist/cjs/sdk/types.js.map +1 -0
  39. package/dist/cjs/sdk/voltra-client.js +632 -0
  40. package/dist/cjs/sdk/voltra-client.js.map +1 -0
  41. package/dist/cjs/sdk/voltra-manager.js +419 -0
  42. package/dist/cjs/sdk/voltra-manager.js.map +1 -0
  43. package/dist/cjs/shared/index.js +12 -0
  44. package/dist/cjs/shared/index.js.map +1 -0
  45. package/dist/cjs/shared/utils.js +51 -0
  46. package/dist/cjs/shared/utils.js.map +1 -0
  47. package/dist/cjs/voltra/index.js +56 -0
  48. package/dist/cjs/voltra/index.js.map +1 -0
  49. package/dist/cjs/voltra/models/connection.js +68 -0
  50. package/dist/cjs/voltra/models/connection.js.map +1 -0
  51. package/dist/cjs/voltra/models/device-filter.js +28 -0
  52. package/dist/cjs/voltra/models/device-filter.js.map +1 -0
  53. package/dist/cjs/voltra/models/device.js +152 -0
  54. package/dist/cjs/voltra/models/device.js.map +1 -0
  55. package/dist/cjs/voltra/models/telemetry/frame.js +46 -0
  56. package/dist/cjs/voltra/models/telemetry/frame.js.map +1 -0
  57. package/dist/cjs/voltra/models/telemetry/index.js +14 -0
  58. package/dist/cjs/voltra/models/telemetry/index.js.map +1 -0
  59. package/dist/cjs/voltra/protocol/commands.js +230 -0
  60. package/dist/cjs/voltra/protocol/commands.js.map +1 -0
  61. package/dist/cjs/voltra/protocol/constants.js +136 -0
  62. package/dist/cjs/voltra/protocol/constants.js.map +1 -0
  63. package/dist/cjs/voltra/protocol/data/chains.json +830 -0
  64. package/dist/cjs/voltra/protocol/data/eccentric.json +1598 -0
  65. package/dist/cjs/voltra/protocol/data/protocol.json +54 -0
  66. package/dist/cjs/voltra/protocol/data/weights.json +62 -0
  67. package/dist/cjs/voltra/protocol/index.js +25 -0
  68. package/dist/cjs/voltra/protocol/index.js.map +1 -0
  69. package/dist/cjs/voltra/protocol/telemetry-decoder.js +146 -0
  70. package/dist/cjs/voltra/protocol/telemetry-decoder.js.map +1 -0
  71. package/dist/esm/bluetooth/adapters/base.js +112 -0
  72. package/dist/esm/bluetooth/adapters/base.js.map +1 -0
  73. package/dist/esm/bluetooth/adapters/index.js +51 -0
  74. package/dist/esm/bluetooth/adapters/index.js.map +1 -0
  75. package/dist/esm/bluetooth/adapters/native.js +469 -0
  76. package/dist/esm/bluetooth/adapters/native.js.map +1 -0
  77. package/dist/esm/bluetooth/adapters/node.js +191 -0
  78. package/dist/esm/bluetooth/adapters/node.js.map +1 -0
  79. package/dist/esm/bluetooth/adapters/types.js +10 -0
  80. package/dist/esm/bluetooth/adapters/types.js.map +1 -0
  81. package/dist/esm/bluetooth/adapters/web-bluetooth-base.js +183 -0
  82. package/dist/esm/bluetooth/adapters/web-bluetooth-base.js.map +1 -0
  83. package/dist/esm/bluetooth/adapters/web.js +108 -0
  84. package/dist/esm/bluetooth/adapters/web.js.map +1 -0
  85. package/dist/esm/bluetooth/controllers/scanner-controller.js +141 -0
  86. package/dist/esm/bluetooth/controllers/scanner-controller.js.map +1 -0
  87. package/dist/esm/bluetooth/index.js +17 -0
  88. package/dist/esm/bluetooth/index.js.map +1 -0
  89. package/dist/esm/bluetooth/models/connection.js +63 -0
  90. package/dist/esm/bluetooth/models/connection.js.map +1 -0
  91. package/dist/esm/bluetooth/models/device.js +22 -0
  92. package/dist/esm/bluetooth/models/device.js.map +1 -0
  93. package/dist/esm/bluetooth/models/environment.js +101 -0
  94. package/dist/esm/bluetooth/models/environment.js.map +1 -0
  95. package/dist/esm/errors.js +155 -0
  96. package/dist/esm/errors.js.map +1 -0
  97. package/dist/esm/index.js +72 -0
  98. package/dist/esm/index.js.map +1 -0
  99. package/dist/esm/react/hooks.js +257 -0
  100. package/dist/esm/react/hooks.js.map +1 -0
  101. package/dist/esm/react/index.js +12 -0
  102. package/dist/esm/react/index.js.map +1 -0
  103. package/dist/esm/sdk/index.js +9 -0
  104. package/dist/esm/sdk/index.js.map +1 -0
  105. package/dist/esm/sdk/types.js +7 -0
  106. package/dist/esm/sdk/types.js.map +1 -0
  107. package/dist/esm/sdk/voltra-client.js +628 -0
  108. package/dist/esm/sdk/voltra-client.js.map +1 -0
  109. package/dist/esm/sdk/voltra-manager.js +415 -0
  110. package/dist/esm/sdk/voltra-manager.js.map +1 -0
  111. package/dist/esm/shared/index.js +5 -0
  112. package/dist/esm/shared/index.js.map +1 -0
  113. package/dist/esm/shared/utils.js +45 -0
  114. package/dist/esm/shared/utils.js.map +1 -0
  115. package/dist/esm/voltra/index.js +26 -0
  116. package/dist/esm/voltra/index.js.map +1 -0
  117. package/dist/esm/voltra/models/connection.js +63 -0
  118. package/dist/esm/voltra/models/connection.js.map +1 -0
  119. package/dist/esm/voltra/models/device-filter.js +23 -0
  120. package/dist/esm/voltra/models/device-filter.js.map +1 -0
  121. package/dist/esm/voltra/models/device.js +148 -0
  122. package/dist/esm/voltra/models/device.js.map +1 -0
  123. package/dist/esm/voltra/models/telemetry/frame.js +40 -0
  124. package/dist/esm/voltra/models/telemetry/frame.js.map +1 -0
  125. package/dist/esm/voltra/models/telemetry/index.js +7 -0
  126. package/dist/esm/voltra/models/telemetry/index.js.map +1 -0
  127. package/dist/esm/voltra/protocol/commands.js +224 -0
  128. package/dist/esm/voltra/protocol/commands.js.map +1 -0
  129. package/dist/esm/voltra/protocol/constants.js +130 -0
  130. package/dist/esm/voltra/protocol/constants.js.map +1 -0
  131. package/dist/esm/voltra/protocol/data/chains.json +830 -0
  132. package/dist/esm/voltra/protocol/data/eccentric.json +1598 -0
  133. package/dist/esm/voltra/protocol/data/protocol.json +54 -0
  134. package/dist/esm/voltra/protocol/data/weights.json +62 -0
  135. package/dist/esm/voltra/protocol/index.js +9 -0
  136. package/dist/esm/voltra/protocol/index.js.map +1 -0
  137. package/dist/esm/voltra/protocol/telemetry-decoder.js +140 -0
  138. package/dist/esm/voltra/protocol/telemetry-decoder.js.map +1 -0
  139. package/dist/types/bluetooth/adapters/base.d.ts +85 -0
  140. package/dist/types/bluetooth/adapters/base.d.ts.map +1 -0
  141. package/dist/types/bluetooth/adapters/index.d.ts +35 -0
  142. package/dist/types/bluetooth/adapters/index.d.ts.map +1 -0
  143. package/dist/types/bluetooth/adapters/native.d.ts +109 -0
  144. package/dist/types/bluetooth/adapters/native.d.ts.map +1 -0
  145. package/dist/types/bluetooth/adapters/node.d.ts +91 -0
  146. package/dist/types/bluetooth/adapters/node.d.ts.map +1 -0
  147. package/dist/types/bluetooth/adapters/types.d.ts +102 -0
  148. package/dist/types/bluetooth/adapters/types.d.ts.map +1 -0
  149. package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts +90 -0
  150. package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts.map +1 -0
  151. package/dist/types/bluetooth/adapters/web.d.ts +57 -0
  152. package/dist/types/bluetooth/adapters/web.d.ts.map +1 -0
  153. package/dist/types/bluetooth/controllers/scanner-controller.d.ts +93 -0
  154. package/dist/types/bluetooth/controllers/scanner-controller.d.ts.map +1 -0
  155. package/dist/types/bluetooth/index.d.ts +14 -0
  156. package/dist/types/bluetooth/index.d.ts.map +1 -0
  157. package/dist/types/bluetooth/models/connection.d.ts +37 -0
  158. package/dist/types/bluetooth/models/connection.d.ts.map +1 -0
  159. package/dist/types/bluetooth/models/device.d.ts +25 -0
  160. package/dist/types/bluetooth/models/device.d.ts.map +1 -0
  161. package/dist/types/bluetooth/models/environment.d.ts +45 -0
  162. package/dist/types/bluetooth/models/environment.d.ts.map +1 -0
  163. package/dist/types/errors.d.ts +113 -0
  164. package/dist/types/errors.d.ts.map +1 -0
  165. package/dist/types/index.d.ts +55 -0
  166. package/dist/types/index.d.ts.map +1 -0
  167. package/dist/types/react/hooks.d.ts +130 -0
  168. package/dist/types/react/hooks.d.ts.map +1 -0
  169. package/dist/types/react/index.d.ts +12 -0
  170. package/dist/types/react/index.d.ts.map +1 -0
  171. package/dist/types/sdk/index.d.ts +11 -0
  172. package/dist/types/sdk/index.d.ts.map +1 -0
  173. package/dist/types/sdk/types.d.ts +104 -0
  174. package/dist/types/sdk/types.d.ts.map +1 -0
  175. package/dist/types/sdk/voltra-client.d.ts +221 -0
  176. package/dist/types/sdk/voltra-client.d.ts.map +1 -0
  177. package/dist/types/sdk/voltra-manager.d.ts +226 -0
  178. package/dist/types/sdk/voltra-manager.d.ts.map +1 -0
  179. package/dist/types/shared/index.d.ts +5 -0
  180. package/dist/types/shared/index.d.ts.map +1 -0
  181. package/dist/types/shared/utils.d.ts +25 -0
  182. package/dist/types/shared/utils.d.ts.map +1 -0
  183. package/dist/types/voltra/index.d.ts +13 -0
  184. package/dist/types/voltra/index.d.ts.map +1 -0
  185. package/dist/types/voltra/models/connection.d.ts +37 -0
  186. package/dist/types/voltra/models/connection.d.ts.map +1 -0
  187. package/dist/types/voltra/models/device-filter.d.ts +19 -0
  188. package/dist/types/voltra/models/device-filter.d.ts.map +1 -0
  189. package/dist/types/voltra/models/device.d.ts +105 -0
  190. package/dist/types/voltra/models/device.d.ts.map +1 -0
  191. package/dist/types/voltra/models/telemetry/frame.d.ts +41 -0
  192. package/dist/types/voltra/models/telemetry/frame.d.ts.map +1 -0
  193. package/dist/types/voltra/models/telemetry/index.d.ts +8 -0
  194. package/dist/types/voltra/models/telemetry/index.d.ts.map +1 -0
  195. package/dist/types/voltra/protocol/commands.d.ts +99 -0
  196. package/dist/types/voltra/protocol/commands.d.ts.map +1 -0
  197. package/dist/types/voltra/protocol/constants.d.ts +103 -0
  198. package/dist/types/voltra/protocol/constants.d.ts.map +1 -0
  199. package/dist/types/voltra/protocol/index.d.ts +9 -0
  200. package/dist/types/voltra/protocol/index.d.ts.map +1 -0
  201. package/dist/types/voltra/protocol/telemetry-decoder.d.ts +45 -0
  202. package/dist/types/voltra/protocol/telemetry-decoder.d.ts.map +1 -0
  203. package/package.json +111 -0
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * Voltra Device Filter
4
+ *
5
+ * Utility functions for filtering Voltra devices from BLE scan results.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.VOLTRA_DEVICE_PREFIX = void 0;
9
+ exports.isVoltraDevice = isVoltraDevice;
10
+ exports.filterVoltraDevices = filterVoltraDevices;
11
+ const constants_1 = require("../protocol/constants");
12
+ /**
13
+ * Voltra device name prefix.
14
+ */
15
+ exports.VOLTRA_DEVICE_PREFIX = constants_1.BLE.DEVICE_NAME_PREFIX;
16
+ /**
17
+ * Check if a device is a Voltra device.
18
+ */
19
+ function isVoltraDevice(device) {
20
+ return device.name?.startsWith(exports.VOLTRA_DEVICE_PREFIX) ?? false;
21
+ }
22
+ /**
23
+ * Filter Voltra devices from a list.
24
+ */
25
+ function filterVoltraDevices(devices) {
26
+ return devices.filter(isVoltraDevice);
27
+ }
28
+ //# sourceMappingURL=device-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-filter.js","sourceRoot":"","sources":["../../../../src/voltra/models/device-filter.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAaH,wCAEC;AAKD,kDAEC;AAnBD,qDAA4C;AAE5C;;GAEG;AACU,QAAA,oBAAoB,GAAG,eAAG,CAAC,kBAAkB,CAAC;AAE3D;;GAEG;AACH,SAAgB,cAAc,CAAC,MAAwB;IACrD,OAAO,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,4BAAoB,CAAC,IAAI,KAAK,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,OAA2B;IAC7D,OAAO,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * Voltra Device Model
4
+ *
5
+ * Represents a Voltra device with its identity, settings, and connection state.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.VoltraDevice = exports.DEFAULT_SETTINGS = void 0;
9
+ /**
10
+ * Default settings for a new device.
11
+ */
12
+ exports.DEFAULT_SETTINGS = {
13
+ weight: 0,
14
+ chains: 0,
15
+ eccentric: 0,
16
+ };
17
+ /**
18
+ * Voltra device model.
19
+ *
20
+ * Represents a single Voltra device with its state and settings.
21
+ * This is a pure model with no async operations.
22
+ */
23
+ class VoltraDevice {
24
+ constructor(deviceId, deviceName) {
25
+ this._deviceId = deviceId;
26
+ this._deviceName = deviceName ?? null;
27
+ this._settings = { ...exports.DEFAULT_SETTINGS };
28
+ this._connectionState = 'disconnected';
29
+ this._isReconnecting = false;
30
+ this._recordingState = 'idle';
31
+ this._recordingStartTime = null;
32
+ this._error = null;
33
+ }
34
+ // ==========================================================================
35
+ // Getters
36
+ // ==========================================================================
37
+ get deviceId() {
38
+ return this._deviceId;
39
+ }
40
+ get deviceName() {
41
+ return this._deviceName;
42
+ }
43
+ get settings() {
44
+ return { ...this._settings };
45
+ }
46
+ get weight() {
47
+ return this._settings.weight;
48
+ }
49
+ get chains() {
50
+ return this._settings.chains;
51
+ }
52
+ get eccentric() {
53
+ return this._settings.eccentric;
54
+ }
55
+ get connectionState() {
56
+ return this._connectionState;
57
+ }
58
+ get isConnected() {
59
+ return this._connectionState === 'connected';
60
+ }
61
+ get isReconnecting() {
62
+ return this._isReconnecting;
63
+ }
64
+ get recordingState() {
65
+ return this._recordingState;
66
+ }
67
+ get isRecording() {
68
+ return this._recordingState === 'active';
69
+ }
70
+ get recordingStartTime() {
71
+ return this._recordingStartTime;
72
+ }
73
+ get error() {
74
+ return this._error;
75
+ }
76
+ // ==========================================================================
77
+ // State Updates
78
+ // ==========================================================================
79
+ /**
80
+ * Update device settings.
81
+ */
82
+ updateSettings(settings) {
83
+ this._settings = { ...this._settings, ...settings };
84
+ }
85
+ /**
86
+ * Set connection state.
87
+ */
88
+ setConnectionState(state) {
89
+ this._connectionState = state;
90
+ }
91
+ /**
92
+ * Set reconnecting flag.
93
+ */
94
+ setReconnecting(value) {
95
+ this._isReconnecting = value;
96
+ }
97
+ /**
98
+ * Set recording state.
99
+ */
100
+ setRecordingState(state) {
101
+ this._recordingState = state;
102
+ if (state === 'active') {
103
+ this._recordingStartTime = Date.now();
104
+ }
105
+ else if (state === 'idle') {
106
+ this._recordingStartTime = null;
107
+ }
108
+ }
109
+ /**
110
+ * Set error message.
111
+ */
112
+ setError(error) {
113
+ this._error = error;
114
+ }
115
+ /**
116
+ * Clear error.
117
+ */
118
+ clearError() {
119
+ this._error = null;
120
+ }
121
+ // ==========================================================================
122
+ // Serialization
123
+ // ==========================================================================
124
+ /**
125
+ * Get a snapshot of the device state.
126
+ */
127
+ toState() {
128
+ return {
129
+ deviceId: this._deviceId,
130
+ deviceName: this._deviceName,
131
+ connectionState: this._connectionState,
132
+ isReconnecting: this._isReconnecting,
133
+ settings: { ...this._settings },
134
+ recordingState: this._recordingState,
135
+ recordingStartTime: this._recordingStartTime,
136
+ error: this._error,
137
+ };
138
+ }
139
+ /**
140
+ * Reset device to initial state (keeps identity).
141
+ */
142
+ reset() {
143
+ this._settings = { ...exports.DEFAULT_SETTINGS };
144
+ this._connectionState = 'disconnected';
145
+ this._isReconnecting = false;
146
+ this._recordingState = 'idle';
147
+ this._recordingStartTime = null;
148
+ this._error = null;
149
+ }
150
+ }
151
+ exports.VoltraDevice = VoltraDevice;
152
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../../../src/voltra/models/device.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * Telemetry Frame Model
4
+ *
5
+ * Represents a single telemetry data point from the Voltra device.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.createFrame = createFrame;
9
+ exports.isActivePhase = isActivePhase;
10
+ exports.isConcentricPhase = isConcentricPhase;
11
+ exports.isEccentricPhase = isEccentricPhase;
12
+ const constants_1 = require("../../protocol/constants");
13
+ /**
14
+ * Create a telemetry frame from parsed values.
15
+ */
16
+ function createFrame(sequence, phase, position, force, velocity) {
17
+ return {
18
+ sequence,
19
+ phase,
20
+ position,
21
+ force,
22
+ velocity,
23
+ timestamp: Date.now(),
24
+ };
25
+ }
26
+ /**
27
+ * Check if a frame represents active movement.
28
+ */
29
+ function isActivePhase(frame) {
30
+ return (frame.phase === constants_1.MovementPhase.CONCENTRIC ||
31
+ frame.phase === constants_1.MovementPhase.ECCENTRIC ||
32
+ frame.phase === constants_1.MovementPhase.HOLD);
33
+ }
34
+ /**
35
+ * Check if frame is concentric (pulling) phase.
36
+ */
37
+ function isConcentricPhase(frame) {
38
+ return frame.phase === constants_1.MovementPhase.CONCENTRIC;
39
+ }
40
+ /**
41
+ * Check if frame is eccentric (lowering) phase.
42
+ */
43
+ function isEccentricPhase(frame) {
44
+ return frame.phase === constants_1.MovementPhase.ECCENTRIC;
45
+ }
46
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../../../../src/voltra/models/telemetry/frame.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA0BH,kCAeC;AAKD,sCAMC;AAKD,8CAEC;AAKD,4CAEC;AAhED,wDAAyD;AAqBzD;;GAEG;AACH,SAAgB,WAAW,CACzB,QAAgB,EAChB,KAAoB,EACpB,QAAgB,EAChB,KAAa,EACb,QAAgB;IAEhB,OAAO;QACL,QAAQ;QACR,KAAK;QACL,QAAQ;QACR,KAAK;QACL,QAAQ;QACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,KAAqB;IACjD,OAAO,CACL,KAAK,CAAC,KAAK,KAAK,yBAAa,CAAC,UAAU;QACxC,KAAK,CAAC,KAAK,KAAK,yBAAa,CAAC,SAAS;QACvC,KAAK,CAAC,KAAK,KAAK,yBAAa,CAAC,IAAI,CACnC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,KAAqB;IACrD,OAAO,KAAK,CAAC,KAAK,KAAK,yBAAa,CAAC,UAAU,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,KAAqB;IACpD,OAAO,KAAK,CAAC,KAAK,KAAK,yBAAa,CAAC,SAAS,CAAC;AACjD,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * Telemetry Models
4
+ *
5
+ * Data structures for workout telemetry.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.isEccentricPhase = exports.isConcentricPhase = exports.isActivePhase = exports.createFrame = void 0;
9
+ var frame_1 = require("./frame");
10
+ Object.defineProperty(exports, "createFrame", { enumerable: true, get: function () { return frame_1.createFrame; } });
11
+ Object.defineProperty(exports, "isActivePhase", { enumerable: true, get: function () { return frame_1.isActivePhase; } });
12
+ Object.defineProperty(exports, "isConcentricPhase", { enumerable: true, get: function () { return frame_1.isConcentricPhase; } });
13
+ Object.defineProperty(exports, "isEccentricPhase", { enumerable: true, get: function () { return frame_1.isEccentricPhase; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/voltra/models/telemetry/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH,iCAA0F;AAAjF,oGAAA,WAAW,OAAA;AAAE,sGAAA,aAAa,OAAA;AAAE,0GAAA,iBAAiB,OAAA;AAAE,yGAAA,gBAAgB,OAAA"}
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * Voltra Protocol Command Builders
4
+ *
5
+ * Builds commands for setting weight, chains, and eccentric resistance.
6
+ */
7
+ var __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.EccentricCommands = exports.ChainsCommands = exports.WeightCommands = void 0;
12
+ const utils_1 = require("../../shared/utils");
13
+ const weights_json_1 = __importDefault(require("./data/weights.json"));
14
+ const chains_json_1 = __importDefault(require("./data/chains.json"));
15
+ const eccentric_json_1 = __importDefault(require("./data/eccentric.json"));
16
+ // Type the JSON imports
17
+ const weights = weights_json_1.default;
18
+ const chains = chains_json_1.default;
19
+ const eccentric = eccentric_json_1.default;
20
+ // =============================================================================
21
+ // Weight Commands (863e register)
22
+ // =============================================================================
23
+ /**
24
+ * Weight command builder for 5-200 lbs in 5 lb increments.
25
+ */
26
+ exports.WeightCommands = {
27
+ MIN: 5,
28
+ MAX: 200,
29
+ INCREMENT: 5,
30
+ /** Get available weight values */
31
+ getAvailable() {
32
+ return Object.keys(weights.values)
33
+ .map(Number)
34
+ .sort((a, b) => a - b);
35
+ },
36
+ /** Check if a weight value is valid */
37
+ isValid(pounds) {
38
+ return pounds >= this.MIN && pounds <= this.MAX && pounds % this.INCREMENT === 0;
39
+ },
40
+ /**
41
+ * Get the command to set a specific weight.
42
+ * @param pounds Weight in pounds (5-200 in increments of 5)
43
+ * @returns 21-byte command, or null if weight not available
44
+ */
45
+ get(pounds) {
46
+ const key = String(pounds);
47
+ const values = weights.values;
48
+ const format = weights.format;
49
+ if (!(key in values)) {
50
+ return null;
51
+ }
52
+ const data = values[key];
53
+ return this._build(pounds, data.seq, data.checksum, format);
54
+ },
55
+ _build(pounds, seq, checksum, format) {
56
+ const cmd = new Uint8Array(21);
57
+ let offset = 0;
58
+ // Prefix
59
+ const prefix = (0, utils_1.hexToBytes)(format.prefix);
60
+ cmd.set(prefix, offset);
61
+ offset += prefix.length;
62
+ // Sequence
63
+ const seqBytes = (0, utils_1.hexToBytes)(seq);
64
+ cmd.set(seqBytes, offset);
65
+ offset += seqBytes.length;
66
+ // Mode
67
+ const mode = (0, utils_1.hexToBytes)(format.mode);
68
+ cmd.set(mode, offset);
69
+ offset += mode.length;
70
+ // Register
71
+ const register = (0, utils_1.hexToBytes)(format.register);
72
+ cmd.set(register, offset);
73
+ offset += register.length;
74
+ // Value (little-endian uint16)
75
+ cmd[offset] = pounds & 0xff;
76
+ cmd[offset + 1] = (pounds >> 8) & 0xff;
77
+ offset += 2;
78
+ // Checksum
79
+ const checksumBytes = (0, utils_1.hexToBytes)(checksum);
80
+ cmd.set(checksumBytes, offset);
81
+ offset += checksumBytes.length;
82
+ // Padding
83
+ const padding = (0, utils_1.hexToBytes)(format.padding);
84
+ cmd.set(padding, offset);
85
+ return cmd;
86
+ },
87
+ };
88
+ /**
89
+ * Chains (reverse resistance) command builder for 0-100 lbs.
90
+ * Requires dual commands: send step1, wait 500ms, send step2.
91
+ */
92
+ exports.ChainsCommands = {
93
+ MIN: 0,
94
+ MAX: 100,
95
+ /** Get available chains values */
96
+ getAvailable() {
97
+ return Object.keys(chains.values)
98
+ .map(Number)
99
+ .sort((a, b) => a - b);
100
+ },
101
+ /** Check if a chains value is valid */
102
+ isValid(pounds) {
103
+ return pounds >= this.MIN && pounds <= this.MAX;
104
+ },
105
+ /**
106
+ * Get dual commands to set chains weight.
107
+ * @param pounds Chains weight (0-100)
108
+ * @returns Tuple of (step1, step2) commands, or null if not available
109
+ */
110
+ get(pounds) {
111
+ const key = String(pounds);
112
+ const values = chains.values;
113
+ const format = chains.format;
114
+ if (!(key in values)) {
115
+ return null;
116
+ }
117
+ const data = values[key];
118
+ return {
119
+ step1: this._build(pounds, 1, data.step1_seq, data.step1_checksum, format),
120
+ step2: this._build(pounds, 2, data.step2_seq, data.step2_checksum, format),
121
+ };
122
+ },
123
+ _build(pounds, step, seq, checksum, format) {
124
+ const fmt = format[`step${step}`];
125
+ const cmd = new Uint8Array(21);
126
+ let offset = 0;
127
+ // Prefix
128
+ const prefix = (0, utils_1.hexToBytes)(fmt.prefix);
129
+ cmd.set(prefix, offset);
130
+ offset += prefix.length;
131
+ // Sequence
132
+ const seqBytes = (0, utils_1.hexToBytes)(seq);
133
+ cmd.set(seqBytes, offset);
134
+ offset += seqBytes.length;
135
+ // Mode
136
+ const mode = (0, utils_1.hexToBytes)(fmt.mode);
137
+ cmd.set(mode, offset);
138
+ offset += mode.length;
139
+ // Register
140
+ const register = (0, utils_1.hexToBytes)(fmt.register);
141
+ cmd.set(register, offset);
142
+ offset += register.length;
143
+ // Value (little-endian uint16)
144
+ cmd[offset] = pounds & 0xff;
145
+ cmd[offset + 1] = (pounds >> 8) & 0xff;
146
+ offset += 2;
147
+ // Checksum
148
+ const checksumBytes = (0, utils_1.hexToBytes)(checksum);
149
+ cmd.set(checksumBytes, offset);
150
+ offset += checksumBytes.length;
151
+ // Padding
152
+ const padding = (0, utils_1.hexToBytes)(fmt.padding);
153
+ cmd.set(padding, offset);
154
+ return cmd;
155
+ },
156
+ };
157
+ // =============================================================================
158
+ // Eccentric Commands (883e register)
159
+ // =============================================================================
160
+ /**
161
+ * Eccentric load adjustment command builder for -195 to +195.
162
+ * Requires dual commands: send step1, wait 500ms, send step2.
163
+ */
164
+ exports.EccentricCommands = {
165
+ MIN: -195,
166
+ MAX: 195,
167
+ /** Get available eccentric values */
168
+ getAvailable() {
169
+ return Object.keys(eccentric.step1.checksums)
170
+ .map(Number)
171
+ .sort((a, b) => a - b);
172
+ },
173
+ /** Check if an eccentric value is valid */
174
+ isValid(value) {
175
+ return value >= this.MIN && value <= this.MAX;
176
+ },
177
+ /**
178
+ * Get dual commands to set eccentric load.
179
+ * @param value Eccentric adjustment (-195 to +195)
180
+ * @returns Tuple of (step1, step2) commands, or null if not available
181
+ */
182
+ get(value) {
183
+ const key = String(value);
184
+ if (!(key in eccentric.step1.checksums)) {
185
+ return null;
186
+ }
187
+ return {
188
+ step1: this._build(value, 1),
189
+ step2: this._build(value, 2),
190
+ };
191
+ },
192
+ _build(value, step) {
193
+ const stepKey = `step${step}`;
194
+ const fmt = eccentric.format[stepKey];
195
+ const seq = eccentric[stepKey].sequences[String(value)];
196
+ const checksum = eccentric[stepKey].checksums[String(value)];
197
+ const cmd = new Uint8Array(21);
198
+ let offset = 0;
199
+ // Prefix
200
+ const prefix = (0, utils_1.hexToBytes)(fmt.prefix);
201
+ cmd.set(prefix, offset);
202
+ offset += prefix.length;
203
+ // Sequence
204
+ const seqBytes = (0, utils_1.hexToBytes)(seq);
205
+ cmd.set(seqBytes, offset);
206
+ offset += seqBytes.length;
207
+ // Mode
208
+ const mode = (0, utils_1.hexToBytes)(fmt.mode);
209
+ cmd.set(mode, offset);
210
+ offset += mode.length;
211
+ // Register
212
+ const register = (0, utils_1.hexToBytes)(fmt.register);
213
+ cmd.set(register, offset);
214
+ offset += register.length;
215
+ // Value (little-endian int16, signed)
216
+ const signedValue = value < 0 ? 0x10000 + value : value;
217
+ cmd[offset] = signedValue & 0xff;
218
+ cmd[offset + 1] = (signedValue >> 8) & 0xff;
219
+ offset += 2;
220
+ // Checksum
221
+ const checksumBytes = (0, utils_1.hexToBytes)(checksum);
222
+ cmd.set(checksumBytes, offset);
223
+ offset += checksumBytes.length;
224
+ // Padding
225
+ const padding = (0, utils_1.hexToBytes)(fmt.padding);
226
+ cmd.set(padding, offset);
227
+ return cmd;
228
+ },
229
+ };
230
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../src/voltra/protocol/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/voltra/protocol/constants.ts"],"names":[],"mappings":"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"}