bt-sensors-plugin-sk 1.3.0 → 1.3.2-1

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
@@ -856,6 +856,10 @@ class BTSensor extends EventEmitter {
856
856
  return this.currentProperties?.RSSI??NaN
857
857
  }
858
858
 
859
+ isPaired(){
860
+ return this.currentProperties?.Paired??false
861
+ }
862
+
859
863
  getSignalStrength(){
860
864
  const rssi = this.getRSSI()
861
865
  if (!rssi)
package/README.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # Bluetooth Sensors for [Signal K](http://www.signalk.org)
2
2
 
3
3
  ## WHAT'S NEW
4
+ # Version 1.3.2-1
5
+
6
+ - VictronSmartBatteryProtect fix
7
+ - RenogyRoverClient deviceID clarity
8
+
9
+ # Version 1.3.2
10
+
11
+ - Victron Alarm Reason improvements
12
+ - VictronOrionXS offReason text implementation
13
+ - Shelly Blu H&T description changes
14
+
15
+ # Version 1.3.1
16
+
17
+ - JBD Protection status
18
+ - SensorPush devices (untested)
4
19
 
5
20
  # Version 1.3.0
6
21
 
@@ -112,7 +127,7 @@ It's pretty easy to write and deploy your own sensor class for any currently uns
112
127
  |[Jikong](https://jikongbms.com/)| https://jikongbms.com/product/ |
113
128
  |[Junctek](https://www.junteks.com)|[Junctek BMS](https://www.junteks.com/pages/product/index) |
114
129
  |[Remoran](https://remoran.eu)| [Remoran Wave.3](https://remoran.eu/wave.html)|
115
- |[AC DC Systems](https://marinedcac.com) | [Bank Manager] hybrid (Pb and Li) charger(https://marinedcac.com/pages/bankmanager)|
130
+ |[AC DC Systems](https://marinedcac.com) | [Bank Manager](https://marinedcac.com/pages/bankmanager) hybrid (Pb and Li) charger|
116
131
  |[Ective](https://ective.de/)| Also Topband(?), Skanbatt and others |
117
132
 
118
133
  ### Environmental
@@ -128,6 +143,7 @@ It's pretty easy to write and deploy your own sensor class for any currently uns
128
143
  |[Govee](http://www.govee.com)| Govee H50xx and H510x Temperature and humidity sensors |
129
144
  |[BTHome](https://bthome.io/)| NOTE: Framework for IOT sensor devices. |
130
145
  |[Inkbird](https://inkbird.com/)| TH-2 Temp and Humidity Sensor |
146
+ |[SensorPush](https://www.sensorpush.com/)| Temperature, Humidity and Atmospheric Pressure sensor|
131
147
 
132
148
 
133
149
  ### Tanks
@@ -0,0 +1,54 @@
1
+ /*
2
+ Smart Battery Protect
3
+ Start
4
+ bit
5
+ Nr of
6
+ bits Meaning Units Range NA
7
+ value Remark
8
+ 8 8 Device state 0 .. 0xFE 0xFF VE_REG_DEVICE_STATE
9
+ 16 8 Output state 0 .. 0xFE 0xFF VE_REG_DC_OUTPUT_STATUS
10
+ 24 8 Error code 0 .. 0xFE 0xFF VE_REG_CHR_ERROR_CODE
11
+ 32 16 Alarm reason 0 .. 0xFFFF - VE_REG_ALARM_REASON
12
+ 48 16 Warning reason 0 .. 0xFFFF - VE_REG_WARNING_REASON
13
+ 64 16 Input voltage 0.01 V 327.68 .. 327.66 V 0x7FFF VE_REG_DC_CHANNEL1_VOLTAGE
14
+ 80 16 Output voltage 0.01 V 0 .. 655.34 V 0xFFFF VE_REG_DC_OUTPUT_VOLTAGE
15
+ 96 32 Off reason 0 .. 0xFFFFFFFF - VE_REG_DEVICE_OFF_REASON_2
16
+ */
17
+
18
+ const VictronSensor = require ("./Victron/VictronSensor.js")
19
+ const VC = require("./Victron/VictronConstants.js")
20
+ class VictronSmartBatteryProtect extends VictronSensor{
21
+
22
+ static ImageFile="VictronSmartBatteryProte.jpg"
23
+
24
+ initSchema(){
25
+ super.initSchema()
26
+ this.addDefaultParam("id")
27
+ this.addMetadatum('deviceState','', 'device state',
28
+ (buff)=>{return VC.OperationMode.get(buff.readUInt8(1))})
29
+ this.addMetadatum('outputStatus','', 'output status', //TODO
30
+ (buff)=>{return (buff.readUInt8(2))})
31
+
32
+ this.addMetadatum('chargerError','', 'charger error',
33
+ (buff)=>{return VC.ChargerError.get(buff.readUInt8(3))})
34
+ this.addMetadatum('alarmReason','', 'alarm reason',
35
+ (buff)=>{return buff.readUInt16LE(4)})
36
+ this.getPath("alarmReason").notify=true
37
+ this.addMetadatum('warningReason','', 'warning reason', //TODO
38
+ (buff)=>{return (buff.readUInt16LE(5))})
39
+ this.addMetadatum('channel1Voltage','V', 'channel one voltage',
40
+ (buff)=>{return this.NaNif(buff.readInt16LE(7),0x7FFF)/100})
41
+ this.addMetadatum('outputVoltage','V', 'output voltage',
42
+ (buff)=>{return this.NaNif(buff.readUInt16LE(9),0xFFFF)/100})
43
+ this.addMetadatum('offReason','', 'off reason',
44
+ (buff)=>{return this.offReasonText(buff.readUInt32LE(11))})
45
+ }
46
+ emitValuesFrom(decData){
47
+ super.emitValuesFrom(decData)
48
+ const alarm = this.getPath("alarmReason").read(decData)
49
+ if (alarm>0)
50
+ this.emitAlarm("alarmReason",alarm)
51
+ }
52
+
53
+ }
54
+ module.exports=VictronSmartBatteryProtect
@@ -0,0 +1,54 @@
1
+ /*
2
+ Smart Battery Protect
3
+ Start
4
+ bit
5
+ Nr of
6
+ bits Meaning Units Range NA
7
+ value Remark
8
+ 8 8 Device state 0 .. 0xFE 0xFF VE_REG_DEVICE_STATE
9
+ 16 8 Output state 0 .. 0xFE 0xFF VE_REG_DC_OUTPUT_STATUS
10
+ 24 8 Error code 0 .. 0xFE 0xFF VE_REG_CHR_ERROR_CODE
11
+ 32 16 Alarm reason 0 .. 0xFFFF - VE_REG_ALARM_REASON
12
+ 48 16 Warning reason 0 .. 0xFFFF - VE_REG_WARNING_REASON
13
+ 64 16 Input voltage 0.01 V 327.68 .. 327.66 V 0x7FFF VE_REG_DC_CHANNEL1_VOLTAGE
14
+ 80 16 Output voltage 0.01 V 0 .. 655.34 V 0xFFFF VE_REG_DC_OUTPUT_VOLTAGE
15
+ 96 32 Off reason 0 .. 0xFFFFFFFF - VE_REG_DEVICE_OFF_REASON_2
16
+ */
17
+
18
+ const VictronSensor = require ("./Victron/VictronSensor.js")
19
+ const VC = require("./Victron/VictronConstants.js")
20
+ class VictronSmartBatteryProtect extends VictronSensor{
21
+
22
+ static ImageFile="VictronSmartBatteryProte.jpg"
23
+
24
+ initSchema(){
25
+ super.initSchema()
26
+ this.addDefaultParam("id")
27
+ this.addMetadatum('deviceState','', 'device state',
28
+ (buff)=>{return VC.OperationMode.get(buff.readUInt8(1))})
29
+ this.addMetadatum('outputStatus','', 'output status', //TODO
30
+ (buff)=>{return (buff.readUInt8(2))})
31
+
32
+ this.addMetadatum('chargerError','', 'charger error',
33
+ (buff)=>{return VC.ChargerError.get(buff.readUInt8(3))})
34
+ this.addMetadatum('alarmReason','', 'alarm reason',
35
+ (buff)=>{return buff.readUInt16LE(4)})
36
+ this.getPath("alarmReason").notify=true
37
+ this.addMetadatum('warningReason','', 'warning reason', //TODO
38
+ (buff)=>{return (buff.readUInt16LE(5))})
39
+ this.addMetadatum('channel1Voltage','V', 'channel one voltage',
40
+ (buff)=>{return this.NaNif(buff.readInt16LE(7),0x7FFF)/100})
41
+ this.addMetadatum('outputVoltage','V', 'output voltage',
42
+ (buff)=>{return this.NaNif(buff.readUInt16LE(9),0xFFFF)/100})
43
+ this.addMetadatum('offReason','', 'off reason',
44
+ (buff)=>{return this.offReasonText(buff.readUInt32LE(11))})
45
+ }
46
+ emitValuesFrom(decData){
47
+ super.emitValuesFrom(decData)
48
+ const alarm = this.getPath("alarmReason").read(decData)
49
+ if (alarm>0)
50
+ this.emitAlarm("alarmReason",alarm)
51
+ }
52
+
53
+ }
54
+ module.exports=VictronSmartBatteryProtect
package/index.js CHANGED
@@ -110,7 +110,7 @@ class MissingSensor {
110
110
  on(){
111
111
 
112
112
  }
113
-
113
+ stopNotifications(){}
114
114
  isError(){
115
115
  return true
116
116
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bt-sensors-plugin-sk",
3
- "version": "1.3.0",
3
+ "version": "1.3.2-1",
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": {
Binary file
@@ -348,7 +348,7 @@ class GobiusCTankMeter extends BTSensor{
348
348
  }
349
349
 
350
350
  async deactivateGATT(){
351
- await this.stopNotifications(this.characteristic)
351
+ await this.stopGATTNotifications(this.characteristic)
352
352
  await super.deactivateGATT()
353
353
  }
354
354
 
@@ -62,15 +62,41 @@ class JBDBMS extends BTSensor {
62
62
  .read=(buffer)=>{return buffer.readUInt16BE(12)}
63
63
 
64
64
  this.addMetadatum('protectionStatus', '', 'Protection Status',
65
- (buffer)=>{return buffer.readUInt16BE(20)} )
65
+ (buffer)=>{
66
+ const bits = buffer.readUInt16BE(20).toString(2)
67
+ return {
68
+ singleCellOvervolt: bits[0]=='1',
69
+ singleCellUndervolt: bits[1]=='1',
70
+ packOvervolt: (bits[2]=='1'),
71
+ packUndervolt: bits[3]=='1',
72
+ chargeOvertemp:bits[4]=='1',
73
+ chargeUndertemp:bits[5]=='1',
74
+ dischargeOvertemp:bits[6]=='1',
75
+ dischargeUndertemp:bits[7]=='1',
76
+ chargeOvercurrent:bits[8]=='1',
77
+ dischargeOvercurrent:bits[9]=='1',
78
+ shortCircut:bits[10]=='1',
79
+ frontEndDetectionICError:bits[11]=='1',
80
+ softwareLockMOS:bits[12]=='1',
81
+ }
82
+ })
66
83
  .default="electrical.batteries.{batteryID}.protectionStatus"
67
84
 
68
85
  this.addDefaultPath('SOC','electrical.batteries.capacity.stateOfCharge')
69
86
  .read=(buffer)=>{return buffer.readUInt8(23)/100}
70
-
71
- this.addMetadatum('FET', '', 'FET Control',
72
- (buffer)=>{return buffer.readUInt8(24)} )
73
- .default="electrical.batteries.{batteryID}.FETControl"
87
+
88
+
89
+ this.addMetadatum('FET', '', 'FET On/Off Status',
90
+ (buffer)=>{return buffer.readUInt8(24) !=0 } )
91
+ .default="electrical.batteries.{batteryID}.FETStatus"
92
+
93
+ this.addMetadatum('FETCharging', '', 'FET Status Charging',
94
+ (buffer)=>{return (buffer.readUInt8(24) & 0x1) !=0 })
95
+ .default="electrical.batteries.{batteryID}.FETStatus.charging"
96
+
97
+ this.addMetadatum('FETDischarging', '', 'FET Status Discharging',
98
+ (buffer)=>{return (buffer.readUInt8(24) & 0x2) !=0 })
99
+ .default="electrical.batteries.{batteryID}.FETStatus.discharging"
74
100
 
75
101
  await this.deviceConnect()
76
102
  const gattServer = await this.device.gatt()
@@ -171,6 +197,7 @@ class JBDBMS extends BTSensor {
171
197
  }
172
198
 
173
199
  async initGATTConnection() {
200
+ this.setConnected(await this.device.isConnected())
174
201
  return this
175
202
  }
176
203
 
@@ -3,7 +3,7 @@ ported from https://github.com/cyrils/renogy-bt
3
3
  */
4
4
  const BTSensor = require("../../BTSensor.js");
5
5
  const VC = require('./RenogyConstants.js');
6
- const crc16Modbus = require('./CRC.js')
6
+ const crc16Modbus = require('./CRC.js');
7
7
  class RenogySensor extends BTSensor{
8
8
  static Domain=BTSensor.SensorDomains.electrical
9
9
  static ALIAS_PREFIX = 'BT-TH'
@@ -34,20 +34,27 @@ class RenogySensor extends BTSensor{
34
34
  b.writeUInt16BE(words,4)
35
35
  b.writeUInt16BE(crc16Modbus(b.subarray(0,6)),6)
36
36
 
37
- await writeCharacteristic.writeValueWithResponse(b, 0)
37
+ await writeCharacteristic.writeValueWithoutResponse(b, 0)
38
38
 
39
39
  }
40
40
  static identify(device){
41
41
  return null
42
42
  }
43
-
43
+ pollFreq=30
44
44
  async initSchema(){
45
45
  await super.initSchema()
46
-
46
+ this.getGATTParams().pollFreq.default=this.pollFreq
47
47
  this.addParameter(
48
48
  "deviceID",
49
49
  {
50
- title: 'ID of device'
50
+ title: 'ID of device',
51
+ description: 'only modify if device is in hub mode or daisy chained',
52
+ default:255,
53
+ type: 'number',
54
+ minimum: 0,
55
+ maximum: 255,
56
+ multipleOf:1,
57
+ isRequired: true
51
58
  }
52
59
  )
53
60
  }
@@ -73,15 +80,17 @@ class RenogySensor extends BTSensor{
73
80
  }
74
81
 
75
82
  async sendReadFunctionRequest(writeReq, words){
76
- this.constructor.sendReadFunctionRequest(
83
+ await this.constructor.sendReadFunctionRequest(
77
84
  this.writeChar, this.getDeviceID(), writeReq, words)
78
85
  }
79
86
 
80
87
  initGATTInterval(){
88
+ this.emitGATT()
81
89
  this.intervalID = setInterval(()=>{
82
90
  this.emitGATT()
83
91
  }, 1000*(this?.pollFreq??60) )
84
92
  }
93
+
85
94
  emitGATT(){
86
95
  this.getAllEmitterFunctions().forEach(async (emitter)=>
87
96
  await emitter()
@@ -12,9 +12,21 @@ class RenogyBattery extends RenogySensor {
12
12
  this.getAndEmitCellTemperatures.bind(this),
13
13
  this.getAndEmitCellVoltages.bind(this)]
14
14
  }
15
+ numberOfCells=4
15
16
  initSchema(){
16
-
17
- this.addMetadatum('numberOfCells','', 'number of cells')
17
+ this.addDefaultParam("batteryID").default="house"
18
+ this.addParameter(
19
+ "numberOfCells",
20
+ {
21
+ title:"Number of cells",
22
+ type: "number",
23
+ isRequired: true,
24
+ default: this.numberOfCells,
25
+ minimum: 1,
26
+ maximum: 16,
27
+ multipleOf:1
28
+ }
29
+ )
18
30
  this.addDefaultPath('current','electrical.batteries.current')
19
31
  .read=(buffer)=>{return buffer.readInt16BE(3)/100}
20
32
 
@@ -41,31 +53,33 @@ class RenogyBattery extends RenogySensor {
41
53
  async initGATTConnection() {
42
54
  await super.initGATTConnection()
43
55
  this.numberOfCells = await this.retrieveNumberOfCells()
44
- this.deviceID = await this.retrieveDeviceID()
45
- this.emit('numberOfCells', this.numberOfCells)
46
56
  }
47
57
 
48
- retrieveNumberOfCells(){
49
-
58
+ retrieveModelID(){
50
59
  return new Promise( async ( resolve, reject )=>{
51
- await this.sendReadFunctionRequest(0x1388,0x11)
52
60
 
53
- const valChanged = async (buffer) => {
54
- resolve(buffer.readUInt16(3))
55
- }
56
- this.readChar.once('valuechanged', valChanged )
61
+ await this.sendReadFunctionRequest(0x1402,0x08)
62
+
63
+ this.readChar.once('valuechanged', async (buffer) => {
64
+ if (buffer[2]!=0x10)
65
+ reject("Unknown error retrieving model ID") //???
66
+ const model = buffer.subarray(3,17).toString().trim()
67
+ resolve(model)
57
68
  })
69
+ })
58
70
  }
59
- retrieveDeviceID(){
71
+ retrieveNumberOfCells(){
72
+
60
73
  return new Promise( async ( resolve, reject )=>{
61
- this.sendFunctionRequest(0x14, 0x67)
74
+ await this.sendReadFunctionRequest(0x1388,0x11)
62
75
 
63
76
  const valChanged = async (buffer) => {
64
- resolve((buffer.readUInt8(4)))
77
+ resolve(buffer.readUInt16(3))
65
78
  }
66
79
  this.readChar.once('valuechanged', valChanged )
67
80
  })
68
81
  }
82
+
69
83
 
70
84
  getAndEmitBatteryInfo(){
71
85
  return new Promise( async ( resolve, reject )=>{
@@ -54,10 +54,24 @@ class RenogyInverter extends RenogySensor {
54
54
  })
55
55
  }
56
56
 
57
+ retrieveModelID(){
58
+ return new Promise( async ( resolve, reject )=>{
59
+
60
+ await this.sendReadFunctionRequest(0x10d7,0x08)
61
+
62
+ this.readChar.once('valuechanged', async (buffer) => {
63
+ if (buffer[2]!=0x10)
64
+ reject("Unknown error retrieving model ID") //???
65
+ const model = buffer.subarray(3,17).toString().trim()
66
+ resolve(model)
67
+ })
68
+ })
69
+ }
70
+
57
71
  getAndEmitInverterStats(){
58
72
  return new Promise( async ( resolve, reject )=>{
59
73
 
60
- await this.sendReadFunctionRequest(0xfa0, 0x8)
74
+ await this.sendReadFunctionRequest(0xfa0, 0xA)
61
75
 
62
76
  this.readChar.once('valuechanged', (buffer) => {
63
77
  ["ueiVoltage","ueiCurrent", "voltage", "loadCurrent", "frequency","temperature"].forEach((tag)=>
@@ -71,7 +85,7 @@ class RenogyInverter extends RenogySensor {
71
85
  getAndEmitSolarCharging(){
72
86
  return new Promise( async ( resolve, reject )=>{
73
87
 
74
- await this.sendReadFunctionRequest(0x10e9, 0x5)
88
+ await this.sendReadFunctionRequest(0x10e9, 0x7)
75
89
 
76
90
  this.readChar.once('valuechanged', (buffer) => {
77
91
  ["solarVoltage","solarCurrent", "solarPower", "solarChargingStatus", "solarChargingPower"].forEach((tag)=>
@@ -85,7 +99,7 @@ class RenogyInverter extends RenogySensor {
85
99
  getAndEmitInverterLoad(){
86
100
  return new Promise( async ( resolve, reject )=>{
87
101
 
88
- await this.sendReadFunctionRequest(0x113a, 0x2)
102
+ await this.sendReadFunctionRequest(0x113a, 0x6)
89
103
 
90
104
  this.readChar.once('valuechanged', (buffer) => {
91
105
  ["loadPower", "chargingCurrent"].forEach((tag)=>
@@ -34,6 +34,10 @@ class RenogyRoverClient extends RenogySensor {
34
34
  initSchema(){
35
35
  //Buffer(73) [1, 3, 68, 32, 32, 82, 78, 71, 45, 67, 84, 82, 76, 45, 87, 78, 68, 51, 48, 7, 140, 0, 132, 0, 126, 0, 120, 0, 111, 0, 106, 100, 50, 0, 5, 0, 120, 0, 120, 0, 28, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 5, 0, 5, 2, 148, 0, 5, 206, 143, 34, 228, buffer: ArrayBuffer(8192), byteLength: 73, byteOffset: 6144, length: 73, Symbol(Symbol.toStringTag): 'Uint8Array']
36
36
  super.initSchema()
37
+
38
+ this.addDefaultParam("id")
39
+ .default="solar"
40
+
37
41
  this.addMetadatum('batteryType', '', "battery type")
38
42
  .default="electrical.chargers.{id}.battery.type"
39
43
  this.addMetadatum('batteryPercentage', 'ratio', "battery percentage",
@@ -118,22 +122,12 @@ class RenogyRoverClient extends RenogySensor {
118
122
 
119
123
  }
120
124
 
121
- retrieveDeviceID(){
122
- return new Promise( async ( resolve, reject )=>{
123
- this.sendReadFunctionRequest(0x1A, 0x1)
124
-
125
- const valChanged = async (buffer) => {
126
- resolve((buffer.readUInt8(4)))
127
- }
128
- this.readChar.once('valuechanged', valChanged )
129
- })
130
- }
131
-
125
+
132
126
  retrieveBatteryType(){
133
127
  return new Promise( async ( resolve, reject )=>{
134
128
  //Buffer(7) [255, 3, 2, 0, 1, 80, 80, buffer: ArrayBuffer(8192), byteLength: 7, byteOffset: 864, length: 7, Symbol(Symbol.toStringTag): 'Uint8Array']
135
129
 
136
- this.sendReadFunctionRequest(0xe004, 0x01)
130
+ await this.sendReadFunctionRequest(0xe004, 0x01)
137
131
 
138
132
  const valChanged = async (buffer) => {
139
133
  resolve(RC.BATTERY_TYPE[(buffer.readUInt8(4))])
@@ -157,13 +151,10 @@ class RenogyRoverClient extends RenogySensor {
157
151
  }
158
152
  async initGATTConnection() {
159
153
  await super.initGATTConnection()
160
- if (!this.deviceID)
161
- this.deviceID = await this.retrieveDeviceID()
162
- this.modelID=await this.retrieveModelID()
163
154
 
155
+ this.modelID=await this.retrieveModelID()
164
156
  this.batteryType = await this.retrieveBatteryType()
165
- this.emit('batteryType', this.batteryType)
166
-
157
+ this.emit('batteryType', this.batteryType)
167
158
 
168
159
  }
169
160
 
@@ -175,7 +166,7 @@ class RenogyRoverClient extends RenogySensor {
175
166
  async getAndEmitChargeInfo(){
176
167
  return new Promise( async ( resolve, reject )=>{
177
168
  try {
178
- this.sendReadFunctionRequest(0x100, 0x22)
169
+ await this.sendReadFunctionRequest(0x100, 0x22)
179
170
 
180
171
  this.readChar.once('valuechanged', buffer => {
181
172
  this.emitValuesFrom(buffer)
@@ -0,0 +1,123 @@
1
+ const BTSensor = require("../BTSensor");
2
+ class SensorPush extends BTSensor{
3
+ static Domain = BTSensor.SensorDomains.environmental
4
+
5
+ static async identify(device){
6
+
7
+ const name = await this.getDeviceProp(device,"Name")
8
+ const regex= /^SensorPush\s(HT|HTP)\s[0-9a-fA-F]{4}$/
9
+ if (name && name.match(regex))
10
+ return this
11
+ else
12
+ return null
13
+ }
14
+ static ImageFile="SensorPush.webp"
15
+ static Manufacturer="Cousins & Sears - Creative Technologists - Brooklyn, NY USA"
16
+ static ServiceUUID = "EF090000-11D6-42BA-93B8-9DD7EC090AB0"
17
+ static Characteristics =
18
+ {
19
+ tx: "EF090003-11D6-42BA-93B8-9DD7EC090AA9",
20
+ adv: "EF090005-11D6-42BA-93B8-9DD7EC090AA9",
21
+ batt: "EF090007-11D6-42BA-93B8-9DD7EC090AA9",
22
+ LED: "EF09000C-11D6-42BA-93B8-9DD7EC090AA9",
23
+ temp: "EF090080-11D6-42BA-93B8-9DD7EC090AA9",
24
+ hum: "EF090081-11D6-42BA-93B8-9DD7EC090AA9",
25
+ bar: "EF090082-11D6-42BA-93B8-9DD7EC090AA9"
26
+ }
27
+ pollFreq=30
28
+ hasGATT(){
29
+ return true
30
+ }
31
+ usingGATT(){
32
+ return true
33
+ }
34
+
35
+
36
+ async emitGATT(){
37
+ this.characteristics.temp.writeValue(0x01000000).then(async ()=>{
38
+ this.emitData("temp", await this.characteristics.temp.readValue())
39
+ this.emitData("hum", await this.characteristics.temp.readValue())
40
+ })
41
+ this.characteristics.bar.writeValue(0x01000000).then(async ()=>{
42
+ this.emitData("bar", await this.characteristics.bar.readValue())
43
+ })
44
+ }
45
+
46
+ initSchema(){
47
+ super.initSchema()
48
+ this.getGATTParams()["useGATT"].default=true
49
+
50
+ this.addDefaultParam("zone")
51
+
52
+ this.addParameter(
53
+ "tx",
54
+ {
55
+ title:'transmission rate in db',
56
+ type: 'number',
57
+ enum: [-21, -18, -15, -12, -9, -6, -3, 0, 1, 2, 3, 4, 5],
58
+ default: -3,
59
+ isRequired: true
60
+ }
61
+ )
62
+ this.addParameter(
63
+ "adv",
64
+ {
65
+ title:'advertising interval in ms',
66
+ type: 'number',
67
+ default: 1285,
68
+ minimum: Math.round((32*625)/1000),
69
+ maximum: Math.round((32767*625)/1000),
70
+ isRequired: true
71
+ }
72
+ )
73
+
74
+ this.addParameter(
75
+ "LED",
76
+ {
77
+ type: 'number',
78
+ title:'LED flashes per second (0=off, 1-127, 128=once every second',
79
+ default: 0,
80
+ minimum: 0,
81
+ maximum: 128,
82
+ isRequired: true
83
+ }
84
+ )
85
+
86
+ this.addDefaultPath("batt","sensors.batteryVoltage")
87
+ .read=(buffer)=>{ return buffer.readUInt16LE()/100}
88
+
89
+ this.addDefaultPath("temp","environment.temperature")
90
+ .read=(buffer)=>{ return buffer.readInt32E()/100}
91
+
92
+ this.addDefaultPath("humidity","environment.humidity")
93
+ .read=(buffer)=>{ return buffer.readInt32E()/10000}
94
+
95
+ this.addDefaultPath("pressure","environment.pressure")
96
+ .read=(buffer)=>{ return buffer.readInt32E()/100}
97
+
98
+ }
99
+
100
+ async initGATTConnection(isReconnecting){
101
+ await super.initGATTConnection(isReconnecting)
102
+ const gattServer = await this.getGATTServer()
103
+ const service = await gattServer.getPrimaryService(this.constructor.ServiceUUID)
104
+ this.characteristics={}
105
+ for (const c in this.constructor.Characteristics) {
106
+ this.characteristics[c] = await service.getCharacteristic(this.constructor.Characteristics[c])
107
+ }
108
+ if (this.tx) this.characteristics.tx.writeValueWithoutResponse(this.tx)
109
+ if (this.LED) this.characteristics.LED.writeValueWithoutResponse(this.LED)
110
+ if (this.adv) this.characteristics.tx.writeValueWithoutResponse(Math.round((this.adv/625)*1000))
111
+ }
112
+ async initGATTNotifications() {
113
+
114
+ }
115
+
116
+ async deactivateGATT(){
117
+ for (const c in this.characteristics) {
118
+ await this.stopGATTNotifications(this.characteristics[c])
119
+ }
120
+ await super.deactivateGATT()
121
+ }
122
+ }
123
+ module.exports=SensorPush
@@ -20,10 +20,10 @@ class ShellySBHT003C extends AbstractBTHomeSensor {
20
20
 
21
21
 
22
22
  getTextDescription(){
23
- return `NOTE: Device must be paired with SignalK server machine to operate properly. For more information about the sensor go here: <a href=https://us.shelly.com/products/shelly-blu-h-t-black target="_blank">Shelly Blu H&T</a>.`
23
+ return `NOTE: Device must be paired with SignalK server machine or you won't see updates (see: <a href=https://shelly-api-docs.shelly.cloud/docs-ble/common#pairing target="_blank">https://shelly-api-docs.shelly.cloud/docs-ble/common#pairing</a> ). For more information about the sensor go here: <a href=https://us.shelly.com/blogs/documentation/shelly-blu-h-t target="_blank">Shelly Blu H&T</a>.<br><br>Alternatively you can edit your /etc/bluetooth/main.conf file and set "TemporaryTimeout = 90" in the [General] section, then restart the bluetooth service.`
24
24
  }
25
25
 
26
- initSchema() {
26
+ initSchema() {
27
27
  super.initSchema()
28
28
  this.addDefaultParam("zone")
29
29
 
@@ -20,11 +20,11 @@ class ShellySBMO003Z extends AbstractBTHomeSensor {
20
20
  * @type {string}
21
21
  */
22
22
  static LOCAL_NAME="Shelly BLU Motion";
23
- static ImageFile="ShellyBLUMotion.webp"
23
+ static ImageFile="ShellyBLUMotion.webp"
24
24
 
25
25
  getTextDescription(){
26
- return `NOTE: Device must be paired with SignalK server machine to operate properly. For more information about the sensor go here: <a href=https://us.shelly.com/products/shelly-blu-motion target="_blank">Shelly Blu Motion</a>.`
27
- }
26
+ return `${!this.isPaired()?"NOTE: Device must be paired with SignalK server machine to operate properly (see: <a href=https://shelly-api-docs.shelly.cloud/docs-ble/common#pairing target=\"_blank\">https://shelly-api-docs.shelly.cloud/docs-ble/common#pairing</a> ":"Device is paired."}).<br><br>For more information about the sensor click here: <a href=https://us.shelly.com/products/shelly-blu-motion target="_blank">Shelly Blu Motion</a>.`
27
+ }
28
28
 
29
29
  initSchema() {
30
30
  super.initSchema()
@@ -62,20 +62,6 @@ class ShellySBMO003Z extends AbstractBTHomeSensor {
62
62
  .default="sensors.{macAndName}.button"
63
63
 
64
64
 
65
- /*
66
- this.addMetadatum(
67
- "packetID",
68
- null,
69
- "packetID from sensor",
70
- this.parsePacketID.bind(this)
71
- )
72
- .default="sensors.{macAndName}.packetID"
73
- */
74
-
75
- }
76
- getState() {
77
-
78
- return super.getState()
79
65
  }
80
66
  }
81
67