incyclist-devices 1.5.38 → 2.0.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 (267) hide show
  1. package/README.MD +238 -0
  2. package/lib/adapters.d.ts +7 -0
  3. package/lib/adapters.js +49 -0
  4. package/lib/antv2/adapter-factory.d.ts +21 -10
  5. package/lib/antv2/adapter-factory.js +51 -33
  6. package/lib/antv2/adapter.d.ts +65 -0
  7. package/lib/antv2/adapter.js +310 -0
  8. package/lib/antv2/ant-interface.d.ts +17 -11
  9. package/lib/antv2/ant-interface.js +41 -31
  10. package/lib/antv2/{ant-binding.d.ts → binding.d.ts} +1 -1
  11. package/lib/antv2/{ant-binding.js → binding.js} +1 -1
  12. package/lib/antv2/fe/adapter.d.ts +28 -0
  13. package/lib/antv2/{fe.js → fe/adapter.js} +106 -90
  14. package/lib/antv2/fe/index.d.ts +2 -0
  15. package/lib/antv2/fe/index.js +7 -0
  16. package/lib/antv2/hr/adapter.d.ts +15 -0
  17. package/lib/antv2/hr/adapter.js +76 -0
  18. package/lib/antv2/hr/index.d.ts +2 -0
  19. package/lib/antv2/hr/index.js +7 -0
  20. package/lib/antv2/index.d.ts +7 -0
  21. package/lib/antv2/index.js +20 -0
  22. package/lib/antv2/modes/ant-fe-adv-st-mode.d.ts +9 -0
  23. package/lib/{ant/antfe → antv2/modes}/ant-fe-adv-st-mode.js +1 -1
  24. package/lib/antv2/modes/ant-fe-erg-mode.d.ts +6 -0
  25. package/lib/{ant/antfe → antv2/modes}/ant-fe-erg-mode.js +1 -1
  26. package/lib/antv2/modes/ant-fe-st-mode.d.ts +5 -0
  27. package/lib/{ant/antfe → antv2/modes}/ant-fe-st-mode.js +1 -1
  28. package/lib/antv2/pwr/adapter.d.ts +24 -0
  29. package/lib/antv2/pwr/adapter.js +141 -0
  30. package/lib/antv2/pwr/index.d.ts +2 -0
  31. package/lib/antv2/pwr/index.js +7 -0
  32. package/lib/antv2/sensor-factory.d.ts +2 -2
  33. package/lib/antv2/types.d.ts +22 -0
  34. package/lib/antv2/types.js +5 -0
  35. package/lib/antv2/utils.d.ts +4 -0
  36. package/lib/antv2/utils.js +192 -0
  37. package/lib/base/adpater.d.ts +68 -0
  38. package/lib/base/adpater.js +183 -0
  39. package/lib/ble/adapter-factory.d.ts +33 -0
  40. package/lib/ble/adapter-factory.js +105 -0
  41. package/lib/ble/base/adapter.d.ts +53 -0
  42. package/lib/ble/base/adapter.js +290 -0
  43. package/lib/ble/base/comms-utils.d.ts +7 -0
  44. package/lib/ble/base/comms-utils.js +91 -0
  45. package/lib/ble/{ble-device.d.ts → base/comms.d.ts} +31 -16
  46. package/lib/ble/{ble-device.js → base/comms.js} +193 -55
  47. package/lib/ble/bindings/index.d.ts +2 -0
  48. package/lib/ble/bindings/index.js +8 -0
  49. package/lib/ble/bindings/linux.d.ts +15 -0
  50. package/lib/ble/bindings/linux.js +39 -0
  51. package/lib/ble/bindings/mock.d.ts +9 -0
  52. package/lib/ble/bindings/mock.js +108 -0
  53. package/lib/ble/bindings/types.d.ts +57 -0
  54. package/lib/ble/bindings/types.js +96 -0
  55. package/lib/ble/ble-interface.d.ts +38 -59
  56. package/lib/ble/ble-interface.js +254 -462
  57. package/lib/ble/ble-peripheral.d.ts +7 -5
  58. package/lib/ble/ble-peripheral.js +52 -21
  59. package/lib/ble/consts.d.ts +3 -0
  60. package/lib/ble/consts.js +4 -1
  61. package/lib/ble/cp/adapter.d.ts +22 -0
  62. package/lib/ble/cp/adapter.js +111 -0
  63. package/lib/ble/cp/comm.d.ts +31 -0
  64. package/lib/ble/cp/comm.js +125 -0
  65. package/lib/ble/cp/index.d.ts +4 -0
  66. package/lib/ble/cp/index.js +10 -0
  67. package/lib/ble/cp/types.d.ts +13 -0
  68. package/lib/ble/cp/types.js +2 -0
  69. package/lib/ble/elite/adapter.d.ts +19 -0
  70. package/lib/ble/elite/adapter.js +120 -0
  71. package/lib/ble/elite/comms.d.ts +32 -0
  72. package/lib/ble/elite/comms.js +126 -0
  73. package/lib/ble/elite/index.d.ts +3 -0
  74. package/lib/ble/elite/index.js +10 -0
  75. package/lib/ble/fm/adapter.d.ts +22 -0
  76. package/lib/ble/fm/adapter.js +249 -0
  77. package/lib/ble/fm/comms.d.ts +50 -0
  78. package/lib/ble/{fm.js → fm/comms.js} +34 -277
  79. package/lib/ble/fm/consts.d.ts +6 -0
  80. package/lib/ble/fm/consts.js +9 -0
  81. package/lib/ble/fm/index.d.ts +5 -0
  82. package/lib/ble/fm/index.js +13 -0
  83. package/lib/ble/fm/types.d.ts +30 -0
  84. package/lib/ble/fm/types.js +2 -0
  85. package/lib/ble/hr/adapter.d.ts +14 -0
  86. package/lib/ble/hr/adapter.js +45 -0
  87. package/lib/ble/hr/comm.d.ts +19 -0
  88. package/lib/ble/hr/comm.js +56 -0
  89. package/lib/ble/hr/index.d.ts +4 -0
  90. package/lib/ble/hr/index.js +10 -0
  91. package/lib/ble/hr/mock.d.ts +7 -0
  92. package/lib/ble/hr/mock.js +47 -0
  93. package/lib/ble/hr/types.d.ts +5 -0
  94. package/lib/ble/hr/types.js +2 -0
  95. package/lib/ble/index.d.ts +9 -0
  96. package/lib/ble/index.js +26 -0
  97. package/lib/ble/peripheral-cache.d.ts +43 -0
  98. package/lib/ble/peripheral-cache.js +107 -0
  99. package/lib/ble/tacx/adapter.d.ts +10 -0
  100. package/lib/ble/tacx/adapter.js +99 -0
  101. package/lib/ble/{tacx.d.ts → tacx/comms.d.ts} +11 -43
  102. package/lib/ble/{tacx.js → tacx/comms.js} +23 -155
  103. package/lib/ble/tacx/index.d.ts +4 -0
  104. package/lib/ble/tacx/index.js +10 -0
  105. package/lib/ble/tacx/types.d.ts +25 -0
  106. package/lib/ble/tacx/types.js +2 -0
  107. package/lib/ble/types.d.ts +128 -0
  108. package/lib/ble/types.js +2 -0
  109. package/lib/ble/utils.d.ts +17 -0
  110. package/lib/ble/utils.js +54 -0
  111. package/lib/ble/wahoo/adapter.d.ts +9 -0
  112. package/lib/ble/wahoo/adapter.js +95 -0
  113. package/lib/ble/{wahoo-kickr.d.ts → wahoo/comms.d.ts} +11 -44
  114. package/lib/ble/{wahoo-kickr.js → wahoo/comms.js} +29 -129
  115. package/lib/ble/wahoo/index.d.ts +4 -0
  116. package/lib/ble/wahoo/index.js +10 -0
  117. package/lib/ble/wahoo/types.d.ts +19 -0
  118. package/lib/ble/wahoo/types.js +2 -0
  119. package/lib/index.d.ts +15 -0
  120. package/lib/index.js +34 -0
  121. package/lib/interfaces.d.ts +7 -0
  122. package/lib/interfaces.js +27 -0
  123. package/lib/{ble → modes}/ble-erg-mode.d.ts +4 -4
  124. package/lib/{ble → modes}/ble-erg-mode.js +2 -2
  125. package/lib/{ble → modes}/ble-st-mode.d.ts +3 -3
  126. package/lib/{ble → modes}/ble-st-mode.js +1 -1
  127. package/lib/{cycling-mode.d.ts → modes/cycling-mode.d.ts} +8 -8
  128. package/lib/modes/power-base.d.ts +3 -3
  129. package/lib/modes/power-base.js +8 -4
  130. package/lib/modes/power-meter.d.ts +3 -3
  131. package/lib/modes/simulator.d.ts +2 -2
  132. package/lib/modes/simulator.js +1 -1
  133. package/lib/serial/adapter-factory.d.ts +12 -0
  134. package/lib/serial/adapter-factory.js +30 -0
  135. package/lib/serial/adapter.d.ts +21 -0
  136. package/lib/serial/adapter.js +61 -0
  137. package/lib/serial/bindings/tcp.d.ts +45 -0
  138. package/lib/serial/bindings/tcp.js +284 -0
  139. package/lib/serial/comm.d.ts +7 -0
  140. package/lib/serial/comm.js +2 -0
  141. package/lib/{daum → serial/daum}/DaumAdapter.d.ts +14 -23
  142. package/lib/{daum → serial/daum}/DaumAdapter.js +57 -97
  143. package/lib/{daum → serial/daum}/DaumPowerMeterCyclingMode.d.ts +2 -2
  144. package/lib/{daum → serial/daum}/DaumPowerMeterCyclingMode.js +1 -1
  145. package/lib/{daum → serial/daum}/ERGCyclingMode.d.ts +3 -3
  146. package/lib/{daum → serial/daum}/ERGCyclingMode.js +3 -3
  147. package/lib/{daum → serial/daum}/SmartTrainerCyclingMode.d.ts +3 -3
  148. package/lib/{daum → serial/daum}/SmartTrainerCyclingMode.js +4 -3
  149. package/lib/serial/daum/classic/adapter.d.ts +29 -0
  150. package/lib/{daum/classic/DaumClassicAdapter.js → serial/daum/classic/adapter.js} +77 -50
  151. package/lib/{daum/classic/bike.d.ts → serial/daum/classic/comms.d.ts} +14 -16
  152. package/lib/{daum/classic/bike.js → serial/daum/classic/comms.js} +68 -152
  153. package/lib/serial/daum/classic/mock.d.ts +96 -0
  154. package/lib/serial/daum/classic/mock.js +365 -0
  155. package/lib/{daum/classic/DaumClassicCyclingMode.d.ts → serial/daum/classic/modes/daum-classic.d.ts} +3 -3
  156. package/lib/{daum/classic/DaumClassicCyclingMode.js → serial/daum/classic/modes/daum-classic.js} +2 -2
  157. package/lib/{daum → serial/daum}/classic/utils.d.ts +1 -1
  158. package/lib/serial/daum/premium/adapter.d.ts +25 -0
  159. package/lib/{daum/premium/DaumPremiumAdapter.js → serial/daum/premium/adapter.js} +107 -47
  160. package/lib/{daum/premium/bike.d.ts → serial/daum/premium/comms.d.ts} +26 -54
  161. package/lib/{daum/premium/bike.js → serial/daum/premium/comms.js} +215 -420
  162. package/lib/serial/daum/premium/mock.d.ts +75 -0
  163. package/lib/serial/daum/premium/mock.js +289 -0
  164. package/lib/{daum/premium/DaumClassicCyclingMode.d.ts → serial/daum/premium/modes/daum-classic.d.ts} +3 -3
  165. package/lib/{daum/premium/DaumClassicCyclingMode.js → serial/daum/premium/modes/daum-classic.js} +2 -2
  166. package/lib/serial/daum/premium/types.d.ts +12 -0
  167. package/lib/serial/daum/premium/types.js +2 -0
  168. package/lib/{daum → serial/daum}/premium/utils.d.ts +8 -11
  169. package/lib/{daum → serial/daum}/premium/utils.js +22 -63
  170. package/lib/serial/index.d.ts +9 -0
  171. package/lib/serial/index.js +49 -0
  172. package/lib/{kettler → serial/kettler}/comms.d.ts +8 -6
  173. package/lib/{kettler → serial/kettler}/comms.js +71 -32
  174. package/lib/{kettler → serial/kettler}/ergo-racer/adapter.d.ts +14 -28
  175. package/lib/{kettler → serial/kettler}/ergo-racer/adapter.js +102 -169
  176. package/lib/serial/kettler/ergo-racer/mock.d.ts +66 -0
  177. package/lib/serial/kettler/ergo-racer/mock.js +216 -0
  178. package/lib/{kettler/ergo-racer/ERGCyclingMode.d.ts → serial/kettler/ergo-racer/modes/erg.d.ts} +4 -4
  179. package/lib/{kettler/ergo-racer/ERGCyclingMode.js → serial/kettler/ergo-racer/modes/erg.js} +2 -2
  180. package/lib/serial/serial-interface.d.ts +60 -0
  181. package/lib/serial/serial-interface.js +309 -0
  182. package/lib/simulator/Simulator.d.ts +12 -25
  183. package/lib/simulator/Simulator.js +26 -87
  184. package/lib/types/adapter.d.ts +39 -0
  185. package/lib/types/adapter.js +2 -0
  186. package/lib/types/capabilities.d.ts +8 -0
  187. package/lib/types/capabilities.js +12 -0
  188. package/lib/types/data.d.ts +12 -0
  189. package/lib/types/data.js +2 -0
  190. package/lib/types/device.d.ts +32 -0
  191. package/lib/types/device.js +11 -0
  192. package/lib/types/interface.d.ts +18 -0
  193. package/lib/types/interface.js +2 -0
  194. package/lib/types/route.d.ts +2 -2
  195. package/lib/types/user.d.ts +1 -1
  196. package/lib/{utils.d.ts → utils/utils.d.ts} +1 -0
  197. package/lib/{utils.js → utils/utils.js} +5 -1
  198. package/package.json +16 -14
  199. package/lib/DeviceSupport.d.ts +0 -36
  200. package/lib/DeviceSupport.js +0 -82
  201. package/lib/ant/AntAdapter.d.ts +0 -50
  202. package/lib/ant/AntAdapter.js +0 -109
  203. package/lib/ant/AntScanner.d.ts +0 -60
  204. package/lib/ant/AntScanner.js +0 -651
  205. package/lib/ant/antfe/AntFEAdapter.d.ts +0 -83
  206. package/lib/ant/antfe/AntFEAdapter.js +0 -652
  207. package/lib/ant/antfe/ant-fe-adv-st-mode.d.ts +0 -9
  208. package/lib/ant/antfe/ant-fe-erg-mode.d.ts +0 -6
  209. package/lib/ant/antfe/ant-fe-st-mode.d.ts +0 -5
  210. package/lib/ant/anthrm/AntHrmAdapter.d.ts +0 -16
  211. package/lib/ant/anthrm/AntHrmAdapter.js +0 -130
  212. package/lib/ant/antpwr/pwr-adapter.d.ts +0 -49
  213. package/lib/ant/antpwr/pwr-adapter.js +0 -251
  214. package/lib/ant/utils.d.ts +0 -1
  215. package/lib/ant/utils.js +0 -23
  216. package/lib/antv2/AntAdapter.d.ts +0 -48
  217. package/lib/antv2/AntAdapter.js +0 -104
  218. package/lib/antv2/ant-device.d.ts +0 -59
  219. package/lib/antv2/ant-device.js +0 -161
  220. package/lib/antv2/fe.d.ts +0 -32
  221. package/lib/antv2/hr.d.ts +0 -18
  222. package/lib/antv2/hr.js +0 -102
  223. package/lib/antv2/incyclist-protocol.d.ts +0 -37
  224. package/lib/antv2/incyclist-protocol.js +0 -126
  225. package/lib/antv2/pwr.d.ts +0 -28
  226. package/lib/antv2/pwr.js +0 -171
  227. package/lib/ble/ble.d.ts +0 -129
  228. package/lib/ble/ble.js +0 -86
  229. package/lib/ble/elite.d.ts +0 -90
  230. package/lib/ble/elite.js +0 -322
  231. package/lib/ble/fm.d.ts +0 -125
  232. package/lib/ble/hrm.d.ts +0 -48
  233. package/lib/ble/hrm.js +0 -134
  234. package/lib/ble/incyclist-protocol.d.ts +0 -31
  235. package/lib/ble/incyclist-protocol.js +0 -153
  236. package/lib/ble/pwr.d.ts +0 -89
  237. package/lib/ble/pwr.js +0 -322
  238. package/lib/daum/classic/DaumClassicAdapter.d.ts +0 -28
  239. package/lib/daum/classic/DaumClassicProtocol.d.ts +0 -27
  240. package/lib/daum/classic/DaumClassicProtocol.js +0 -185
  241. package/lib/daum/premium/DaumPremiumAdapter.d.ts +0 -16
  242. package/lib/daum/premium/DaumPremiumProtocol.d.ts +0 -32
  243. package/lib/daum/premium/DaumPremiumProtocol.js +0 -207
  244. package/lib/daum/premium/tcpserial.d.ts +0 -33
  245. package/lib/daum/premium/tcpserial.js +0 -123
  246. package/lib/device.d.ts +0 -94
  247. package/lib/device.js +0 -76
  248. package/lib/kettler/ergo-racer/protocol.d.ts +0 -41
  249. package/lib/kettler/ergo-racer/protocol.js +0 -203
  250. package/lib/protocol.d.ts +0 -74
  251. package/lib/protocol.js +0 -41
  252. package/lib/registry.d.ts +0 -8
  253. package/lib/registry.js +0 -33
  254. package/lib/serialport/bindings/tcp.d.ts +0 -20
  255. package/lib/serialport/bindings/tcp.js +0 -33
  256. package/lib/serialport/index.d.ts +0 -2
  257. package/lib/serialport/index.js +0 -29
  258. package/lib/serialport/serialport.d.ts +0 -29
  259. package/lib/serialport/serialport.js +0 -87
  260. /package/lib/{cycling-mode.js → modes/cycling-mode.js} +0 -0
  261. /package/lib/{daum → serial/daum}/classic/utils.js +0 -0
  262. /package/lib/{daum → serial/daum}/constants.d.ts +0 -0
  263. /package/lib/{daum → serial/daum}/constants.js +0 -0
  264. /package/lib/{serialport.d.ts → serial/serialport.d.ts} +0 -0
  265. /package/lib/{serialport.js → serial/serialport.js} +0 -0
  266. /package/lib/{calculations.d.ts → utils/calculations.d.ts} +0 -0
  267. /package/lib/{calculations.js → utils/calculations.js} +0 -0
@@ -13,23 +13,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const gd_eventlog_1 = require("gd-eventlog");
16
- const utils_1 = require("../utils");
17
- const ble_1 = require("./ble");
18
- const ble_2 = require("./ble");
19
- const ble_peripheral_1 = __importDefault(require("./ble-peripheral"));
20
- const CONNECT_TIMEOUT = 5000;
16
+ const adapter_factory_1 = __importDefault(require("./adapter-factory"));
17
+ const utils_1 = require("./utils");
18
+ const comms_utils_1 = require("./base/comms-utils");
19
+ const peripheral_cache_1 = __importDefault(require("./peripheral-cache"));
20
+ const events_1 = __importDefault(require("events"));
21
+ const utils_2 = require("../utils/utils");
21
22
  const DEFAULT_SCAN_TIMEOUT = 20000;
22
- class BleInterface extends ble_1.BleInterfaceClass {
23
- constructor(props = {}) {
24
- super(props);
25
- this.scanState = { isScanning: false, isConnecting: false, timeout: undefined, isBackgroundScan: false };
26
- this.connectState = { isConnecting: false, isConnected: false, isInitSuccess: false };
27
- this.devices = [];
28
- this.peripheralCache = [];
29
- if (props.logger)
30
- this.logger = props.logger;
31
- this.logger = new gd_eventlog_1.EventLogger('BLE');
32
- }
23
+ class BleInterface extends events_1.default {
33
24
  static getInstance(props = {}) {
34
25
  if (!BleInterface._instance) {
35
26
  BleInterface._instance = new BleInterface(props);
@@ -47,10 +38,42 @@ class BleInterface extends ble_1.BleInterfaceClass {
47
38
  }
48
39
  return BleInterface._instance;
49
40
  }
50
- static register(id, type, Class, services) {
51
- if (this.deviceClasses.find(i => i.id === id))
41
+ constructor(props = {}) {
42
+ super();
43
+ this.scanState = { isScanning: false, isConnecting: false, timeout: undefined, isBackgroundScan: false };
44
+ this.connectState = { isConnecting: false, isConnected: false, isInitSuccess: false };
45
+ this.props = props;
46
+ if (props.binding)
47
+ this.setBinding(props.binding);
48
+ this.peripheralCache = new peripheral_cache_1.default();
49
+ this.connectedDevices = [];
50
+ if (props.logger)
51
+ this.logger = props.logger;
52
+ else
53
+ this.logger = new gd_eventlog_1.EventLogger('BLE');
54
+ }
55
+ getBinding() { return this.binding; }
56
+ setBinding(binding) { if (binding)
57
+ this.binding = binding; }
58
+ getName() {
59
+ return 'ble';
60
+ }
61
+ startConnectSensor() {
62
+ this.sensorIsConnecting = true;
63
+ }
64
+ stopConnectSensor() {
65
+ this.sensorIsConnecting = false;
66
+ }
67
+ waitForSensorConnectionFinish() {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ while (this.sensorIsConnecting && this.connectState.isConnected) {
70
+ yield (0, utils_2.sleep)(100);
71
+ }
52
72
  return;
53
- this.deviceClasses.push({ id, type, Class, services });
73
+ });
74
+ }
75
+ getAdapterFactory() {
76
+ return adapter_factory_1.default.getInstance();
54
77
  }
55
78
  logEvent(event) {
56
79
  if (this.logger) {
@@ -61,7 +84,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
61
84
  }
62
85
  }
63
86
  onStateChange(state) {
64
- if (state !== ble_1.BleState.POWERED_ON) {
87
+ if (state !== 'poweredOn') {
65
88
  this.connectState.isConnected = false;
66
89
  }
67
90
  else {
@@ -71,48 +94,25 @@ class BleInterface extends ble_1.BleInterfaceClass {
71
94
  onError(err) {
72
95
  this.logEvent({ message: 'error', error: err.message, stack: err.stack });
73
96
  }
74
- connect(props = {}) {
75
- const timeout = props.timeout || 2000;
97
+ connect(to) {
98
+ const timeout = this.props.timeout || to || 2000;
76
99
  return new Promise((resolve, reject) => {
77
100
  if (this.connectState.isConnected) {
78
101
  return resolve(true);
79
102
  }
80
- this.logEvent({ message: 'connect request', });
103
+ this.logEvent({ message: 'Ble connect request', });
81
104
  if (!this.getBinding())
82
105
  return Promise.reject(new Error('no binding defined'));
83
106
  this.connectState.timeout = setTimeout(() => {
84
107
  this.connectState.isConnected = false;
85
108
  this.connectState.isConnecting = false;
86
109
  this.connectState.timeout = null;
87
- this.logEvent({ message: 'connect result: timeout' });
88
- reject(new Error('timeout'));
110
+ this.logEvent({ message: 'Ble connect result: timeout' });
111
+ resolve(false);
89
112
  }, timeout);
90
113
  try {
91
- if (!this.connectState.isInitSuccess) {
92
- const binding = this.getBinding()._bindings;
93
- if (binding) {
94
- const binding_init_original = binding.init.bind(binding);
95
- const self = this;
96
- binding.on('error', (err) => { this.getBinding().emit('error', err); });
97
- binding.init = function () {
98
- try {
99
- binding_init_original();
100
- self.connectState.isInitSuccess = true;
101
- }
102
- catch (err) {
103
- self.connectState.isInitSuccess = false;
104
- self.connectState.isConnected = false;
105
- self.connectState.isConnecting = false;
106
- self.logEvent({ message: 'connect result: error', error: err.message });
107
- return reject(new Error(err.message));
108
- }
109
- };
110
- }
111
- else {
112
- }
113
- }
114
114
  const state = this.getBinding().state;
115
- if (state === ble_1.BleState.POWERED_ON) {
115
+ if (state === 'poweredOn') {
116
116
  clearTimeout(this.connectState.timeout);
117
117
  this.connectState.timeout = null;
118
118
  this.getBinding().removeAllListeners('stateChange');
@@ -132,14 +132,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
132
132
  return reject(err);
133
133
  });
134
134
  this.getBinding().on('stateChange', (state) => {
135
- if (state === ble_1.BleState.POWERED_ON) {
135
+ if (state === 'poweredOn') {
136
136
  clearTimeout(this.connectState.timeout);
137
137
  this.connectState.timeout = null;
138
138
  this.getBinding().removeAllListeners('stateChange');
139
139
  this.getBinding().on('stateChange', this.onStateChange.bind(this));
140
140
  this.connectState.isConnected = true;
141
141
  this.connectState.isConnecting = false;
142
- this.logEvent({ message: 'connect result: success' });
142
+ this.logEvent({ message: 'Ble connect result: success' });
143
143
  return resolve(true);
144
144
  }
145
145
  else {
@@ -154,7 +154,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
154
154
  if (this.connectState.timeout)
155
155
  clearTimeout(this.connectState.timeout);
156
156
  this.connectState.timeout = null;
157
- this.logEvent({ message: 'connect result: error', error: err.message });
157
+ this.logEvent({ message: 'Ble connect result: error', error: err.message });
158
158
  return reject(new Error('bluetooth unavailable, cause: ' + err.message));
159
159
  }
160
160
  });
@@ -170,11 +170,11 @@ class BleInterface extends ble_1.BleInterfaceClass {
170
170
  if (this.scanState.isScanning) {
171
171
  yield this.stopScan();
172
172
  }
173
- const connectedDevices = this.devices.filter(d => d.isConnected);
173
+ const devices = this.getAdapterFactory().getAllInstances();
174
+ const connectedDevices = devices.filter(d => d.isConnected());
174
175
  for (let i = 0; i < connectedDevices.length; i++) {
175
176
  const d = connectedDevices[i];
176
- const device = d.device;
177
- yield device.disconnect();
177
+ yield d.close();
178
178
  }
179
179
  this.connectState.isConnected = false;
180
180
  this.connectState.isConnecting = false;
@@ -189,83 +189,6 @@ class BleInterface extends ble_1.BleInterfaceClass {
189
189
  isConnected() {
190
190
  return this.connectState.isConnected;
191
191
  }
192
- getDevicesFromServices(deviceTypes, services) {
193
- if (!deviceTypes || !Array.isArray(deviceTypes) || deviceTypes.length === 0) {
194
- return [];
195
- }
196
- const get = (deviceTypes, fnCompare) => {
197
- const types = deviceTypes.filter(DeviceType => {
198
- const C = DeviceType;
199
- let found = false;
200
- if (C.services)
201
- found = C.services.find((s) => fnCompare(s));
202
- return found;
203
- });
204
- return types;
205
- };
206
- if (typeof services === 'string') {
207
- return get(deviceTypes, (s) => (0, ble_2.matches)(s, services));
208
- }
209
- if (Array.isArray(services)) {
210
- const sids = services.map(ble_1.uuid);
211
- return get(deviceTypes, s => {
212
- const res = sids.find((service) => (0, ble_2.matches)(s, service));
213
- return res !== undefined;
214
- });
215
- }
216
- return [];
217
- }
218
- getAllSupportedServices() {
219
- const supported = BleInterface.deviceClasses;
220
- const res = [];
221
- if (supported && supported.length > 0) {
222
- supported.forEach(dc => {
223
- if (dc && dc.services) {
224
- dc.services.forEach(s => {
225
- if (!res.includes(s))
226
- res.push(s);
227
- });
228
- }
229
- });
230
- }
231
- return res;
232
- }
233
- getAllSupportedDeviceTypes() {
234
- const supported = BleInterface.deviceClasses;
235
- return supported.map(dc => dc.Class);
236
- }
237
- getServicesFromDeviceTypes(deviceTypes) {
238
- let services = [];
239
- try {
240
- if (!deviceTypes || !Array.isArray(deviceTypes) || deviceTypes.length === 0) {
241
- return [];
242
- }
243
- deviceTypes.forEach(DeviceType => {
244
- if (DeviceType.services) {
245
- const dtServices = DeviceType.services;
246
- dtServices.forEach(s => {
247
- if (!services.find(s2 => s2 === s))
248
- services.push(s);
249
- });
250
- }
251
- });
252
- }
253
- catch (err) {
254
- console.log(err);
255
- }
256
- return services;
257
- }
258
- getServicesFromDevice(device) {
259
- if (!device)
260
- return [];
261
- const services = [];
262
- const dServices = device.getServiceUUids();
263
- dServices.forEach(s => {
264
- if (!services.find(s2 => s2 === s))
265
- services.push(s);
266
- });
267
- return services;
268
- }
269
192
  waitForConnectFinished(timeout) {
270
193
  const waitStart = Date.now();
271
194
  const waitTimeout = waitStart + timeout;
@@ -282,39 +205,18 @@ class BleInterface extends ble_1.BleInterfaceClass {
282
205
  }, 100);
283
206
  });
284
207
  }
285
- addPeripheralToCache(peripheral, props = {}) {
286
- const info = this.peripheralCache.find(i => i.address === peripheral.address);
287
- const connector = info && info.connector ? info.connector : new ble_peripheral_1.default(this, peripheral);
288
- this.peripheralCache.push(Object.assign({ address: peripheral.address, ts: Date.now(), peripheral, connector }, props));
289
- }
290
208
  onDisconnect(peripheral) {
291
- const idx = this.peripheralCache.findIndex(i => i.address === peripheral.address);
292
- if (idx !== -1)
293
- this.peripheralCache.splice(idx, 1);
294
- }
295
- getConnector(peripheral) {
296
- const info = this.peripheralCache.find(i => i.address === peripheral.address);
297
- if (!info) {
298
- const connector = new ble_peripheral_1.default(this, peripheral);
299
- this.peripheralCache.push({ address: peripheral.address, ts: Date.now(), peripheral, connector });
300
- return connector;
301
- }
302
- return info.connector;
303
- }
304
- findPeripheral(peripheral) {
305
- const info = this.peripheralCache.find(i => i.address === peripheral.address || peripheral.address === i.peripheral.address || peripheral.name === i.peripheral.name || peripheral.id === i.peripheral.id);
306
- return info ? info.peripheral : undefined;
209
+ this.peripheralCache.remove(peripheral);
307
210
  }
308
211
  getCharacteristics(peripheral) {
309
212
  return __awaiter(this, void 0, void 0, function* () {
310
213
  let characteristics = undefined;
311
- let chachedPeripheralInfo = this.peripheralCache.find(i => i.address === peripheral.address);
214
+ let chachedPeripheralInfo = this.peripheralCache.find({ peripheral });
312
215
  if (chachedPeripheralInfo && Date.now() - chachedPeripheralInfo.ts > 600000) {
313
216
  chachedPeripheralInfo.ts = Date.now();
314
217
  }
315
218
  if (!chachedPeripheralInfo) {
316
- this.addPeripheralToCache(peripheral);
317
- chachedPeripheralInfo = this.peripheralCache.find(i => i.address === peripheral.address);
219
+ chachedPeripheralInfo = this.peripheralCache.add({ address: peripheral.address, ts: Date.now(), peripheral });
318
220
  }
319
221
  const connector = chachedPeripheralInfo.connector;
320
222
  if (!chachedPeripheralInfo.characteristics) {
@@ -324,150 +226,23 @@ class BleInterface extends ble_1.BleInterfaceClass {
324
226
  peripheral.state = connector.getState();
325
227
  yield connector.initialize();
326
228
  characteristics = connector.getCharachteristics();
327
- this.logEvent({ message: 'characteristic info (+):', info: characteristics.map(c => `${peripheral.address} ${c.uuid} ${c.properties}`) });
229
+ this.logEvent({ message: 'characteristic info (+):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
328
230
  chachedPeripheralInfo.characteristics = characteristics;
329
231
  chachedPeripheralInfo.state = { isConfigured: true, isLoading: false, isInterrupted: false };
330
232
  }
331
233
  catch (err) {
332
- console.log(err);
234
+ console.log('~~ ERROR', err);
333
235
  }
334
236
  }
335
237
  else {
336
238
  characteristics = chachedPeripheralInfo.characteristics;
337
- this.logEvent({ message: 'characteristic info (*):', info: characteristics.map(c => `${peripheral.address} ${c.uuid} ${c.properties}`) });
239
+ this.logEvent({ message: 'characteristic info (*):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
338
240
  }
339
241
  if (!characteristics)
340
242
  this.logEvent({ message: 'characteristic info:', info: 'none' });
341
243
  return characteristics;
342
244
  });
343
245
  }
344
- getDeviceClasses(peripheral, props = {}) {
345
- let DeviceClasses;
346
- const { deviceTypes, profile, services = peripheral.advertisement.serviceUuids } = props;
347
- if ((!deviceTypes || deviceTypes.length === 0)) {
348
- const classes = BleInterface.deviceClasses.map(c => c.Class);
349
- DeviceClasses = this.getDevicesFromServices(classes, services);
350
- }
351
- else {
352
- DeviceClasses = this.getDevicesFromServices(deviceTypes, services);
353
- }
354
- if (profile && DeviceClasses && DeviceClasses.length > 0) {
355
- DeviceClasses = DeviceClasses.filter(C => {
356
- const device = new C({ peripheral });
357
- if (device.getProfile() !== profile)
358
- return false;
359
- return true;
360
- });
361
- }
362
- return DeviceClasses;
363
- }
364
- createDevice(DeviceClass, peripheral, characteristics) {
365
- try {
366
- const C = DeviceClass;
367
- const device = new C({ peripheral });
368
- const cids = characteristics ? characteristics.map(c => (0, ble_1.uuid)(c.uuid)) : [];
369
- this.logEvent({ message: 'trying to create device', peripheral: peripheral.address, characteristics: cids, profile: device.getProfile() });
370
- const existingDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
371
- if (existingDevice)
372
- return existingDevice.device;
373
- device.setInterface(this);
374
- if (characteristics && device.isMatching(cids)) {
375
- device.characteristics = characteristics;
376
- device.setCharacteristicUUIDs(characteristics.map(c => c.uuid));
377
- return device;
378
- }
379
- else {
380
- this.logEvent({ message: 'failed to create device', peripheral: peripheral.address, profile: device.getProfile() });
381
- }
382
- }
383
- catch (err) {
384
- this.logEvent({ message: 'error', fn: '', error: err.message || err, stack: err.stack });
385
- }
386
- }
387
- connectDevice(requested, timeout = DEFAULT_SCAN_TIMEOUT + CONNECT_TIMEOUT) {
388
- return __awaiter(this, void 0, void 0, function* () {
389
- const { id, name, address } = requested;
390
- const profile = requested instanceof ble_1.BleDeviceClass ?
391
- (requested.getProfile && typeof (requested.getProfile) === 'function' ? requested.getProfile() : undefined) :
392
- requested.profile;
393
- this.logEvent({ message: 'connectDevice', id, name, address, profile, isbusy: this.scanState.isConnecting });
394
- if (this.scanState.isConnecting) {
395
- yield this.waitForConnectFinished(CONNECT_TIMEOUT);
396
- }
397
- this.scanState.isConnecting = true;
398
- const existing = this.devices.find(i => (!profile || i.device.getProfile() === profile) && (i.device.address === requested.address || i.device.id === requested.id || i.device.name === requested.name));
399
- if (existing) {
400
- this.logEvent({ message: 'connect existing device' });
401
- yield existing.device.connect();
402
- this.scanState.isConnecting = false;
403
- return existing.device;
404
- }
405
- const peripheralInfo = this.peripheralCache.find(i => (i.address === requested.address || (i.periphal && i.peripheral.id === requested.id)));
406
- if (peripheralInfo) {
407
- if (!peripheralInfo.characteristic) {
408
- yield this.getCharacteristics(peripheralInfo.periphal);
409
- const DeviceClasses = this.getDeviceClasses(peripheralInfo.peripheral, { profile });
410
- if (!DeviceClasses || DeviceClasses.length === 0)
411
- return;
412
- const devices = DeviceClasses.map(C => this.createDevice(C, peripheralInfo.periphal, peripheralInfo.characteristics));
413
- if (devices && devices.length > 0) {
414
- for (let i = 0; i < devices.length; i++) {
415
- const idx = this.devices.push({ device: devices[i], isConnected: false }) - 1;
416
- if (!devices[i].isConnected())
417
- yield devices[i].connect();
418
- this.devices[idx].isConnected = true;
419
- }
420
- }
421
- }
422
- const connectedDevice = this.devices.find(d => d.isConnected);
423
- if (connectedDevice)
424
- return connectedDevice.device;
425
- }
426
- let devices = [];
427
- let retry = false;
428
- let retryCount = 0;
429
- do {
430
- if (retryCount > 0) {
431
- this.logEvent({ message: 'retry connect device', id, name, address, profile, retryCount });
432
- }
433
- try {
434
- devices = yield this.scan({ timeout: DEFAULT_SCAN_TIMEOUT, requested: requested });
435
- if (devices.length === 0) {
436
- retryCount++;
437
- retry = retryCount < 5;
438
- }
439
- }
440
- catch (err) {
441
- if (err.message === 'scanning already in progress') {
442
- yield (0, utils_1.sleep)(1000);
443
- retryCount++;
444
- retry = retryCount < 5;
445
- continue;
446
- }
447
- this.scanState.isConnecting = false;
448
- throw err;
449
- }
450
- } while (devices.length === 0 && retry);
451
- if (devices.length === 0) {
452
- this.logEvent({ message: 'connectDevice failure', id, name, address, profile, error: 'device not found' });
453
- this.scanState.isConnecting = false;
454
- throw new Error('device not found');
455
- }
456
- if (devices[0]) {
457
- this.logEvent({ message: 'connectDevice connecting', id, name, address, profile });
458
- const connected = yield devices[0].connect();
459
- this.scanState.isConnecting = false;
460
- if (connected) {
461
- this.logEvent({ message: 'connectDevice success', id, name, address, profile });
462
- return devices[0];
463
- }
464
- else {
465
- this.logEvent({ message: 'connectDevice failure', id, name, address, profile });
466
- throw new Error('connect failed');
467
- }
468
- }
469
- });
470
- }
471
246
  waitForScanFinished(timeout) {
472
247
  const waitStart = Date.now();
473
248
  const waitTimeout = waitStart + timeout;
@@ -484,181 +259,222 @@ class BleInterface extends ble_1.BleInterfaceClass {
484
259
  }, 100);
485
260
  });
486
261
  }
487
- getBestDeviceMatch(DeviceClasses) {
488
- if (!DeviceClasses || DeviceClasses.length === 0)
489
- return;
490
- const details = DeviceClasses.map(c => ({ name: c.prototype.constructor.name, priority: c.detectionPriority || 0, class: c }));
491
- details.sort((a, b) => b.priority - a.priority);
492
- return details[0].class;
493
- }
494
- scan(props) {
262
+ onPeripheralFound(p, callback, props = {}) {
495
263
  return __awaiter(this, void 0, void 0, function* () {
496
- const { timeout = DEFAULT_SCAN_TIMEOUT, deviceTypes = [], requested } = props;
497
- let profile;
498
- if (requested)
499
- profile = requested instanceof ble_1.BleDeviceClass ?
500
- (requested.getProfile && typeof (requested.getProfile) === 'function' ? requested.getProfile() : undefined) :
501
- requested.profile;
502
- const { id, address, name } = requested || {};
503
- const scanForDevice = (requested !== null && requested !== undefined);
504
- const services = (!deviceTypes || deviceTypes.length === 0) ? this.getAllSupportedServices() : this.getServicesFromDeviceTypes(deviceTypes);
505
- const bleBinding = this.getBinding();
506
- if (!bleBinding)
507
- return Promise.reject(new Error('no binding defined'));
508
- if (!this.isConnected()) {
509
- yield this.connect();
264
+ let peripheral = p;
265
+ if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName) {
266
+ return;
267
+ }
268
+ const scanForDevice = (props.comms !== undefined) || (props.request !== undefined && props.request !== null);
269
+ const request = props.comms ? props.comms.getSettings() : props.request;
270
+ if (scanForDevice && this.scanState.peripherals.size > 0) {
271
+ return;
272
+ }
273
+ if (!this.scanState.peripherals)
274
+ this.scanState.peripherals = new Map();
275
+ if (peripheral.address === undefined || peripheral.address === '')
276
+ peripheral.address = peripheral.id || peripheral.name;
277
+ const isPeripheralProcessed = this.scanState.peripherals.get(peripheral.address) !== undefined;
278
+ if (isPeripheralProcessed) {
279
+ return;
510
280
  }
511
- const peripheralsProcessed = [];
512
- const devicesProcessed = [];
513
- this.logEvent({ message: 'scan()', props: { timeout }, scanState: this.scanState,
514
- peripheralCache: this.peripheralCache.map(i => ({ address: i.address, ts: i.ts, name: i.peripheral ? i.peripheral.advertisement.localName : '' })),
515
- deviceCache: this.devices.map(i => ({ address: i.device.address, profile: i.device.getProfile(), isConnected: i.isConnected }))
516
- });
517
- let opStr;
518
281
  if (scanForDevice) {
519
- opStr = 'search device';
520
- this.logEvent({ message: 'search device request', services, device: { id, address, name }, deviceTypes });
282
+ let found = false;
283
+ found =
284
+ (request.name && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
285
+ (request.address && request.address === peripheral.address);
286
+ if (!found) {
287
+ return;
288
+ }
289
+ this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
290
+ this.scanState.peripherals.set(peripheral.address, peripheral);
291
+ const characteristics = yield this.getCharacteristics(peripheral);
292
+ callback(peripheral, characteristics);
293
+ return;
521
294
  }
522
295
  else {
523
- opStr = 'scan';
524
- const supported = BleInterface.deviceClasses.map(dc => ({ id: dc.id, type: dc.type, services: dc.services }));
525
- this.logEvent({ message: 'scan start', services, supported });
296
+ this.logEvent({ message: 'BLE scan: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
297
+ this.scanState.peripherals.set(peripheral.address, peripheral);
298
+ const { protocolFilter } = props;
299
+ const connector = this.peripheralCache.getConnector(p);
300
+ const characteristics = yield this.getCharacteristics(p);
301
+ const announcedServices = connector.getServices();
302
+ const services = announcedServices ? announcedServices.map(utils_1.uuid) : undefined;
303
+ peripheral = connector.getPeripheral();
304
+ const DeviceClasses = this.getAdapterFactory().getDeviceClasses(peripheral, { services }) || [];
305
+ const MatchingClasses = protocolFilter && DeviceClasses ? DeviceClasses.filter(C => protocolFilter.includes(C.protocol)) : DeviceClasses;
306
+ const DeviceClass = (0, comms_utils_1.getBestDeviceMatch)(MatchingClasses.filter(C => C.isMatching(characteristics.map(c => c.uuid))));
307
+ this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol) });
308
+ if (!DeviceClass)
309
+ return callback(null);
310
+ const { id, name, address } = (0, utils_1.getPeripheralInfo)(peripheral);
311
+ const settings = { protocol: DeviceClass.protocol, interface: 'ble', id, name: peripheral.name || name, address: peripheral.address || address };
312
+ callback(settings, characteristics);
313
+ }
314
+ });
315
+ }
316
+ scanForDevice(comms, props) {
317
+ return __awaiter(this, void 0, void 0, function* () {
318
+ const { timeout = DEFAULT_SCAN_TIMEOUT } = props;
319
+ const request = comms.getSettings();
320
+ const { protocol } = request;
321
+ const ble = this.getBinding();
322
+ if (!this.isConnected()) {
323
+ yield this.connect();
526
324
  }
325
+ const device = adapter_factory_1.default.getInstance().createInstance(request);
326
+ if (device.isConnected())
327
+ return device.getComms().peripheral;
328
+ let opStr;
329
+ opStr = 'search device';
330
+ this.logEvent({ message: 'search device request', request });
527
331
  if (this.scanState.isScanning) {
528
332
  try {
529
333
  this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
530
334
  yield this.waitForScanFinished(timeout);
531
335
  }
532
336
  catch (err) {
533
- this.logEvent({ message: `${opStr} result: already scanning` });
534
- return Promise.reject(err);
337
+ this.logEvent({ message: `${opStr} result: already scanning`, error: err.message });
338
+ throw (err);
535
339
  }
536
340
  }
537
341
  return new Promise((resolve, reject) => {
538
342
  this.scanState.isScanning = true;
539
- if (scanForDevice) {
540
- if (this.devices && this.devices.length > 0) {
541
- const knownDevices = this.devices.map(i => ({ name: i.device.name, address: i.device.address, isConnected: i.isConnected, connectState: i.device.getConnectState() }));
542
- this.logEvent({ message: `${opStr}: check if already registered`, device: { name, address }, knownDevices });
543
- const existing = this.devices.find(i => (i.device.address === address || i.device.name === name || i.device.id === id));
544
- if (existing)
545
- this.logEvent({ message: `${opStr}: device already registered`, device: { name, address } });
546
- }
547
- }
343
+ this.scanState.peripherals = new Map();
548
344
  const onTimeout = () => {
549
345
  if (!this.scanState.isScanning || !this.scanState.timeout)
550
346
  return;
551
347
  this.scanState.timeout = null;
552
- this.logEvent({ message: `${opStr} result: devices found`, requested: scanForDevice ? { name, address, profile } : undefined, devices: this.devices.map(i => i.device.name + (!i.device.name || i.device.name === '') ? `addr=${i.device.address}` : '') });
553
- this.getBinding().removeAllListeners('discover');
554
- this.logEvent({ message: `${opStr}: stop scanning`, requested: scanForDevice ? { name, address, profile } : undefined, });
555
- bleBinding.stopScanning(() => {
348
+ this.logEvent({ message: `${opStr} result: timeout`, request });
349
+ ble.removeAllListeners('discover');
350
+ this.logEvent({ message: `${opStr}: stop scanning`, request });
351
+ ble.stopScanning(() => {
556
352
  this.scanState.isScanning = false;
557
- if (scanForDevice) {
558
- reject(new Error('device not found'));
559
- return;
560
- }
561
- resolve(this.devices.map(i => i.device));
353
+ reject(new Error('device not found'));
354
+ return;
562
355
  });
563
356
  };
564
- const onPeripheralFound = (peripheral, fromCache = false) => __awaiter(this, void 0, void 0, function* () {
565
- if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName || !peripheral.advertisement.serviceUuids)
566
- return;
567
- if (fromCache) {
568
- this.logEvent({ message: 'adding from Cache', peripheral: peripheral.address });
569
- }
570
- else {
571
- const { id, name, address, advertisement = {} } = peripheral;
572
- this.logEvent({ message: 'BLE scan: found device', peripheral: { id, name: advertisement.localName, address, services: advertisement.serviceUuids } });
573
- }
574
- if (peripheral.address === undefined || peripheral.address === '')
575
- peripheral.address = peripheral.id;
576
- const isPeripheralProcessed = peripheralsProcessed.find(p => p === peripheral.address) !== undefined;
577
- if (isPeripheralProcessed)
578
- return;
579
- peripheralsProcessed.push(peripheral.address);
580
- if (scanForDevice && requested.name && requested.name !== peripheral.advertisement.localName)
581
- return;
582
- const connector = this.getConnector(peripheral);
583
- const characteristics = yield this.getCharacteristics(peripheral);
584
- const connectedServices = connector.getServices();
585
- const services = connectedServices ? connectedServices.map(cs => cs.uuid) : undefined;
586
- const connectedPeripheral = connector.getPeripheral();
587
- const { id, name, address, advertisement = {} } = connectedPeripheral;
588
- const DeviceClasses = this.getDeviceClasses(connectedPeripheral, { profile, services }) || [];
589
- this.logEvent({ message: 'BLE scan: device connected', peripheral: { id, name, address, services: advertisement.serviceUuids }, services, classes: DeviceClasses.map(c => c.prototype.constructor.name) });
590
- let cntFound = 0;
591
- const DeviceClass = this.getBestDeviceMatch(DeviceClasses);
592
- if (!DeviceClass)
593
- return;
594
- if (scanForDevice && cntFound > 0)
595
- return;
596
- const d = this.createDevice(DeviceClass, peripheral, characteristics);
597
- if (!d) {
598
- this.logEvent({ message: `${opStr}: could not create device `, DeviceClass });
599
- return;
600
- }
601
- try {
602
- this.logEvent({ message: `${opStr}: connecting `, device: d.name, profile: d.getProfile(), address: d.address });
603
- yield d.connect();
604
- }
605
- catch (err) {
606
- this.logEvent({ message: 'error', fn: 'onPeripheralFound()', error: err.message || err, stack: err.stack });
607
- }
608
- if (scanForDevice) {
609
- if ((id && id !== '' && d.id === id) ||
610
- (address && address !== '' && d.address === address) ||
611
- (name && name !== '' && d.name === name))
612
- cntFound++;
613
- }
614
- else
615
- cntFound++;
616
- const existing = devicesProcessed.find(device => device.id === d.id && device.getProfile() === d.getProfile());
617
- if (!scanForDevice && cntFound > 0 && !existing) {
618
- this.logEvent({ message: `${opStr}: device found`, device: d.name, profile: d.getProfile(), address: d.address, services: d.services.join(',') });
619
- this.addDeviceToCache(d, peripheral.state === 'connected');
620
- devicesProcessed.push(d);
621
- this.emit('device', d);
622
- return;
357
+ this.logEvent({ message: `${opStr}: start scanning`, request, timeout });
358
+ let services = [];
359
+ if (protocol !== 'tacx') {
360
+ services = (device.getComms().getServices()) || [];
361
+ }
362
+ ble.startScanning(services, false, (err) => {
363
+ if (err) {
364
+ this.logEvent({ message: `${opStr} result: error`, request, error: err.message });
365
+ this.scanState.isScanning = false;
366
+ return reject(err);
623
367
  }
624
- if (scanForDevice && cntFound > 0) {
625
- this.logEvent({ message: `${opStr}: device found`, device: d.name, profile: d.getProfile(), address: d.address, services: d.services.join(',') });
626
- this.addDeviceToCache(d, peripheral.state === 'connected');
627
- devicesProcessed.push(d);
628
- this.emit('device', d);
629
- process.nextTick(() => {
630
- if (this.scanState.timeout) {
631
- clearTimeout(this.scanState.timeout);
632
- this.scanState.timeout = null;
633
- }
634
- this.logEvent({ message: `${opStr}: stop scanning`, requested: scanForDevice ? { name, address, profile } : undefined, });
635
- bleBinding.stopScanning(() => {
636
- this.getBinding().removeAllListeners('discover');
637
- this.scanState.isScanning = false;
638
- resolve([d]);
368
+ ble.on('discover', (p) => {
369
+ this.onPeripheralFound(p, (peripheral, characteristics) => {
370
+ device.getComms().characteristics = characteristics;
371
+ process.nextTick(() => {
372
+ if (this.scanState.timeout) {
373
+ clearTimeout(this.scanState.timeout);
374
+ this.scanState.timeout = null;
375
+ }
376
+ this.logEvent({ message: `${opStr}: stop scanning`, request });
377
+ ble.stopScanning(() => {
378
+ ble.removeAllListeners('discover');
379
+ this.scanState.isScanning = false;
380
+ resolve(peripheral);
381
+ });
639
382
  });
640
- });
383
+ }, { comms });
384
+ });
385
+ const cachedItem = this.peripheralCache.find(request);
386
+ if (cachedItem) {
387
+ this.logEvent({ message: `${opStr}: adding peripheral from cache `, peripheral: (0, utils_1.getPeripheralInfo)(cachedItem.peripheral) });
388
+ ble.emit('discover', cachedItem.peripheral);
641
389
  }
642
390
  });
643
- this.logEvent({ message: `${opStr}: start scanning`, requested: scanForDevice ? { name, address, profile } : undefined, timeout });
644
- let services = [];
645
- if (scanForDevice && name && !name.toLowerCase().startsWith('tacx')) {
646
- if (props.requested instanceof ble_1.BleDeviceClass) {
647
- const device = props.requested;
648
- services = (device.getServices()) || [];
649
- }
391
+ this.scanState.timeout = setTimeout(onTimeout, timeout);
392
+ });
393
+ });
394
+ }
395
+ scan(props = {}) {
396
+ return __awaiter(this, void 0, void 0, function* () {
397
+ const { timeout = DEFAULT_SCAN_TIMEOUT, protocol, protocols } = props;
398
+ const requestedProtocols = protocols || [];
399
+ if (protocol && !requestedProtocols.find(p => p === protocol))
400
+ requestedProtocols.push(protocol);
401
+ const protocolFilter = requestedProtocols.length > 0 ? requestedProtocols : null;
402
+ const services = protocolFilter === null ? this.getAdapterFactory().getAllSupportedServices() : (0, comms_utils_1.getServicesFromProtocols)(protocolFilter);
403
+ const ble = this.getBinding();
404
+ const opStr = 'scan';
405
+ if (this.scanState.isScanning) {
406
+ try {
407
+ this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
408
+ yield this.waitForScanFinished(timeout);
409
+ }
410
+ catch (err) {
411
+ this.logEvent({ message: `${opStr} result: already scanning` });
412
+ throw (err);
650
413
  }
651
- bleBinding.startScanning(services, false, (err) => {
414
+ }
415
+ this.scanState.isScanning = true;
416
+ const tsStart = Date.now();
417
+ const tsTimeoutExpired = tsStart + timeout;
418
+ while (!this.isConnected() && this.scanState.isScanning && Date.now() < tsTimeoutExpired) {
419
+ const connected = yield this.connect();
420
+ if (!connected)
421
+ yield (0, utils_2.sleep)(1000);
422
+ }
423
+ if (Date.now() > tsTimeoutExpired) {
424
+ return [];
425
+ }
426
+ if (!this.scanState.isScanning) {
427
+ return [];
428
+ }
429
+ const adjustedScanTimeout = tsStart - Date.now() + timeout;
430
+ const supported = adapter_factory_1.default.getInstance().getAll().map(i => i.protocol);
431
+ this.logEvent({ message: 'scan start', services, supported });
432
+ return new Promise((resolve, reject) => {
433
+ this.scanState.peripherals = new Map();
434
+ const detected = [];
435
+ const requested = protocolFilter;
436
+ const onTimeout = () => {
437
+ if (!this.scanState.isScanning || !this.scanState.timeout)
438
+ return;
439
+ this.scanState.timeout = null;
440
+ const devices = detected.map(d => {
441
+ const { id, name, address, protocol } = d;
442
+ return { id, name, address, protocol };
443
+ });
444
+ this.logEvent({ message: `${opStr} result: timeout, devices found`, requested, devices });
445
+ ble.removeAllListeners('discover');
446
+ this.logEvent({ message: `${opStr}: stop scanning`, requested });
447
+ ble.stopScanning(() => {
448
+ this.scanState.isScanning = false;
449
+ resolve(detected);
450
+ });
451
+ };
452
+ this.logEvent({ message: `${opStr}: start scanning`, requested, timeout });
453
+ this.scanState.timeout = setTimeout(onTimeout, adjustedScanTimeout);
454
+ ble.startScanning(protocolFilter ? services : [], false, (err) => {
652
455
  if (err) {
653
- this.logEvent({ message: `${opStr} result: error`, requested: scanForDevice ? { name, address, profile } : undefined, error: err.message });
456
+ this.logEvent({ message: `${opStr} result: error`, requested, error: err.message });
654
457
  this.scanState.isScanning = false;
655
458
  return reject(err);
656
459
  }
657
- bleBinding.on('discover', (p) => {
658
- onPeripheralFound(p);
460
+ ble.on('discover', (p) => {
461
+ this.onPeripheralFound(p, (deviceSettings, characteristics) => {
462
+ if (deviceSettings) {
463
+ detected.push(deviceSettings);
464
+ const device = this.getAdapterFactory().createInstance(deviceSettings);
465
+ device.getComms().characteristics = characteristics;
466
+ this.emit('device', deviceSettings);
467
+ }
468
+ }, { protocolFilter });
659
469
  });
470
+ const cachedItems = this.peripheralCache.filter(protocolFilter ? services : []);
471
+ if (cachedItems && cachedItems.length > 0) {
472
+ cachedItems.map(c => c.peripheral).forEach(peripheral => {
473
+ this.logEvent({ message: `${opStr}: adding peripheral from cache `, peripheral: (0, utils_1.getPeripheralInfo)(peripheral) });
474
+ ble.emit('discover', peripheral);
475
+ });
476
+ }
660
477
  });
661
- this.scanState.timeout = setTimeout(onTimeout, timeout);
662
478
  });
663
479
  });
664
480
  }
@@ -669,13 +485,12 @@ class BleInterface extends ble_1.BleInterfaceClass {
669
485
  this.logEvent({ message: 'scan stop result: not scanning' });
670
486
  return true;
671
487
  }
672
- if (!this.getBinding())
488
+ const ble = this.getBinding();
489
+ if (!ble)
673
490
  throw new Error('no binding defined');
674
- this.getBinding().removeAllListeners('discover');
675
- const ongoing = this.peripheralCache.filter(i => i.state && i.state.isLoading);
676
- if (ongoing)
677
- ongoing.forEach(i => { i.isInterrupted = true; });
678
- yield this.getBinding().stopScanning();
491
+ ble.removeAllListeners('discover');
492
+ this.peripheralCache.handleStopScan();
493
+ ble.stopScanning();
679
494
  this.scanState.isScanning = false;
680
495
  this.logEvent({ message: 'scan stop result: success' });
681
496
  return true;
@@ -685,37 +500,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
685
500
  return this.scanState.isScanning === true;
686
501
  }
687
502
  addConnectedDevice(device) {
688
- const existigDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
689
- if (existigDevice) {
690
- existigDevice.isConnected = true;
691
- return;
692
- }
693
- this.devices.push({ device, isConnected: true });
694
- }
695
- addDeviceToCache(device, isConnected) {
696
- const existigDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
697
- if (existigDevice) {
698
- return;
699
- }
700
- this.devices.push({ device, isConnected });
701
- }
702
- findConnected(device) {
703
- const connected = this.devices.find(i => i.device.id === device.id && i.isConnected);
704
- if (connected)
705
- return connected.device;
706
- return undefined;
707
- }
708
- findDeviceInCache(device) {
709
- const existing = this.devices.find(i => (i.device.id === device.id || i.device.address === device.address || i.device.name === device.name) && i.device.getProfile() === device.profile);
710
- return existing ? existing.device : undefined;
503
+ const idx = this.connectedDevices.findIndex(d => d.isSame(device));
504
+ if (idx === -1)
505
+ this.connectedDevices.push(device);
711
506
  }
712
507
  removeConnectedDevice(device) {
713
- const existigDevice = this.devices.find(i => i.device.id === device.id);
714
- if (existigDevice) {
715
- existigDevice.isConnected = false;
716
- return;
717
- }
508
+ const idx = this.connectedDevices.findIndex(d => d.isSame(device));
509
+ if (idx !== -1)
510
+ this.connectedDevices.splice(idx);
718
511
  }
719
512
  }
720
513
  exports.default = BleInterface;
721
- BleInterface.deviceClasses = [];