bt-sensors-plugin-sk 1.3.2 → 1.3.4-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/BTSensor.js CHANGED
@@ -3,7 +3,7 @@ const { log } = require('node:console');
3
3
  const EventEmitter = require('node:events');
4
4
  const AutoQueue = require("./Queue.js")
5
5
  const DistanceManager = require("./DistanceManager")
6
-
6
+ const OutOfRangeDevice = require("./OutOfRangeDevice.js")
7
7
  /**
8
8
  * @author Andrew Gerngross <oh.that.andy@gmail.com>
9
9
  */
@@ -278,7 +278,7 @@ class BTSensor extends EventEmitter {
278
278
 
279
279
  unsetError(){
280
280
  this._error=false
281
- this.emit("error", false)
281
+ this.emit("errorDetected", false)
282
282
  }
283
283
 
284
284
  setError(message){
@@ -292,7 +292,7 @@ class BTSensor extends EventEmitter {
292
292
 
293
293
  this._errorLog.push({timestamp:Date.now(), message:message})
294
294
  this._error=true
295
- this.emit("error", true)
295
+ this.emit("errorDetected", true)
296
296
  }
297
297
 
298
298
  //Instance Initialization functions
@@ -365,7 +365,10 @@ class BTSensor extends EventEmitter {
365
365
  await this.initSchema()
366
366
 
367
367
  this.initListen()
368
- this.setState("DORMANT")
368
+ if ( this.device instanceof OutOfRangeDevice)
369
+ this.setState("OUT OF RANGE")
370
+ else
371
+ this.setState("DORMANT")
369
372
 
370
373
  }
371
374
 
@@ -1059,11 +1062,11 @@ class BTSensor extends EventEmitter {
1059
1062
  if (!(path === undefined)) {
1060
1063
  let preparedPath = this.preparePath(path)
1061
1064
  this.on(tag, (val)=>{
1062
- if (pathMeta.notify){
1065
+ /* if (pathMeta.notify){
1063
1066
  this._app.notify(tag, val, id )
1064
- } else {
1067
+ } else {*/
1065
1068
  this.updatePath(preparedPath,val, id, source)
1066
- }
1069
+ //}
1067
1070
  })
1068
1071
  }
1069
1072
  })
package/README.md CHANGED
@@ -1,6 +1,23 @@
1
1
  # Bluetooth Sensors for [Signal K](http://www.signalk.org)
2
2
 
3
3
  ## WHAT'S NEW
4
+
5
+
6
+ # Version 1.3.4 - beta
7
+
8
+ - Experimental inactivity timeout with Bluetooth recycle
9
+
10
+ # Version 1.3.3
11
+
12
+ - Support for additional Xiaomi environmental sensors
13
+ - Out Of Range device automatic retry
14
+ - Pairing guide
15
+
16
+ # Version 1.3.2-1
17
+
18
+ - VictronSmartBatteryProtect fix
19
+ - RenogyRoverClient deviceID clarity
20
+
4
21
  # Version 1.3.2
5
22
 
6
23
  - Victron Alarm Reason improvements
package/index.js CHANGED
@@ -178,6 +178,11 @@ module.exports = function (app) {
178
178
  minimum: 10,
179
179
  maximum: 3600
180
180
  },
181
+ inactivityTimeout: {title: "Inactivity timeout (in seconds). If no contact with any sensors for this period, the Bluetooth adapter will be recycled.",
182
+ type: "integer", default: 60,
183
+ minimum: 0,
184
+ maximum: 3600
185
+ },
181
186
  discoveryInterval: {title: "Scan for new devices interval (in seconds-- 0 for no new device scanning)",
182
187
  type: "integer",
183
188
  default: 10,
@@ -203,6 +208,8 @@ module.exports = function (app) {
203
208
  plugin.started=true
204
209
  var adapterID=options.adapter
205
210
  var foundConfiguredDevices=0
211
+ var lastContactDelta=Infinity
212
+
206
213
 
207
214
  if (Object.keys(options).length==0){ //empty config means initial startup. save defaults and enabled=true.
208
215
  let json = {configuration:{adapter:"hci0", transport:"le", discoveryTimeout:30, discoveryInterval:10}, enabled:true, enableDebug:false}
@@ -445,7 +452,7 @@ module.exports = function (app) {
445
452
  sensor.on("connected", (state)=>{
446
453
  updateSensor(sensor)
447
454
  })
448
- sensor.on("error",(error)=>{
455
+ sensor.on("errorDetected",(error)=>{
449
456
  updateSensor(sensor)
450
457
  })
451
458
  sensor.on("debug", ()=>{
@@ -492,19 +499,21 @@ module.exports = function (app) {
492
499
  s.stopListening()
493
500
  else{
494
501
  const device = new OutOfRangeDevice(adapter, config)
495
- const c = await getClassFor(device,config)
496
- if (c.domain==BTSensor.SensorDomains.beacons || c.IsRoaming){
497
- s = await instantiateSensor(device,config)
498
- device.once("deviceFound",async (device)=>{
499
- s.device=device
500
- s.listen()
501
- await s.activate(config, plugin)
502
- removeSensorFromList(s)
503
- addSensorToList(s)
504
- })
502
+ s = await instantiateSensor(device,config)
503
+ device.once("deviceFound",async (device)=>{
504
+ s.device=device
505
+ s.listen()
506
+ if (config.active)
507
+ await s.activate(config, plugin)
508
+ else {
509
+ s.unsetError()
510
+ s.setState("DORMANT")
511
+ }
512
+ removeSensorFromList(s)
505
513
  addSensorToList(s)
506
- resolve(s)
507
- }
514
+ })
515
+ addSensorToList(s)
516
+ resolve(s)
508
517
  }
509
518
  if (startNumber == starts ) {
510
519
  const errorTxt = `Unable to communicate with device ${deviceNameAndAddress(config)} Reason: ${e?.message??e}`
@@ -755,15 +764,28 @@ module.exports = function (app) {
755
764
  }
756
765
  const minTimeout=Math.min(...deviceConfigs.map((dc)=>dc?.discoveryTimeout??options.discoveryTimeout))
757
766
  const intervalTimeout = ((minTimeout==Infinity)?(options?.discoveryTimeout??plugin.schema.properties.discoveryTimeout.default):minTimeout)*1000
758
- deviceHealthID = setInterval( ()=> {
767
+
768
+
769
+
770
+ deviceHealthID = setInterval( async ()=> {
759
771
  sensorMap.forEach((sensor)=>{
760
772
  const config = getDeviceConfig(sensor.getMacAddress())
761
773
  const dt = config?.discoveryTimeout??options.discoveryTimeout
762
774
  const lc=sensor.elapsedTimeSinceLastContact()
775
+ if (lc<lastContactDelta) //get min last contact delta
776
+ lastContactDelta=lc
763
777
  if (lc > dt) {
764
778
  updateSensor(sensor)
765
779
  }
766
780
  })
781
+ if (sensorMap.size && lastContactDelta > options.inactivityTimeout)
782
+ {
783
+
784
+ plugin.debug(`No contact with any sensors for ${lastContactDelta} seconds. Recycling Bluetooth adapter.`)
785
+ await adapter.setPowered(false)
786
+ await adapter.setPowered(true)
787
+ }
788
+
767
789
  }, intervalTimeout)
768
790
 
769
791
  if (!options.hasOwnProperty("discoveryInterval" )) //no config -- first run
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bt-sensors-plugin-sk",
3
- "version": "1.3.2",
3
+ "version": "1.3.4-beta",
4
4
  "description": "Bluetooth Sensors for Signalk - see https://www.npmjs.com/package/bt-sensors-plugin-sk#supported-sensors for a list of supported sensors",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -13,7 +13,7 @@
13
13
  "@jellybrick/dbus-next": "^0.10.3",
14
14
  "int24": "^0.0.1",
15
15
  "kaitai-struct": "^0.10.0",
16
- "@naugehyde/node-ble":"^1.13.4",
16
+ "@naugehyde/node-ble":"^1.13.5",
17
17
  "semver": "^7.7.1",
18
18
  "lru-cache": "^11.1.0"
19
19
  },
package/pairing.md ADDED
@@ -0,0 +1,147 @@
1
+ # Bluetooth Device Pairing using bluetoothctl
2
+
3
+ This guide provides a step-by-step procedure for pairing, trusting, and connecting a new Bluetooth device using the bluetoothctl command-line utility, which is the official Bluetooth client for BlueZ (the Linux Bluetooth stack).
4
+
5
+ ## Prerequisites
6
+
7
+ - A running Linux system (e.g., Debian, Ubuntu, Fedora, Arch).
8
+ - The bluez package installed (which includes bluetoothctl).
9
+ - The Bluetooth service (bluetooth.service) is running.
10
+ - Your local Bluetooth adapter is enabled and powered on.
11
+
12
+ ## The Pairing Process
13
+
14
+ Follow these steps within your terminal:
15
+
16
+ ### Step 1: Launch bluetoothctl
17
+
18
+ Open your terminal and run the command to enter the interactive bluetoothctl prompt.
19
+
20
+ ```
21
+
22
+ bluetoothctl
23
+
24
+ ```
25
+
26
+ (The prompt should change to [bluetooth]#)
27
+
28
+ ### Step 2: Check Controller Status (Optional but recommended)Ensure your adapter is powered on and set to discoverable/pairable mode.
29
+
30
+ ```
31
+
32
+ [bluetooth]# show
33
+
34
+ ```
35
+
36
+ If the Powered field is listed as no, power the adapter on:
37
+
38
+ ```
39
+
40
+ [bluetooth]# power on
41
+
42
+ ```
43
+
44
+ ### Step 3: Start Scanning for Devices
45
+
46
+ Put your target Bluetooth device into pairing mode (see device instructions). Then, start the scanning process:
47
+
48
+ ```
49
+
50
+ [bluetooth]# scan on
51
+
52
+ ```
53
+
54
+
55
+ You will see a list of discovered devices scrolling by with their MAC addresses and names.
56
+
57
+ ```
58
+ Discovery started
59
+ [CHG] Device 12:34:56:78:90:AB Name: My Bluetooth Headphones
60
+ [NEW] Device AB:CD:EF:12:34:56 Name: Wireless Mouse
61
+ ...
62
+ ```
63
+
64
+
65
+ ### Step 4: Identify and Stop Scanning
66
+
67
+ Once you see the name of your device, copy its MAC Address (e.g., AB:CD:EF:12:34:56) and stop the scan to save battery and reduce clutter:
68
+
69
+ ```
70
+
71
+ [bluetooth]# scan off
72
+
73
+ ```
74
+
75
+
76
+ Step 5: Trust the Device
77
+
78
+ Trusting the device is crucial. It allows the device to reconnect automatically after a reboot or disconnection without needing to re-pair. Replace [MAC_ADDRESS] with your device's MAC address.
79
+
80
+ ```
81
+
82
+ [bluetooth]# trust [MAC_ADDRESS]
83
+
84
+ Attempting to trust AB:CD:EF:12:34:56
85
+ [CHG] Device AB:CD:EF:12:34:56 Trusted: yes
86
+ ...
87
+
88
+ ```
89
+
90
+ ### Step 6: Connect the Device
91
+
92
+ This step attempts to establish the active connection.
93
+
94
+ ```
95
+
96
+ [bluetooth]# connect [MAC_ADDRESS]
97
+
98
+ Attempting to connect to AB:CD:EF:12:34:56
99
+ [CHG] Device AB:CD:EF:12:34:56 Connected: yes
100
+ Connection successful
101
+ ...
102
+ ```
103
+
104
+ ### Step 7: Pair the Device
105
+
106
+ If the connection attempt in Step 6 did not automatically handle the key exchange, or if you prefer to explicitly perform the key exchange first, use the pair command. This initiates the actual pairing sequence. If your device requires a PIN or Passkey, bluetoothctl will prompt you to enter it (or confirm it). NOTE: Check your device's manual for setting the device's pairing mode.
107
+
108
+ ```
109
+
110
+ [bluetooth]# pair [MAC_ADDRESS]
111
+ Attempting to pair with AB:CD:EF:12:34:56
112
+ [CHG] Device AB:CD:EF:12:34:56 Paired: yes
113
+ Pairing successful
114
+ ...
115
+
116
+ ```
117
+
118
+ (If prompted, enter or confirm the Passkey. If this command succeeds, you may need to run connect (Step 6) again to establish the active link.)
119
+
120
+ ### Step 8: Exit
121
+
122
+ Once the connection is established, you can exit the interactive utility.
123
+
124
+ ```
125
+
126
+ [bluetooth]# exit
127
+
128
+ ```
129
+
130
+ ## Summary of Essential Commands
131
+
132
+ | **Command** | **Purpose** |
133
+ | :--- | :--- |
134
+ | `bluetoothctl` | Enter the interactive prompt. |
135
+ | `power on` | Power on the local Bluetooth adapter. |
136
+ | `scan on` | Start discovering nearby devices. |
137
+ | `scan off` | Stop device discovery. |
138
+ | `trust [MAC]` | Mark the device as trusted for auto-reconnection. **(Crucial)** |
139
+ | `connect [MAC]` | Establish a connection to the device (may implicitly trigger pairing). |
140
+ | `pair [MAC]` | Explicitly initiate the pairing process (key exchange). |
141
+ | `exit` | Exit the `bluetoothctl` utility. |
142
+
143
+ ### Troubleshooting Tips
144
+
145
+ * **Adapter Issues:** If `show` or `list` commands don't show an adapter, ensure your Bluetooth hardware is properly recognized by the system (check kernel logs or `rfkill list`).
146
+
147
+ * **Device Out of Range:** Ensure the device is close to the computer and is fully charged.