bt-sensors-plugin-sk 1.2.4-1 → 1.2.4-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,20 @@
1
1
  # Bluetooth Sensors for [Signal K](http://www.signalk.org)
2
- # Version 1.2.4-1
3
-
4
2
  ## WHAT'S NEW
5
3
 
4
+ # Version 1.2.4-3
5
+
6
+ - Mercury Smartcraft fixes (working now!)
7
+ - Govee 510x regression errors fixed
8
+
9
+ # Version 1.2.4-2
10
+
11
+ - RenogyRoverClient fix to Battery SOC calculation
12
+ - VictronBatteryMonitor set default aux mode to secondary voltage
13
+ - SwitchBotTH and Meter Plus ::identify errors fixed
14
+ - MercurySmartcraft::identify method fix
15
+
16
+ # Version 1.2.4-1
17
+
6
18
  - **NEW SENSOR** [Bank Manager](https://marinedcac.com/pages/bankmanager) (tested)
7
19
  - **NEW SENSOR** [Mercury Smartcraft](https://www.mercurymarine.com/us/en/gauges-and-controls/displays/smartcraft-connect) (untested)
8
20
  - Fixed Govee 5075 parsing
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "bt-sensors-plugin-sk",
3
- "version": "1.2.4-1",
3
+ "version": "1.2.4-3",
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
- "dependencies": {
6
+ "dependencies": {
7
7
  "@rjsf/bootstrap-4": "^5.24.11",
8
8
  "@rjsf/core": "^5.24.11",
9
9
  "@rjsf/utils": "^5.24.11",
@@ -18,6 +18,7 @@ class GoveeSensor extends BTSensor {
18
18
 
19
19
  }
20
20
 
21
+ static DATA_ID=0xec88
21
22
  getManufacturer(){
22
23
  return "Govee"
23
24
  }
@@ -38,7 +39,7 @@ class GoveeSensor extends BTSensor {
38
39
  super.propertiesChanged(props)
39
40
  if (!props.hasOwnProperty("ManufacturerData")) return
40
41
 
41
- const buffer = this.getManufacturerData(0xec88)
42
+ const buffer = this.getManufacturerData(this.constructor.DATA_ID)
42
43
  if (buffer) {
43
44
  this.emitValuesFrom(buffer)
44
45
  }
@@ -1,6 +1,7 @@
1
1
  const GoveeSensor = require("./Govee/GoveeSensor");
2
2
 
3
3
  class GoveeH510x extends GoveeSensor{
4
+
4
5
  static getIDRegex(){
5
6
  return /^GVH510[0-9]_[a-f,A-F,0-9]{4}$/
6
7
  }
@@ -15,7 +16,7 @@ class GoveeH510x extends GoveeSensor{
15
16
  sensor.emitValuesFrom(Buffer.from([0x01,0x01,0x03,0x6d,0xcc,0x5c]))
16
17
 
17
18
  }
18
-
19
+ static DATA_ID = 0x0001
19
20
  initSchema(){
20
21
  super.initSchema()
21
22
  this.addDefaultParam("zone")
@@ -41,7 +41,7 @@ class JunctekBMS extends BTSensor{
41
41
  this.addDefaultPath("cycles",'electrical.batteries.cycles')
42
42
 
43
43
  this.addDefaultPath("soc",'electrical.batteries.capacity.stateOfCharge')
44
- this.addDefaultPath("remainingAh",'electrical.batteries.capacity.remaining')
44
+ this.addDefaultPath("remaining",'electrical.batteries.capacity.remaining')
45
45
  this.addDefaultPath("timeRemaining",'electrical.batteries.capacity.timeRemaining')
46
46
  this.addDefaultPath("discharge",'electrical.batteries.capacity.dischargeSinceFull')
47
47
  this.addDefaultPath("charge",'electrical.batteries.capacity.charge')
@@ -53,7 +53,7 @@ class JunctekBMS extends BTSensor{
53
53
 
54
54
  emitFrom(buffer){
55
55
  var value=[], chargeDirection = 1
56
-
56
+ this.debug(buffer)
57
57
  for (let byte of buffer){
58
58
  if (byte==0xBB) {
59
59
  value=[]
@@ -63,50 +63,53 @@ class JunctekBMS extends BTSensor{
63
63
  continue
64
64
  }
65
65
 
66
- value.push[byte]
67
-
68
- if (parseInt(byte.toString(16))==NaN){ //not a base-10 number. seriously. that's how Junctek does this.
66
+ if (isNaN(parseInt(byte.toString(16)))){ //not a base-10 number. seriously. that's how Junctek does this.
69
67
  const v = parseInt(bytesToBase10String(value))
68
+ value=[]
70
69
  switch (byte){
71
- case 0xC0:{
72
- emit("voltage",v/100)
73
- }
74
- case 0xC1:{
75
- emit("current",(v/100)*chargeDirection)
76
- }
77
-
78
- case 0xD1:{
70
+ case 0xC0:
71
+ this.emit("voltage",v/100)
72
+ break
73
+
74
+ case 0xC1:
75
+ this.emit("current",(v/100)*chargeDirection)
76
+ break
77
+
78
+ case 0xD1:
79
79
  if (byte==0)
80
80
  chargeDirection=-1
81
- }
82
-
83
- case 0xD2:{
84
- emit("remainingAh",v/1000)
85
- }
86
-
87
- case 0xD3:{
88
- emit("discharge",v/100000)
89
- }
90
- case 0xD4:{
91
- emit("charge",v/100000)
92
- }
93
- case 0xD6:{
94
- emit("timeRemaining",v*60)
95
- }
96
- case 0xD7:{
97
- emit("impedance",v/100)
98
- }
99
- case 0xD8:{
100
- emit("power",(v/100)*chargeDirection)
101
- }
102
- case 0xD9:{
103
- emit("temperature",v + 173.15) //assume C not F
104
- }
105
- case 0xB1:{
106
- emit("capacityActual",v /10 )
107
- }
81
+ break
82
+
83
+ case 0xD2:
84
+ this.emit("remaining",v*3.6)
85
+ break
86
+
87
+ case 0xD3:
88
+ this.emit("discharge",v/100000)
89
+ break
90
+ case 0xD4:
91
+ this.emit("charge",v/100000)
92
+ break
93
+ case 0xD6:
94
+ this.emit("timeRemaining",v*60)
95
+ break
96
+ case 0xD7:
97
+ this.emit("impedance",v/100)
98
+ break
99
+ case 0xD8:
100
+ this.emit("power",(v/100)*chargeDirection)
101
+ break
102
+ case 0xD9:
103
+ this.emit("temperature",v + 273.15) //assume C not F
104
+ break
105
+ case 0xB1:
106
+ this.emit("capacityActual",v /10 )
107
+ break
108
108
  }
109
109
  }
110
+ else{
111
+ value.push(byte)
112
+ }
110
113
  }
111
114
  }
112
115
  emitGATT(){
@@ -120,8 +123,9 @@ class JunctekBMS extends BTSensor{
120
123
  if (!this.gattServer) {
121
124
  this.gattServer = await this.device.gatt()
122
125
  this.battService = await this.gattServer.getPrimaryService("0000fff0-0000-1000-8000-00805f9b34fb")
123
- this.battCharacteristic = await this.battService.getCharacteristic("0000ffe1-0000-1000-8000-00805f9b34fb")
124
- }
126
+ this.battCharacteristic = await this.battService.getCharacteristic("0000fff1-0000-1000-8000-00805f9b34fb")
127
+
128
+ }
125
129
  resolve(this)
126
130
  }) .catch((e)=>{ reject(e.message) }) })
127
131
  }
@@ -21,7 +21,7 @@ class MercurySmartcraft extends BTSensor{
21
21
 
22
22
  const name = await this.getDeviceProp(device,"Name")
23
23
  const address = await this.getDeviceProp(device,"Address")
24
- if (name == `VVM_${address.replace(":","")}`)
24
+ if (name && address && name == `VVM_${address.replace(":","")}`)
25
25
  return this
26
26
  else
27
27
  return null
@@ -38,7 +38,7 @@ class MercurySmartcraft extends BTSensor{
38
38
  emitGATT(){
39
39
  }
40
40
  initSchema(){
41
- const bo = 0
41
+ const bo = 2
42
42
 
43
43
  super.initSchema()
44
44
  this.addParameter(
@@ -48,7 +48,7 @@ class MercurySmartcraft extends BTSensor{
48
48
  "examples": ["port","starboard","p0","p1"]
49
49
  }
50
50
  )
51
- _schema.properties.params.required=["id"]
51
+ this._schema.properties.params.required=["id"]
52
52
 
53
53
  this.addMetadatum("rpm","Hz","engine revolutions per sec",
54
54
  (buffer)=>{return buffer.readUInt16LE(bo)/60}
@@ -67,15 +67,15 @@ class MercurySmartcraft extends BTSensor{
67
67
  ).default='propulsion.{id}.runTime'
68
68
 
69
69
  this.addMetadatum("rate","m3/s","Fuel rate of consumption (cubic meters per second)",
70
- (buffer)=>{return buffer.readUInt16LE(bo)/10000}
70
+ (buffer)=>{return buffer.readUInt16LE(bo)/100000/3600}
71
71
  ).default='propulsion.{id}.fuel.rate'
72
72
 
73
73
  this.addMetadatum("pressure","Pa","Fuel pressure",
74
- (buffer)=>{return buffer.readUInt16LE(bo)/100}
74
+ (buffer)=>{return buffer.readUInt16LE(bo)*10}
75
75
  ).default='propulsion.{id}.pressure'
76
76
 
77
77
  this.addMetadatum("level","ratio","Level of fluid in tank 0-100%",
78
- (buffer)=>{return buffer.readUInt16LE(bo)/100}
78
+ (buffer)=>{return buffer.readUInt16LE(bo)/10000}
79
79
  ).default='tanks.petrol.currentLevel'
80
80
  }
81
81
 
@@ -100,7 +100,7 @@ class MercurySmartcraft extends BTSensor{
100
100
  }) .catch((e)=>{ reject(e.message) }) })
101
101
  }
102
102
  async initGATTNotifications() {
103
- await this.sdpCharacteristic.writeDataWithoutResponse(Buffer.from([0x0D,0x01]))
103
+ await this.sdpCharacteristic.writeValue(Buffer.from([0x0D,0x01]))
104
104
  for (const c in this.dataCharacteristics){
105
105
  Promise.resolve(this.dataCharacteristics[c].startNotifications().then(()=>{
106
106
  this.dataCharacteristics[c].on('valuechanged', buffer => {
@@ -113,7 +113,7 @@ class MercurySmartcraft extends BTSensor{
113
113
  async stopListening(){
114
114
  super.stopListening()
115
115
  for (const c in this.dataCharacteristics){
116
- if (this.dataCharacteristics[c] && await this.dataCharacteristics[char].isNotifying()) {
116
+ if (this.dataCharacteristics[c] && await this.dataCharacteristics[c].isNotifying()) {
117
117
  await this.dataCharacteristics[c].stopNotifications()
118
118
  }
119
119
  }
@@ -34,7 +34,7 @@ class RenogyRoverClient extends RenogySensor {
34
34
  this.addMetadatum('batteryType', '', "battery type")
35
35
  .default="electrical.chargers.{id}.battery.type"
36
36
  this.addMetadatum('batteryPercentage', 'ratio', "battery percentage",
37
- (buffer)=>{return buffer.readUInt16BE(3) })
37
+ (buffer)=>{return buffer.readUInt16BE(3)/100 })
38
38
  .default="electrical.chargers.{id}.battery.soc"
39
39
 
40
40
  this.addMetadatum('batteryVoltage', 'V', "battery voltage",
@@ -24,7 +24,7 @@ class SwitchBotMeterPlus extends BTSensor{
24
24
  const keys = Object.keys(md)
25
25
  if ( (keys && keys.length>0) && (sdKeys && sdKeys.length >0) ){
26
26
  const id = keys[keys.length-1]
27
- if (parseInt(id)==this.ID && md[id][0]==modelID && sdKeys[0] == this.serviceDataKey)
27
+ if (parseInt(id)==this.ID && md[id][0]==this.modelID && sdKeys[0] == this.serviceDataKey)
28
28
  return this
29
29
  }
30
30
  return null
@@ -63,7 +63,7 @@ class SwitchBotMeterPlus extends BTSensor{
63
63
  }
64
64
 
65
65
  getName() {
66
- return "SwitchBotMeterPlus"
66
+ return `SwitchBot Meter Plus (${this?.name??"Unnamed"})`
67
67
  }
68
68
 
69
69
  }
@@ -32,7 +32,7 @@ class SwitchBotTH extends BTSensor {
32
32
  const keys = Object.keys(md)
33
33
  if (keys && keys.length>0){
34
34
  const id = keys[keys.length-1]
35
- if (parseInt(id)==this.ID && md[id].length==12 && md[id][0]==modelID)
35
+ if (parseInt(id)==this.ID && md[id].length==12 && md[id][0]==this.modelID)
36
36
  return this
37
37
  }
38
38
  return null
@@ -59,7 +59,7 @@ class SwitchBotTH extends BTSensor {
59
59
  return "Wonder Labs"
60
60
  }
61
61
  getName() {
62
- "SwitchBotTH"
62
+ return `SwitchBotTH (${this?.name??"Unnamed"})`
63
63
  }
64
64
  async propertiesChanged(props){
65
65
  super.propertiesChanged(props)
@@ -22,7 +22,9 @@ class VictronBatteryMonitor extends VictronSensor{
22
22
  d.currentProperties = {}
23
23
  d.currentProperties.ManufacturerData={}
24
24
  d.currentProperties.ManufacturerData[0x02e1]=b
25
- d.initMetadata()
25
+ d.debug = (m)=>{console.log(m)}
26
+ d.debug.bind(d)
27
+ d.initSchema()
26
28
  Object.keys(d.getPaths()).forEach((tag)=>{
27
29
  d.on(tag,(v)=>console.log(`${tag}=${v}`))
28
30
  })
@@ -72,7 +74,7 @@ class VictronBatteryMonitor extends VictronSensor{
72
74
  this.addDefaultPath( 'ttg',"electrical.batteries.capacity.timeRemaining")
73
75
  .read=(buff,offset=0)=>{return this.NaNif(buff.readUInt16LE(offset),0xFFFF)*60}
74
76
  this.getPath("ttg").gatt='65970ffe-4bda-4c1e-af4b-551c4cf74769'
75
-
77
+ this.auxMode=VC.AuxMode.STARTER_VOLTAGE
76
78
  try {
77
79
  if (this.encryptionKey){
78
80
  const decData = this.decrypt(this.getManufacturerData(0x02e1))