tesla-fleet-api 0.3.0 → 0.5.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 (342) hide show
  1. package/README.md +284 -1
  2. package/dist/_virtual/_rolldown/runtime.cjs +32 -0
  3. package/dist/_virtual/_rolldown/runtime.mjs +12 -0
  4. package/dist/bluetooth/adapters/shared.cjs +38 -0
  5. package/dist/bluetooth/adapters/shared.mjs +36 -0
  6. package/dist/bluetooth/async.cjs +121 -0
  7. package/dist/bluetooth/async.d.cts +10 -0
  8. package/dist/bluetooth/async.d.mts +10 -0
  9. package/dist/bluetooth/async.mjs +116 -0
  10. package/dist/bluetooth/broadcast.cjs +153 -0
  11. package/dist/bluetooth/broadcast.d.cts +59 -0
  12. package/dist/bluetooth/broadcast.d.mts +59 -0
  13. package/dist/bluetooth/broadcast.mjs +151 -0
  14. package/dist/bluetooth/constants.cjs +99 -0
  15. package/dist/bluetooth/constants.d.cts +70 -0
  16. package/dist/bluetooth/constants.d.mts +70 -0
  17. package/dist/bluetooth/constants.mjs +72 -0
  18. package/dist/bluetooth/esphome.cjs +292 -0
  19. package/dist/bluetooth/esphome.d.cts +83 -0
  20. package/dist/bluetooth/esphome.d.mts +83 -0
  21. package/dist/bluetooth/esphome.mjs +291 -0
  22. package/dist/bluetooth/framing.cjs +125 -0
  23. package/dist/bluetooth/framing.d.cts +45 -0
  24. package/dist/bluetooth/framing.d.mts +45 -0
  25. package/dist/bluetooth/framing.mjs +122 -0
  26. package/dist/bluetooth/homey.cjs +155 -0
  27. package/dist/bluetooth/homey.d.cts +75 -0
  28. package/dist/bluetooth/homey.d.mts +75 -0
  29. package/dist/bluetooth/homey.mjs +150 -0
  30. package/dist/bluetooth/names.cjs +24 -0
  31. package/dist/bluetooth/names.d.cts +10 -0
  32. package/dist/bluetooth/names.d.mts +10 -0
  33. package/dist/bluetooth/names.mjs +20 -0
  34. package/dist/bluetooth/noble.cjs +178 -0
  35. package/dist/bluetooth/noble.d.cts +58 -0
  36. package/dist/bluetooth/noble.d.mts +58 -0
  37. package/dist/bluetooth/noble.mjs +177 -0
  38. package/dist/bluetooth/streamglue.cjs +157 -0
  39. package/dist/bluetooth/streamglue.d.cts +37 -0
  40. package/dist/bluetooth/streamglue.d.mts +37 -0
  41. package/dist/bluetooth/streamglue.mjs +154 -0
  42. package/dist/bluetooth/teslabluetooth.cjs +67 -0
  43. package/dist/bluetooth/teslabluetooth.d.cts +41 -0
  44. package/dist/bluetooth/teslabluetooth.d.mts +41 -0
  45. package/dist/bluetooth/teslabluetooth.mjs +66 -0
  46. package/dist/bluetooth/transport.cjs +10 -0
  47. package/dist/bluetooth/transport.d.cts +95 -0
  48. package/dist/bluetooth/transport.d.mts +95 -0
  49. package/dist/bluetooth/transport.mjs +10 -0
  50. package/dist/bluetooth/vehiclebluetooth.cjs +1272 -0
  51. package/dist/bluetooth/vehiclebluetooth.d.cts +495 -0
  52. package/dist/bluetooth/vehiclebluetooth.d.mts +495 -0
  53. package/dist/bluetooth/vehiclebluetooth.mjs +1270 -0
  54. package/dist/bluetooth/verify.cjs +93 -0
  55. package/dist/bluetooth/verify.d.cts +35 -0
  56. package/dist/bluetooth/verify.d.mts +35 -0
  57. package/dist/bluetooth/verify.mjs +91 -0
  58. package/dist/bluetooth.cjs +53 -0
  59. package/dist/bluetooth.d.cts +10 -0
  60. package/dist/bluetooth.d.mts +10 -0
  61. package/dist/bluetooth.mjs +9 -0
  62. package/dist/charging.cjs +53 -0
  63. package/dist/charging.d.cts +31 -0
  64. package/dist/charging.d.mts +30 -0
  65. package/dist/charging.mjs +53 -0
  66. package/dist/commands.cjs +1797 -0
  67. package/dist/commands.d.cts +881 -0
  68. package/dist/commands.d.mts +881 -0
  69. package/dist/commands.mjs +1791 -0
  70. package/dist/const.cjs +322 -0
  71. package/dist/const.d.cts +308 -0
  72. package/dist/const.d.mts +308 -0
  73. package/dist/const.mjs +282 -0
  74. package/dist/energy.cjs +142 -0
  75. package/dist/energy.d.cts +101 -0
  76. package/dist/energy.d.mts +100 -0
  77. package/dist/energy.mjs +142 -0
  78. package/dist/energyisland.cjs +38 -0
  79. package/dist/energyisland.mjs +37 -0
  80. package/dist/energyparsers.cjs +118 -0
  81. package/dist/energyparsers.d.cts +39 -0
  82. package/dist/energyparsers.d.mts +39 -0
  83. package/dist/energyparsers.mjs +116 -0
  84. package/dist/energyspecific.cjs +457 -0
  85. package/dist/energyspecific.d.cts +258 -0
  86. package/dist/energyspecific.d.mts +258 -0
  87. package/dist/energyspecific.mjs +451 -0
  88. package/dist/exceptions.cjs +1488 -0
  89. package/dist/exceptions.d.cts +1143 -0
  90. package/dist/exceptions.d.mts +1143 -0
  91. package/dist/exceptions.mjs +1325 -0
  92. package/dist/funnel.cjs +297 -0
  93. package/dist/funnel.d.cts +118 -0
  94. package/dist/funnel.d.mts +118 -0
  95. package/dist/funnel.mjs +292 -0
  96. package/dist/index.cjs +287 -0
  97. package/dist/index.d.cts +28 -0
  98. package/dist/index.d.mts +28 -0
  99. package/dist/index.mjs +27 -0
  100. package/dist/log.cjs +75 -0
  101. package/dist/log.d.cts +4 -0
  102. package/dist/log.d.mts +4 -0
  103. package/dist/log.mjs +71 -0
  104. package/dist/oauth.cjs +143 -0
  105. package/dist/oauth.d.cts +69 -0
  106. package/dist/oauth.d.mts +69 -0
  107. package/dist/oauth.mjs +143 -0
  108. package/dist/partner.cjs +32 -0
  109. package/dist/partner.d.cts +24 -0
  110. package/dist/partner.d.mts +23 -0
  111. package/dist/partner.mjs +32 -0
  112. package/dist/powerwall/client.cjs +818 -0
  113. package/dist/powerwall/client.d.cts +297 -0
  114. package/dist/powerwall/client.d.mts +297 -0
  115. package/dist/powerwall/client.mjs +807 -0
  116. package/dist/powerwall/components.cjs +188 -0
  117. package/dist/powerwall/components.d.cts +45 -0
  118. package/dist/powerwall/components.d.mts +45 -0
  119. package/dist/powerwall/components.mjs +182 -0
  120. package/dist/powerwall/energysite.cjs +216 -0
  121. package/dist/powerwall/energysite.d.cts +104 -0
  122. package/dist/powerwall/energysite.d.mts +104 -0
  123. package/dist/powerwall/energysite.mjs +214 -0
  124. package/dist/powerwall/exceptions.cjs +59 -0
  125. package/dist/powerwall/exceptions.d.cts +38 -0
  126. package/dist/powerwall/exceptions.d.mts +38 -0
  127. package/dist/powerwall/exceptions.mjs +51 -0
  128. package/dist/powerwall/gateway.cjs +102 -0
  129. package/dist/powerwall/gateway.d.cts +57 -0
  130. package/dist/powerwall/gateway.d.mts +57 -0
  131. package/dist/powerwall/gateway.mjs +101 -0
  132. package/dist/powerwall/merge.cjs +163 -0
  133. package/dist/powerwall/merge.d.cts +63 -0
  134. package/dist/powerwall/merge.d.mts +63 -0
  135. package/dist/powerwall/merge.mjs +159 -0
  136. package/dist/powerwall/models.d.cts +95 -0
  137. package/dist/powerwall/models.d.mts +95 -0
  138. package/dist/powerwall/queries.cjs +17 -0
  139. package/dist/powerwall/queries.mjs +10 -0
  140. package/dist/powerwall/transport.cjs +232 -0
  141. package/dist/powerwall/transport.mjs +227 -0
  142. package/dist/powerwall.cjs +47 -0
  143. package/dist/powerwall.d.cts +9 -0
  144. package/dist/powerwall.d.mts +9 -0
  145. package/dist/powerwall.mjs +8 -0
  146. package/dist/router/base.cjs +203 -0
  147. package/dist/router/base.d.cts +112 -0
  148. package/dist/router/base.d.mts +112 -0
  149. package/dist/router/base.mjs +200 -0
  150. package/dist/router/energysite.cjs +65 -0
  151. package/dist/router/energysite.d.cts +47 -0
  152. package/dist/router/energysite.d.mts +47 -0
  153. package/dist/router/energysite.mjs +60 -0
  154. package/dist/router.cjs +13 -0
  155. package/dist/router.d.cts +3 -0
  156. package/dist/router.d.mts +3 -0
  157. package/dist/router.mjs +3 -0
  158. package/dist/signing/crypto.cjs +59 -0
  159. package/dist/signing/crypto.mjs +52 -0
  160. package/dist/signing/energy.cjs +123 -0
  161. package/dist/signing/energy.d.cts +45 -0
  162. package/dist/signing/energy.d.mts +45 -0
  163. package/dist/signing/energy.mjs +120 -0
  164. package/dist/signing/jws.cjs +229 -0
  165. package/dist/signing/jws.d.cts +45 -0
  166. package/dist/signing/jws.d.mts +45 -0
  167. package/dist/signing/jws.mjs +211 -0
  168. package/dist/signing/keys.cjs +191 -0
  169. package/dist/signing/keys.d.cts +21 -0
  170. package/dist/signing/keys.d.mts +21 -0
  171. package/dist/signing/keys.mjs +182 -0
  172. package/dist/signing/session.cjs +186 -0
  173. package/dist/signing/session.d.cts +106 -0
  174. package/dist/signing/session.d.mts +106 -0
  175. package/dist/signing/session.mjs +184 -0
  176. package/dist/tariff.cjs +319 -0
  177. package/dist/tariff.d.cts +40 -0
  178. package/dist/tariff.d.mts +40 -0
  179. package/dist/tariff.mjs +317 -0
  180. package/dist/teslafleetapi.cjs +326 -0
  181. package/dist/teslafleetapi.d.cts +160 -0
  182. package/dist/teslafleetapi.d.mts +160 -0
  183. package/dist/teslafleetapi.mjs +326 -0
  184. package/dist/teslemetry.cjs +183 -0
  185. package/dist/teslemetry.d.cts +113 -0
  186. package/dist/teslemetry.d.mts +113 -0
  187. package/dist/teslemetry.mjs +181 -0
  188. package/dist/teslemetryenergy.cjs +287 -0
  189. package/dist/teslemetryenergy.d.cts +154 -0
  190. package/dist/teslemetryenergy.d.mts +154 -0
  191. package/dist/teslemetryenergy.mjs +282 -0
  192. package/dist/teslemetryvehicle.cjs +407 -0
  193. package/dist/teslemetryvehicle.d.cts +238 -0
  194. package/dist/teslemetryvehicle.d.mts +238 -0
  195. package/dist/teslemetryvehicle.mjs +405 -0
  196. package/dist/tessie.cjs +71 -0
  197. package/dist/tessie.d.cts +69 -0
  198. package/dist/tessie.d.mts +69 -0
  199. package/dist/tessie.mjs +71 -0
  200. package/dist/tessievehicle.cjs +514 -0
  201. package/dist/tessievehicle.d.cts +333 -0
  202. package/dist/tessievehicle.d.mts +333 -0
  203. package/dist/tessievehicle.mjs +513 -0
  204. package/dist/types/commands.d.cts +28 -0
  205. package/dist/types/commands.d.mts +28 -0
  206. package/dist/types/live_status.d.cts +30 -0
  207. package/dist/types/live_status.d.mts +30 -0
  208. package/dist/types/products.d.cts +58 -0
  209. package/dist/types/products.d.mts +58 -0
  210. package/dist/types/responses.d.cts +13 -0
  211. package/dist/types/responses.d.mts +13 -0
  212. package/dist/types/site_info.d.cts +154 -0
  213. package/dist/types/site_info.d.mts +154 -0
  214. package/dist/types/vehicle.d.cts +33 -0
  215. package/dist/types/vehicle.d.mts +33 -0
  216. package/dist/types/vehicle_data.d.cts +278 -0
  217. package/dist/types/vehicle_data.d.mts +278 -0
  218. package/dist/types.cjs +0 -0
  219. package/dist/types.d.cts +9 -0
  220. package/dist/types.d.mts +9 -0
  221. package/dist/types.mjs +1 -0
  222. package/dist/user.cjs +28 -0
  223. package/dist/user.d.cts +17 -0
  224. package/dist/user.d.mts +16 -0
  225. package/dist/user.mjs +28 -0
  226. package/dist/util.cjs +41 -0
  227. package/dist/util.d.cts +18 -0
  228. package/dist/util.d.mts +18 -0
  229. package/dist/util.mjs +40 -0
  230. package/dist/vehicle.cjs +847 -0
  231. package/dist/vehicle.d.cts +566 -0
  232. package/dist/vehicle.d.mts +565 -0
  233. package/dist/vehicle.mjs +847 -0
  234. package/dist/vehiclesigned.cjs +35 -0
  235. package/dist/vehiclesigned.d.cts +23 -0
  236. package/dist/vehiclesigned.d.mts +22 -0
  237. package/dist/vehiclesigned.mjs +35 -0
  238. package/dist/vehiclespecific.cjs +715 -0
  239. package/dist/vehiclespecific.d.cts +497 -0
  240. package/dist/vehiclespecific.d.mts +496 -0
  241. package/dist/vehiclespecific.mjs +715 -0
  242. package/package.json +178 -38
  243. package/dist/charging.d.ts +0 -30
  244. package/dist/charging.js +0 -51
  245. package/dist/charging.js.map +0 -1
  246. package/dist/commands.d.ts +0 -352
  247. package/dist/commands.js +0 -875
  248. package/dist/commands.js.map +0 -1
  249. package/dist/energy.d.ts +0 -94
  250. package/dist/energy.js +0 -125
  251. package/dist/energy.js.map +0 -1
  252. package/dist/energyspecific.d.ts +0 -77
  253. package/dist/energyspecific.js +0 -97
  254. package/dist/energyspecific.js.map +0 -1
  255. package/dist/helpers.d.ts +0 -2
  256. package/dist/helpers.js +0 -10
  257. package/dist/helpers.js.map +0 -1
  258. package/dist/index.d.ts +0 -15
  259. package/dist/index.js +0 -15
  260. package/dist/index.js.map +0 -1
  261. package/dist/partner.d.ts +0 -23
  262. package/dist/partner.js +0 -31
  263. package/dist/partner.js.map +0 -1
  264. package/dist/signing/crypto.d.ts +0 -10
  265. package/dist/signing/crypto.js +0 -26
  266. package/dist/signing/crypto.js.map +0 -1
  267. package/dist/signing/errors.d.ts +0 -29
  268. package/dist/signing/errors.js +0 -40
  269. package/dist/signing/errors.js.map +0 -1
  270. package/dist/signing/session.d.ts +0 -69
  271. package/dist/signing/session.js +0 -102
  272. package/dist/signing/session.js.map +0 -1
  273. package/dist/tariff.d.ts +0 -29
  274. package/dist/tariff.js +0 -302
  275. package/dist/tariff.js.map +0 -1
  276. package/dist/teslafleetapi.d.ts +0 -58
  277. package/dist/teslafleetapi.js +0 -120
  278. package/dist/teslafleetapi.js.map +0 -1
  279. package/dist/teslemetry.d.ts +0 -29
  280. package/dist/teslemetry.js +0 -39
  281. package/dist/teslemetry.js.map +0 -1
  282. package/dist/tessie.d.ts +0 -23
  283. package/dist/tessie.js +0 -28
  284. package/dist/tessie.js.map +0 -1
  285. package/dist/types/commands.d.ts +0 -44
  286. package/dist/types/commands.js +0 -11
  287. package/dist/types/commands.js.map +0 -1
  288. package/dist/types/live_status.d.ts +0 -26
  289. package/dist/types/live_status.js +0 -2
  290. package/dist/types/live_status.js.map +0 -1
  291. package/dist/types/products.d.ts +0 -54
  292. package/dist/types/products.js +0 -2
  293. package/dist/types/products.js.map +0 -1
  294. package/dist/types/responses.d.ts +0 -5
  295. package/dist/types/responses.js +0 -2
  296. package/dist/types/responses.js.map +0 -1
  297. package/dist/types/site_info.d.ts +0 -150
  298. package/dist/types/site_info.js +0 -2
  299. package/dist/types/site_info.js.map +0 -1
  300. package/dist/types/vehicle.d.ts +0 -23
  301. package/dist/types/vehicle.js +0 -10
  302. package/dist/types/vehicle.js.map +0 -1
  303. package/dist/types/vehicle_data.d.ts +0 -274
  304. package/dist/types/vehicle_data.js +0 -2
  305. package/dist/types/vehicle_data.js.map +0 -1
  306. package/dist/user.d.ts +0 -16
  307. package/dist/user.js +0 -26
  308. package/dist/user.js.map +0 -1
  309. package/dist/vehicle.d.ts +0 -548
  310. package/dist/vehicle.js +0 -774
  311. package/dist/vehicle.js.map +0 -1
  312. package/dist/vehiclesigned.d.ts +0 -13
  313. package/dist/vehiclesigned.js +0 -19
  314. package/dist/vehiclesigned.js.map +0 -1
  315. package/dist/vehiclespecific.d.ts +0 -432
  316. package/dist/vehiclespecific.js +0 -601
  317. package/dist/vehiclespecific.js.map +0 -1
  318. package/src/charging.ts +0 -66
  319. package/src/commands.ts +0 -1134
  320. package/src/energy.ts +0 -217
  321. package/src/energyspecific.ts +0 -116
  322. package/src/helpers.ts +0 -11
  323. package/src/index.ts +0 -21
  324. package/src/partner.ts +0 -37
  325. package/src/signing/crypto.ts +0 -29
  326. package/src/signing/errors.ts +0 -50
  327. package/src/signing/session.ts +0 -132
  328. package/src/tariff.ts +0 -375
  329. package/src/teslafleetapi.ts +0 -182
  330. package/src/teslemetry.ts +0 -54
  331. package/src/tessie.ts +0 -42
  332. package/src/types/commands.ts +0 -62
  333. package/src/types/live_status.ts +0 -27
  334. package/src/types/products.ts +0 -61
  335. package/src/types/responses.ts +0 -1
  336. package/src/types/site_info.ts +0 -159
  337. package/src/types/vehicle.ts +0 -33
  338. package/src/types/vehicle_data.ts +0 -286
  339. package/src/user.ts +0 -35
  340. package/src/vehicle.ts +0 -886
  341. package/src/vehiclesigned.ts +0 -20
  342. package/src/vehiclespecific.ts +0 -818
@@ -0,0 +1,153 @@
1
+ const require_commands = require("../commands.cjs");
2
+ let _teslemetry_tesla_protocol_command_universal_message = require("@teslemetry/tesla-protocol/command/universal_message");
3
+ let _teslemetry_tesla_protocol_command_vcsec = require("@teslemetry/tesla-protocol/command/vcsec");
4
+ // src/bluetooth/broadcast.ts
5
+ /**
6
+ * Local callbacks, not tied to a connection, so they live as long as the
7
+ * vehicle and survive reconnects. A callback that throws is logged, and neither
8
+ * later callbacks nor message routing see it.
9
+ */
10
+ var ListenerRegistry = class {
11
+ log;
12
+ entries = [];
13
+ constructor(log) {
14
+ this.log = log;
15
+ }
16
+ get size() {
17
+ return this.entries.length;
18
+ }
19
+ add(callback) {
20
+ const entry = { callback };
21
+ this.entries.push(entry);
22
+ return () => {
23
+ this.entries = this.entries.filter((other) => other !== entry);
24
+ };
25
+ }
26
+ emit(value) {
27
+ for (const { callback } of this.entries) try {
28
+ callback(value);
29
+ } catch (error) {
30
+ this.log(`BLE listener failed: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`);
31
+ }
32
+ }
33
+ };
34
+ /**
35
+ * A broadcast's VCSEC status, if it carries one. Broadcasts are unsigned, so
36
+ * they need no session and prove nothing about who sent them.
37
+ */
38
+ function decodeVcsecStatus(message) {
39
+ if (message.protobufMessageAsBytes === void 0) return null;
40
+ try {
41
+ return _teslemetry_tesla_protocol_command_vcsec.FromVCSECMessage.decode(message.protobufMessageAsBytes).vehicleStatus ?? null;
42
+ } catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * Persistent listeners for unsolicited broadcasts, which arrive on the same
48
+ * notifications as command replies. Each `VehicleStatus` leaf has a typed
49
+ * `listen_*`, and `listen_broadcast` takes every raw broadcast on a domain,
50
+ * including payloads with no typed listener.
51
+ *
52
+ * The scalar listeners fire on every status broadcast with whatever value it
53
+ * holds, because proto3 has no presence on them, so a lock-only broadcast also
54
+ * reports `GEAR_UNKNOWN`. The closure listeners fire only when the broadcast
55
+ * carries the block they read.
56
+ */
57
+ var BroadcastListeners = class extends require_commands.default {
58
+ statusListeners = new ListenerRegistry((message) => this.log(message));
59
+ domainListeners = /* @__PURE__ */ new Map();
60
+ log(message) {
61
+ this.parent.parent._log(message);
62
+ }
63
+ /** Hand one unaddressed message to everything listening. */
64
+ dispatchBroadcast(domain, message) {
65
+ this.domainListeners.get(domain)?.emit(message);
66
+ if (domain === _teslemetry_tesla_protocol_command_universal_message.Domain.DOMAIN_VEHICLE_SECURITY && this.statusListeners.size > 0) {
67
+ const status = decodeVcsecStatus(message);
68
+ if (status) this.statusListeners.emit(status);
69
+ }
70
+ }
71
+ listenClosure(callback) {
72
+ return this.statusListeners.add((status) => {
73
+ if (status.closureStatuses) callback(status.closureStatuses);
74
+ });
75
+ }
76
+ /** Listen for every unsolicited broadcast on `domain`, including `VehicleStatus`. */
77
+ listen_broadcast(domain, callback) {
78
+ let registry = this.domainListeners.get(domain);
79
+ if (!registry) {
80
+ registry = new ListenerRegistry((message) => this.log(message));
81
+ this.domainListeners.set(domain, registry);
82
+ }
83
+ return registry.add(callback);
84
+ }
85
+ /** Listen for the vehicle's overall lock state. */
86
+ listen_vehicle_lock_state(callback) {
87
+ return this.statusListeners.add((status) => callback(status.vehicleLockState));
88
+ }
89
+ /** Listen for the vehicle's sleep status. */
90
+ listen_vehicle_sleep_status(callback) {
91
+ return this.statusListeners.add((status) => callback(status.vehicleSleepStatus));
92
+ }
93
+ /** Listen for driver presence. */
94
+ listen_user_presence(callback) {
95
+ return this.statusListeners.add((status) => callback(status.userPresence));
96
+ }
97
+ /** Listen for the gear selection. */
98
+ listen_gear(callback) {
99
+ return this.statusListeners.add((status) => callback(status.gear));
100
+ }
101
+ /** Listen for the UI desire state. */
102
+ listen_ui_desire(callback) {
103
+ return this.statusListeners.add((status) => callback(status.UIDesire));
104
+ }
105
+ /** Listen for the tonneau's open percentage, on broadcasts that carry it. */
106
+ listen_tonneau_percent_open(callback) {
107
+ return this.statusListeners.add((status) => {
108
+ if (status.detailedClosureStatus) callback(status.detailedClosureStatus.tonneauPercentOpen);
109
+ });
110
+ }
111
+ /**
112
+ * Listen for a broadcast's whole closure block in one call. The listeners
113
+ * below each fire separately for the same broadcast.
114
+ */
115
+ listen_closure_statuses(callback) {
116
+ return this.listenClosure(callback);
117
+ }
118
+ /** Listen for the front driver door. */
119
+ listen_front_driver_door(callback) {
120
+ return this.listenClosure((closures) => callback(closures.frontDriverDoor));
121
+ }
122
+ /** Listen for the front passenger door. */
123
+ listen_front_passenger_door(callback) {
124
+ return this.listenClosure((closures) => callback(closures.frontPassengerDoor));
125
+ }
126
+ /** Listen for the rear driver door. */
127
+ listen_rear_driver_door(callback) {
128
+ return this.listenClosure((closures) => callback(closures.rearDriverDoor));
129
+ }
130
+ /** Listen for the rear passenger door. */
131
+ listen_rear_passenger_door(callback) {
132
+ return this.listenClosure((closures) => callback(closures.rearPassengerDoor));
133
+ }
134
+ /** Listen for the front trunk. */
135
+ listen_front_trunk(callback) {
136
+ return this.listenClosure((closures) => callback(closures.frontTrunk));
137
+ }
138
+ /** Listen for the rear trunk. */
139
+ listen_rear_trunk(callback) {
140
+ return this.listenClosure((closures) => callback(closures.rearTrunk));
141
+ }
142
+ /** Listen for the charge port. */
143
+ listen_charge_port(callback) {
144
+ return this.listenClosure((closures) => callback(closures.chargePort));
145
+ }
146
+ /** Listen for the tonneau. */
147
+ listen_tonneau(callback) {
148
+ return this.listenClosure((closures) => callback(closures.tonneau));
149
+ }
150
+ };
151
+ exports.BroadcastListeners = BroadcastListeners;
152
+ exports.ListenerRegistry = ListenerRegistry;
153
+ exports.decodeVcsecStatus = decodeVcsecStatus;
@@ -0,0 +1,59 @@
1
+ import Commands from "../commands.cjs";
2
+ import { Domain, RoutableMessage } from "@teslemetry/tesla-protocol/command/universal_message";
3
+ import { ClosureStateE, ClosureStatuses, GearE, UIDesireE, UserPresenceE, VehicleLockStateE, VehicleSleepStatusE, VehicleStatus } from "@teslemetry/tesla-protocol/command/vcsec";
4
+ /** Removes a listener. Safe to call twice. */
5
+ export type Unsubscribe = () => void;
6
+ /**
7
+ * Persistent listeners for unsolicited broadcasts, which arrive on the same
8
+ * notifications as command replies. Each `VehicleStatus` leaf has a typed
9
+ * `listen_*`, and `listen_broadcast` takes every raw broadcast on a domain,
10
+ * including payloads with no typed listener.
11
+ *
12
+ * The scalar listeners fire on every status broadcast with whatever value it
13
+ * holds, because proto3 has no presence on them, so a lock-only broadcast also
14
+ * reports `GEAR_UNKNOWN`. The closure listeners fire only when the broadcast
15
+ * carries the block they read.
16
+ */
17
+ export declare abstract class BroadcastListeners extends Commands {
18
+ private readonly statusListeners;
19
+ private readonly domainListeners;
20
+ protected log(message: string): void;
21
+ /** Hand one unaddressed message to everything listening. */
22
+ protected dispatchBroadcast(domain: Domain, message: RoutableMessage): void;
23
+ private listenClosure;
24
+ /** Listen for every unsolicited broadcast on `domain`, including `VehicleStatus`. */
25
+ listen_broadcast(domain: Domain, callback: (message: RoutableMessage) => void): Unsubscribe;
26
+ /** Listen for the vehicle's overall lock state. */
27
+ listen_vehicle_lock_state(callback: (state: VehicleLockStateE) => void): Unsubscribe;
28
+ /** Listen for the vehicle's sleep status. */
29
+ listen_vehicle_sleep_status(callback: (status: VehicleSleepStatusE) => void): Unsubscribe;
30
+ /** Listen for driver presence. */
31
+ listen_user_presence(callback: (presence: UserPresenceE) => void): Unsubscribe;
32
+ /** Listen for the gear selection. */
33
+ listen_gear(callback: (gear: GearE) => void): Unsubscribe;
34
+ /** Listen for the UI desire state. */
35
+ listen_ui_desire(callback: (desire: UIDesireE) => void): Unsubscribe;
36
+ /** Listen for the tonneau's open percentage, on broadcasts that carry it. */
37
+ listen_tonneau_percent_open(callback: (percent: number) => void): Unsubscribe;
38
+ /**
39
+ * Listen for a broadcast's whole closure block in one call. The listeners
40
+ * below each fire separately for the same broadcast.
41
+ */
42
+ listen_closure_statuses(callback: (closures: ClosureStatuses) => void): Unsubscribe;
43
+ /** Listen for the front driver door. */
44
+ listen_front_driver_door(callback: (state: ClosureStateE) => void): Unsubscribe;
45
+ /** Listen for the front passenger door. */
46
+ listen_front_passenger_door(callback: (state: ClosureStateE) => void): Unsubscribe;
47
+ /** Listen for the rear driver door. */
48
+ listen_rear_driver_door(callback: (state: ClosureStateE) => void): Unsubscribe;
49
+ /** Listen for the rear passenger door. */
50
+ listen_rear_passenger_door(callback: (state: ClosureStateE) => void): Unsubscribe;
51
+ /** Listen for the front trunk. */
52
+ listen_front_trunk(callback: (state: ClosureStateE) => void): Unsubscribe;
53
+ /** Listen for the rear trunk. */
54
+ listen_rear_trunk(callback: (state: ClosureStateE) => void): Unsubscribe;
55
+ /** Listen for the charge port. */
56
+ listen_charge_port(callback: (state: ClosureStateE) => void): Unsubscribe;
57
+ /** Listen for the tonneau. */
58
+ listen_tonneau(callback: (state: ClosureStateE) => void): Unsubscribe;
59
+ }
@@ -0,0 +1,59 @@
1
+ import Commands from "../commands.mjs";
2
+ import { Domain, RoutableMessage } from "@teslemetry/tesla-protocol/command/universal_message";
3
+ import { ClosureStateE, ClosureStatuses, GearE, UIDesireE, UserPresenceE, VehicleLockStateE, VehicleSleepStatusE, VehicleStatus } from "@teslemetry/tesla-protocol/command/vcsec";
4
+ /** Removes a listener. Safe to call twice. */
5
+ export type Unsubscribe = () => void;
6
+ /**
7
+ * Persistent listeners for unsolicited broadcasts, which arrive on the same
8
+ * notifications as command replies. Each `VehicleStatus` leaf has a typed
9
+ * `listen_*`, and `listen_broadcast` takes every raw broadcast on a domain,
10
+ * including payloads with no typed listener.
11
+ *
12
+ * The scalar listeners fire on every status broadcast with whatever value it
13
+ * holds, because proto3 has no presence on them, so a lock-only broadcast also
14
+ * reports `GEAR_UNKNOWN`. The closure listeners fire only when the broadcast
15
+ * carries the block they read.
16
+ */
17
+ export declare abstract class BroadcastListeners extends Commands {
18
+ private readonly statusListeners;
19
+ private readonly domainListeners;
20
+ protected log(message: string): void;
21
+ /** Hand one unaddressed message to everything listening. */
22
+ protected dispatchBroadcast(domain: Domain, message: RoutableMessage): void;
23
+ private listenClosure;
24
+ /** Listen for every unsolicited broadcast on `domain`, including `VehicleStatus`. */
25
+ listen_broadcast(domain: Domain, callback: (message: RoutableMessage) => void): Unsubscribe;
26
+ /** Listen for the vehicle's overall lock state. */
27
+ listen_vehicle_lock_state(callback: (state: VehicleLockStateE) => void): Unsubscribe;
28
+ /** Listen for the vehicle's sleep status. */
29
+ listen_vehicle_sleep_status(callback: (status: VehicleSleepStatusE) => void): Unsubscribe;
30
+ /** Listen for driver presence. */
31
+ listen_user_presence(callback: (presence: UserPresenceE) => void): Unsubscribe;
32
+ /** Listen for the gear selection. */
33
+ listen_gear(callback: (gear: GearE) => void): Unsubscribe;
34
+ /** Listen for the UI desire state. */
35
+ listen_ui_desire(callback: (desire: UIDesireE) => void): Unsubscribe;
36
+ /** Listen for the tonneau's open percentage, on broadcasts that carry it. */
37
+ listen_tonneau_percent_open(callback: (percent: number) => void): Unsubscribe;
38
+ /**
39
+ * Listen for a broadcast's whole closure block in one call. The listeners
40
+ * below each fire separately for the same broadcast.
41
+ */
42
+ listen_closure_statuses(callback: (closures: ClosureStatuses) => void): Unsubscribe;
43
+ /** Listen for the front driver door. */
44
+ listen_front_driver_door(callback: (state: ClosureStateE) => void): Unsubscribe;
45
+ /** Listen for the front passenger door. */
46
+ listen_front_passenger_door(callback: (state: ClosureStateE) => void): Unsubscribe;
47
+ /** Listen for the rear driver door. */
48
+ listen_rear_driver_door(callback: (state: ClosureStateE) => void): Unsubscribe;
49
+ /** Listen for the rear passenger door. */
50
+ listen_rear_passenger_door(callback: (state: ClosureStateE) => void): Unsubscribe;
51
+ /** Listen for the front trunk. */
52
+ listen_front_trunk(callback: (state: ClosureStateE) => void): Unsubscribe;
53
+ /** Listen for the rear trunk. */
54
+ listen_rear_trunk(callback: (state: ClosureStateE) => void): Unsubscribe;
55
+ /** Listen for the charge port. */
56
+ listen_charge_port(callback: (state: ClosureStateE) => void): Unsubscribe;
57
+ /** Listen for the tonneau. */
58
+ listen_tonneau(callback: (state: ClosureStateE) => void): Unsubscribe;
59
+ }
@@ -0,0 +1,151 @@
1
+ import Commands from "../commands.mjs";
2
+ import { Domain } from "@teslemetry/tesla-protocol/command/universal_message";
3
+ import { FromVCSECMessage } from "@teslemetry/tesla-protocol/command/vcsec";
4
+ // src/bluetooth/broadcast.ts
5
+ /**
6
+ * Local callbacks, not tied to a connection, so they live as long as the
7
+ * vehicle and survive reconnects. A callback that throws is logged, and neither
8
+ * later callbacks nor message routing see it.
9
+ */
10
+ var ListenerRegistry = class {
11
+ log;
12
+ entries = [];
13
+ constructor(log) {
14
+ this.log = log;
15
+ }
16
+ get size() {
17
+ return this.entries.length;
18
+ }
19
+ add(callback) {
20
+ const entry = { callback };
21
+ this.entries.push(entry);
22
+ return () => {
23
+ this.entries = this.entries.filter((other) => other !== entry);
24
+ };
25
+ }
26
+ emit(value) {
27
+ for (const { callback } of this.entries) try {
28
+ callback(value);
29
+ } catch (error) {
30
+ this.log(`BLE listener failed: ${error instanceof Error ? `${error.name}: ${error.message}` : String(error)}`);
31
+ }
32
+ }
33
+ };
34
+ /**
35
+ * A broadcast's VCSEC status, if it carries one. Broadcasts are unsigned, so
36
+ * they need no session and prove nothing about who sent them.
37
+ */
38
+ function decodeVcsecStatus(message) {
39
+ if (message.protobufMessageAsBytes === void 0) return null;
40
+ try {
41
+ return FromVCSECMessage.decode(message.protobufMessageAsBytes).vehicleStatus ?? null;
42
+ } catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * Persistent listeners for unsolicited broadcasts, which arrive on the same
48
+ * notifications as command replies. Each `VehicleStatus` leaf has a typed
49
+ * `listen_*`, and `listen_broadcast` takes every raw broadcast on a domain,
50
+ * including payloads with no typed listener.
51
+ *
52
+ * The scalar listeners fire on every status broadcast with whatever value it
53
+ * holds, because proto3 has no presence on them, so a lock-only broadcast also
54
+ * reports `GEAR_UNKNOWN`. The closure listeners fire only when the broadcast
55
+ * carries the block they read.
56
+ */
57
+ var BroadcastListeners = class extends Commands {
58
+ statusListeners = new ListenerRegistry((message) => this.log(message));
59
+ domainListeners = /* @__PURE__ */ new Map();
60
+ log(message) {
61
+ this.parent.parent._log(message);
62
+ }
63
+ /** Hand one unaddressed message to everything listening. */
64
+ dispatchBroadcast(domain, message) {
65
+ this.domainListeners.get(domain)?.emit(message);
66
+ if (domain === Domain.DOMAIN_VEHICLE_SECURITY && this.statusListeners.size > 0) {
67
+ const status = decodeVcsecStatus(message);
68
+ if (status) this.statusListeners.emit(status);
69
+ }
70
+ }
71
+ listenClosure(callback) {
72
+ return this.statusListeners.add((status) => {
73
+ if (status.closureStatuses) callback(status.closureStatuses);
74
+ });
75
+ }
76
+ /** Listen for every unsolicited broadcast on `domain`, including `VehicleStatus`. */
77
+ listen_broadcast(domain, callback) {
78
+ let registry = this.domainListeners.get(domain);
79
+ if (!registry) {
80
+ registry = new ListenerRegistry((message) => this.log(message));
81
+ this.domainListeners.set(domain, registry);
82
+ }
83
+ return registry.add(callback);
84
+ }
85
+ /** Listen for the vehicle's overall lock state. */
86
+ listen_vehicle_lock_state(callback) {
87
+ return this.statusListeners.add((status) => callback(status.vehicleLockState));
88
+ }
89
+ /** Listen for the vehicle's sleep status. */
90
+ listen_vehicle_sleep_status(callback) {
91
+ return this.statusListeners.add((status) => callback(status.vehicleSleepStatus));
92
+ }
93
+ /** Listen for driver presence. */
94
+ listen_user_presence(callback) {
95
+ return this.statusListeners.add((status) => callback(status.userPresence));
96
+ }
97
+ /** Listen for the gear selection. */
98
+ listen_gear(callback) {
99
+ return this.statusListeners.add((status) => callback(status.gear));
100
+ }
101
+ /** Listen for the UI desire state. */
102
+ listen_ui_desire(callback) {
103
+ return this.statusListeners.add((status) => callback(status.UIDesire));
104
+ }
105
+ /** Listen for the tonneau's open percentage, on broadcasts that carry it. */
106
+ listen_tonneau_percent_open(callback) {
107
+ return this.statusListeners.add((status) => {
108
+ if (status.detailedClosureStatus) callback(status.detailedClosureStatus.tonneauPercentOpen);
109
+ });
110
+ }
111
+ /**
112
+ * Listen for a broadcast's whole closure block in one call. The listeners
113
+ * below each fire separately for the same broadcast.
114
+ */
115
+ listen_closure_statuses(callback) {
116
+ return this.listenClosure(callback);
117
+ }
118
+ /** Listen for the front driver door. */
119
+ listen_front_driver_door(callback) {
120
+ return this.listenClosure((closures) => callback(closures.frontDriverDoor));
121
+ }
122
+ /** Listen for the front passenger door. */
123
+ listen_front_passenger_door(callback) {
124
+ return this.listenClosure((closures) => callback(closures.frontPassengerDoor));
125
+ }
126
+ /** Listen for the rear driver door. */
127
+ listen_rear_driver_door(callback) {
128
+ return this.listenClosure((closures) => callback(closures.rearDriverDoor));
129
+ }
130
+ /** Listen for the rear passenger door. */
131
+ listen_rear_passenger_door(callback) {
132
+ return this.listenClosure((closures) => callback(closures.rearPassengerDoor));
133
+ }
134
+ /** Listen for the front trunk. */
135
+ listen_front_trunk(callback) {
136
+ return this.listenClosure((closures) => callback(closures.frontTrunk));
137
+ }
138
+ /** Listen for the rear trunk. */
139
+ listen_rear_trunk(callback) {
140
+ return this.listenClosure((closures) => callback(closures.rearTrunk));
141
+ }
142
+ /** Listen for the charge port. */
143
+ listen_charge_port(callback) {
144
+ return this.listenClosure((closures) => callback(closures.chargePort));
145
+ }
146
+ /** Listen for the tonneau. */
147
+ listen_tonneau(callback) {
148
+ return this.listenClosure((closures) => callback(closures.tonneau));
149
+ }
150
+ };
151
+ export { BroadcastListeners, ListenerRegistry, decodeVcsecStatus };
@@ -0,0 +1,99 @@
1
+ // src/bluetooth/constants.ts
2
+ /** The vehicle's GATT service. It is never advertised, so never scan for it. */
3
+ const SERVICE_UUID = "00000211-b2d1-43f0-9b88-960cebf8b91e";
4
+ /** Client to car. Tesla's Go SDK names the two by the opposite view, hence these names. */
5
+ const VEHICLE_WRITE_UUID = "00000212-b2d1-43f0-9b88-960cebf8b91e";
6
+ /** Car to client. */
7
+ const VEHICLE_NOTIFY_UUID = "00000213-b2d1-43f0-9b88-960cebf8b91e";
8
+ /** Python's name for `VEHICLE_WRITE_UUID`. */
9
+ const WRITE_UUID = VEHICLE_WRITE_UUID;
10
+ /** Python's name for `VEHICLE_NOTIFY_UUID`. */
11
+ const READ_UUID = VEHICLE_NOTIFY_UUID;
12
+ /** The keepalive read target. */
13
+ const VERSION_UUID = "00000214-b2d1-43f0-9b88-960cebf8b91e";
14
+ /** GATT Device Name. */
15
+ const NAME_UUID = "00002a00-0000-1000-8000-00805f9b34fb";
16
+ /** GATT Appearance. */
17
+ const APPEARANCE_UUID = "00002a01-0000-1000-8000-00805f9b34fb";
18
+ /** Generic Access, for a backend that needs a service UUID to reach the two above. */
19
+ const GENERIC_ACCESS_UUID = "00001800-0000-1000-8000-00805f9b34fb";
20
+ /** Client Characteristic Configuration. Only an ESPHome proxy needs it written by hand. */
21
+ const CCCD_UUID = "00002902-0000-1000-8000-00805f9b34fb";
22
+ /** Largest frame accepted, length prefix included. Tesla's Go SDK allows 2 more bytes. */
23
+ const MAX_FRAME_SIZE = 1024;
24
+ /**
25
+ * Bytes per write when a connection does not say: the ATT default MTU of 23,
26
+ * less 3 of header. Safe on any link, and all Homey offers, as it hides the MTU.
27
+ */
28
+ const DEFAULT_MAX_WRITE_SIZE = 20;
29
+ /** A chunk after this much silence means the partial frame before it was abandoned. */
30
+ const STALE_CHUNK_TIMEOUT_MS = 1e3;
31
+ /** An idle held link drops at about 42 s on average; a read this often keeps it about 10 times longer. */
32
+ const DEFAULT_KEEPALIVE_INTERVAL_MS = 2e4;
33
+ /** Infotainment answers a handshake 4 to 16 s after an RKE wake. */
34
+ const DEFAULT_WAKE_TIMEOUT_MS = 3e4;
35
+ /**
36
+ * One infotainment readiness probe. A ready infotainment answers in 0.26 to 0.39 s.
37
+ * The window opens once the request is fully written, so a slow 20-byte link
38
+ * spends none of it writing. Raise it with `wake_probe_timeout_ms` if a link's
39
+ * replies are slower than this, as a probe that keeps timing out never proves
40
+ * the car is ready.
41
+ */
42
+ const DEFAULT_WAKE_PROBE_TIMEOUT_MS = 1e3;
43
+ /** How often a wake is resent while infotainment stays silent: a first wake can be missed after a long sleep. */
44
+ const WAKE_RESEND_INTERVAL_MS = 3e3;
45
+ /** How long an awake car's infotainment may take to finish booting. */
46
+ const INFOTAINMENT_BOOT_TIMEOUT_MS = 2e4;
47
+ /** How long a charge-port opening has to show in charge state. It took about 1.4 s in live trials. */
48
+ const CHARGE_PORT_VERIFY_TIMEOUT_MS = 5e3;
49
+ /** Between charge-state polls, while waiting for readiness or for the latch. */
50
+ const CHARGE_PORT_VERIFY_INTERVAL_MS = 250;
51
+ /** How long `pair` waits for someone to tap a key card. */
52
+ const DEFAULT_PAIR_TIMEOUT_MS = 3e5;
53
+ /** Between `pair`'s checks of whether the key was accepted. */
54
+ const DEFAULT_PAIR_POLL_INTERVAL_MS = 5e3;
55
+ /** Connect attempts. Each is bounded by `DEFAULT_CONNECT_TIMEOUT_MS`. */
56
+ const DEFAULT_CONNECT_ATTEMPTS = 3;
57
+ /** One connect attempt. Python takes the same figure from `bleak-retry-connector`. */
58
+ const DEFAULT_CONNECT_TIMEOUT_MS = 2e4;
59
+ /** One scan. It must outlast the backend's window, which Homey fixes at about 5 s. */
60
+ const DEFAULT_SCAN_TIMEOUT_MS = 1e4;
61
+ /** Bound on tearing down a link: the failure behind it is what gets reported. */
62
+ const LINK_TEARDOWN_TIMEOUT_MS = 5e3;
63
+ /**
64
+ * One write call. Not in Python, whose backends bound their own writes. Homey's
65
+ * have no timeout and its link state can be stale, so a hung write must end
66
+ * here. A design choice. BLE-00 step 10 measures how long a failing write takes
67
+ * on Homey, which sets it.
68
+ */
69
+ const GATT_WRITE_TIMEOUT_MS = 5e3;
70
+ /** One read call, other than a keepalive's. */
71
+ const GATT_READ_TIMEOUT_MS = 5e3;
72
+ exports.APPEARANCE_UUID = APPEARANCE_UUID;
73
+ exports.CCCD_UUID = CCCD_UUID;
74
+ exports.CHARGE_PORT_VERIFY_INTERVAL_MS = CHARGE_PORT_VERIFY_INTERVAL_MS;
75
+ exports.CHARGE_PORT_VERIFY_TIMEOUT_MS = CHARGE_PORT_VERIFY_TIMEOUT_MS;
76
+ exports.DEFAULT_CONNECT_ATTEMPTS = DEFAULT_CONNECT_ATTEMPTS;
77
+ exports.DEFAULT_CONNECT_TIMEOUT_MS = DEFAULT_CONNECT_TIMEOUT_MS;
78
+ exports.DEFAULT_KEEPALIVE_INTERVAL_MS = DEFAULT_KEEPALIVE_INTERVAL_MS;
79
+ exports.DEFAULT_MAX_WRITE_SIZE = DEFAULT_MAX_WRITE_SIZE;
80
+ exports.DEFAULT_PAIR_POLL_INTERVAL_MS = DEFAULT_PAIR_POLL_INTERVAL_MS;
81
+ exports.DEFAULT_PAIR_TIMEOUT_MS = DEFAULT_PAIR_TIMEOUT_MS;
82
+ exports.DEFAULT_SCAN_TIMEOUT_MS = DEFAULT_SCAN_TIMEOUT_MS;
83
+ exports.DEFAULT_WAKE_PROBE_TIMEOUT_MS = DEFAULT_WAKE_PROBE_TIMEOUT_MS;
84
+ exports.DEFAULT_WAKE_TIMEOUT_MS = DEFAULT_WAKE_TIMEOUT_MS;
85
+ exports.GATT_READ_TIMEOUT_MS = GATT_READ_TIMEOUT_MS;
86
+ exports.GATT_WRITE_TIMEOUT_MS = GATT_WRITE_TIMEOUT_MS;
87
+ exports.GENERIC_ACCESS_UUID = GENERIC_ACCESS_UUID;
88
+ exports.INFOTAINMENT_BOOT_TIMEOUT_MS = INFOTAINMENT_BOOT_TIMEOUT_MS;
89
+ exports.LINK_TEARDOWN_TIMEOUT_MS = LINK_TEARDOWN_TIMEOUT_MS;
90
+ exports.MAX_FRAME_SIZE = MAX_FRAME_SIZE;
91
+ exports.NAME_UUID = NAME_UUID;
92
+ exports.READ_UUID = READ_UUID;
93
+ exports.SERVICE_UUID = SERVICE_UUID;
94
+ exports.STALE_CHUNK_TIMEOUT_MS = STALE_CHUNK_TIMEOUT_MS;
95
+ exports.VEHICLE_NOTIFY_UUID = VEHICLE_NOTIFY_UUID;
96
+ exports.VEHICLE_WRITE_UUID = VEHICLE_WRITE_UUID;
97
+ exports.VERSION_UUID = VERSION_UUID;
98
+ exports.WAKE_RESEND_INTERVAL_MS = WAKE_RESEND_INTERVAL_MS;
99
+ exports.WRITE_UUID = WRITE_UUID;
@@ -0,0 +1,70 @@
1
+ /** The vehicle's GATT service. It is never advertised, so never scan for it. */
2
+ export declare const SERVICE_UUID = "00000211-b2d1-43f0-9b88-960cebf8b91e";
3
+ /** Client to car. Tesla's Go SDK names the two by the opposite view, hence these names. */
4
+ export declare const VEHICLE_WRITE_UUID = "00000212-b2d1-43f0-9b88-960cebf8b91e";
5
+ /** Car to client. */
6
+ export declare const VEHICLE_NOTIFY_UUID = "00000213-b2d1-43f0-9b88-960cebf8b91e";
7
+ /** Python's name for `VEHICLE_WRITE_UUID`. */
8
+ export declare const WRITE_UUID = "00000212-b2d1-43f0-9b88-960cebf8b91e";
9
+ /** Python's name for `VEHICLE_NOTIFY_UUID`. */
10
+ export declare const READ_UUID = "00000213-b2d1-43f0-9b88-960cebf8b91e";
11
+ /** The keepalive read target. */
12
+ export declare const VERSION_UUID = "00000214-b2d1-43f0-9b88-960cebf8b91e";
13
+ /** GATT Device Name. */
14
+ export declare const NAME_UUID = "00002a00-0000-1000-8000-00805f9b34fb";
15
+ /** GATT Appearance. */
16
+ export declare const APPEARANCE_UUID = "00002a01-0000-1000-8000-00805f9b34fb";
17
+ /** Generic Access, for a backend that needs a service UUID to reach the two above. */
18
+ export declare const GENERIC_ACCESS_UUID = "00001800-0000-1000-8000-00805f9b34fb";
19
+ /** Client Characteristic Configuration. Only an ESPHome proxy needs it written by hand. */
20
+ export declare const CCCD_UUID = "00002902-0000-1000-8000-00805f9b34fb";
21
+ /** Largest frame accepted, length prefix included. Tesla's Go SDK allows 2 more bytes. */
22
+ export declare const MAX_FRAME_SIZE = 1024;
23
+ /**
24
+ * Bytes per write when a connection does not say: the ATT default MTU of 23,
25
+ * less 3 of header. Safe on any link, and all Homey offers, as it hides the MTU.
26
+ */
27
+ export declare const DEFAULT_MAX_WRITE_SIZE = 20;
28
+ /** A chunk after this much silence means the partial frame before it was abandoned. */
29
+ export declare const STALE_CHUNK_TIMEOUT_MS = 1000;
30
+ /** An idle held link drops at about 42 s on average; a read this often keeps it about 10 times longer. */
31
+ export declare const DEFAULT_KEEPALIVE_INTERVAL_MS = 20000;
32
+ /** Infotainment answers a handshake 4 to 16 s after an RKE wake. */
33
+ export declare const DEFAULT_WAKE_TIMEOUT_MS = 30000;
34
+ /**
35
+ * One infotainment readiness probe. A ready infotainment answers in 0.26 to 0.39 s.
36
+ * The window opens once the request is fully written, so a slow 20-byte link
37
+ * spends none of it writing. Raise it with `wake_probe_timeout_ms` if a link's
38
+ * replies are slower than this, as a probe that keeps timing out never proves
39
+ * the car is ready.
40
+ */
41
+ export declare const DEFAULT_WAKE_PROBE_TIMEOUT_MS = 1000;
42
+ /** How often a wake is resent while infotainment stays silent: a first wake can be missed after a long sleep. */
43
+ export declare const WAKE_RESEND_INTERVAL_MS = 3000;
44
+ /** How long an awake car's infotainment may take to finish booting. */
45
+ export declare const INFOTAINMENT_BOOT_TIMEOUT_MS = 20000;
46
+ /** How long a charge-port opening has to show in charge state. It took about 1.4 s in live trials. */
47
+ export declare const CHARGE_PORT_VERIFY_TIMEOUT_MS = 5000;
48
+ /** Between charge-state polls, while waiting for readiness or for the latch. */
49
+ export declare const CHARGE_PORT_VERIFY_INTERVAL_MS = 250;
50
+ /** How long `pair` waits for someone to tap a key card. */
51
+ export declare const DEFAULT_PAIR_TIMEOUT_MS = 300000;
52
+ /** Between `pair`'s checks of whether the key was accepted. */
53
+ export declare const DEFAULT_PAIR_POLL_INTERVAL_MS = 5000;
54
+ /** Connect attempts. Each is bounded by `DEFAULT_CONNECT_TIMEOUT_MS`. */
55
+ export declare const DEFAULT_CONNECT_ATTEMPTS = 3;
56
+ /** One connect attempt. Python takes the same figure from `bleak-retry-connector`. */
57
+ export declare const DEFAULT_CONNECT_TIMEOUT_MS = 20000;
58
+ /** One scan. It must outlast the backend's window, which Homey fixes at about 5 s. */
59
+ export declare const DEFAULT_SCAN_TIMEOUT_MS = 10000;
60
+ /** Bound on tearing down a link: the failure behind it is what gets reported. */
61
+ export declare const LINK_TEARDOWN_TIMEOUT_MS = 5000;
62
+ /**
63
+ * One write call. Not in Python, whose backends bound their own writes. Homey's
64
+ * have no timeout and its link state can be stale, so a hung write must end
65
+ * here. A design choice. BLE-00 step 10 measures how long a failing write takes
66
+ * on Homey, which sets it.
67
+ */
68
+ export declare const GATT_WRITE_TIMEOUT_MS = 5000;
69
+ /** One read call, other than a keepalive's. */
70
+ export declare const GATT_READ_TIMEOUT_MS = 5000;
@@ -0,0 +1,70 @@
1
+ /** The vehicle's GATT service. It is never advertised, so never scan for it. */
2
+ export declare const SERVICE_UUID = "00000211-b2d1-43f0-9b88-960cebf8b91e";
3
+ /** Client to car. Tesla's Go SDK names the two by the opposite view, hence these names. */
4
+ export declare const VEHICLE_WRITE_UUID = "00000212-b2d1-43f0-9b88-960cebf8b91e";
5
+ /** Car to client. */
6
+ export declare const VEHICLE_NOTIFY_UUID = "00000213-b2d1-43f0-9b88-960cebf8b91e";
7
+ /** Python's name for `VEHICLE_WRITE_UUID`. */
8
+ export declare const WRITE_UUID = "00000212-b2d1-43f0-9b88-960cebf8b91e";
9
+ /** Python's name for `VEHICLE_NOTIFY_UUID`. */
10
+ export declare const READ_UUID = "00000213-b2d1-43f0-9b88-960cebf8b91e";
11
+ /** The keepalive read target. */
12
+ export declare const VERSION_UUID = "00000214-b2d1-43f0-9b88-960cebf8b91e";
13
+ /** GATT Device Name. */
14
+ export declare const NAME_UUID = "00002a00-0000-1000-8000-00805f9b34fb";
15
+ /** GATT Appearance. */
16
+ export declare const APPEARANCE_UUID = "00002a01-0000-1000-8000-00805f9b34fb";
17
+ /** Generic Access, for a backend that needs a service UUID to reach the two above. */
18
+ export declare const GENERIC_ACCESS_UUID = "00001800-0000-1000-8000-00805f9b34fb";
19
+ /** Client Characteristic Configuration. Only an ESPHome proxy needs it written by hand. */
20
+ export declare const CCCD_UUID = "00002902-0000-1000-8000-00805f9b34fb";
21
+ /** Largest frame accepted, length prefix included. Tesla's Go SDK allows 2 more bytes. */
22
+ export declare const MAX_FRAME_SIZE = 1024;
23
+ /**
24
+ * Bytes per write when a connection does not say: the ATT default MTU of 23,
25
+ * less 3 of header. Safe on any link, and all Homey offers, as it hides the MTU.
26
+ */
27
+ export declare const DEFAULT_MAX_WRITE_SIZE = 20;
28
+ /** A chunk after this much silence means the partial frame before it was abandoned. */
29
+ export declare const STALE_CHUNK_TIMEOUT_MS = 1000;
30
+ /** An idle held link drops at about 42 s on average; a read this often keeps it about 10 times longer. */
31
+ export declare const DEFAULT_KEEPALIVE_INTERVAL_MS = 20000;
32
+ /** Infotainment answers a handshake 4 to 16 s after an RKE wake. */
33
+ export declare const DEFAULT_WAKE_TIMEOUT_MS = 30000;
34
+ /**
35
+ * One infotainment readiness probe. A ready infotainment answers in 0.26 to 0.39 s.
36
+ * The window opens once the request is fully written, so a slow 20-byte link
37
+ * spends none of it writing. Raise it with `wake_probe_timeout_ms` if a link's
38
+ * replies are slower than this, as a probe that keeps timing out never proves
39
+ * the car is ready.
40
+ */
41
+ export declare const DEFAULT_WAKE_PROBE_TIMEOUT_MS = 1000;
42
+ /** How often a wake is resent while infotainment stays silent: a first wake can be missed after a long sleep. */
43
+ export declare const WAKE_RESEND_INTERVAL_MS = 3000;
44
+ /** How long an awake car's infotainment may take to finish booting. */
45
+ export declare const INFOTAINMENT_BOOT_TIMEOUT_MS = 20000;
46
+ /** How long a charge-port opening has to show in charge state. It took about 1.4 s in live trials. */
47
+ export declare const CHARGE_PORT_VERIFY_TIMEOUT_MS = 5000;
48
+ /** Between charge-state polls, while waiting for readiness or for the latch. */
49
+ export declare const CHARGE_PORT_VERIFY_INTERVAL_MS = 250;
50
+ /** How long `pair` waits for someone to tap a key card. */
51
+ export declare const DEFAULT_PAIR_TIMEOUT_MS = 300000;
52
+ /** Between `pair`'s checks of whether the key was accepted. */
53
+ export declare const DEFAULT_PAIR_POLL_INTERVAL_MS = 5000;
54
+ /** Connect attempts. Each is bounded by `DEFAULT_CONNECT_TIMEOUT_MS`. */
55
+ export declare const DEFAULT_CONNECT_ATTEMPTS = 3;
56
+ /** One connect attempt. Python takes the same figure from `bleak-retry-connector`. */
57
+ export declare const DEFAULT_CONNECT_TIMEOUT_MS = 20000;
58
+ /** One scan. It must outlast the backend's window, which Homey fixes at about 5 s. */
59
+ export declare const DEFAULT_SCAN_TIMEOUT_MS = 10000;
60
+ /** Bound on tearing down a link: the failure behind it is what gets reported. */
61
+ export declare const LINK_TEARDOWN_TIMEOUT_MS = 5000;
62
+ /**
63
+ * One write call. Not in Python, whose backends bound their own writes. Homey's
64
+ * have no timeout and its link state can be stale, so a hung write must end
65
+ * here. A design choice. BLE-00 step 10 measures how long a failing write takes
66
+ * on Homey, which sets it.
67
+ */
68
+ export declare const GATT_WRITE_TIMEOUT_MS = 5000;
69
+ /** One read call, other than a keepalive's. */
70
+ export declare const GATT_READ_TIMEOUT_MS = 5000;