bt-sensors-plugin-sk 1.2.5 → 1.2.6-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.
Files changed (126) hide show
  1. package/BTSensor.js +77 -38
  2. package/DistanceManager.js +249 -0
  3. package/Mixin.js +19 -0
  4. package/OutOfRangeDevice.js +46 -0
  5. package/README.md +20 -6
  6. package/classLoader.js +7 -2
  7. package/connectUUID.exp +26 -0
  8. package/index.js +54 -11
  9. package/package.json +8 -6
  10. package/public/159.js +1 -1
  11. package/public/540.js +1 -1
  12. package/public/681.js +3 -9
  13. package/public/681.js.LICENSE.txt +2 -0
  14. package/public/764.js +1 -0
  15. package/public/images/ATC.jpeg +0 -0
  16. package/public/images/Aranet4.webp +0 -0
  17. package/public/images/BP108B.webp +0 -0
  18. package/public/images/GoveeH5074.jpg +0 -0
  19. package/public/images/GoveeH5075.webp +0 -0
  20. package/public/images/GoveeH510x.jpg +0 -0
  21. package/public/images/InkbirdTH3.webp +0 -0
  22. package/public/images/JBDBMS.webp +0 -0
  23. package/public/images/Junctek.webp +0 -0
  24. package/public/images/KilovaultHLXPlus.jpg +0 -0
  25. package/public/images/LancolVoltageMeter.webp +0 -0
  26. package/public/images/LiTimeLiFePo4Battery.avif +0 -0
  27. package/public/images/MercurySmartcraft.jpg +0 -0
  28. package/public/images/MopekaTankSensor.jpg +0 -0
  29. package/public/images/RemoranWave3.jpeg +0 -0
  30. package/public/images/RenogyInverter.jpg +0 -0
  31. package/public/images/RenogyRoverClient.jpg +0 -0
  32. package/public/images/RenogySmartLiFePo4Battery.webp +0 -0
  33. package/public/images/RuuviTag.jpg +0 -0
  34. package/public/images/ShellyBLUHT.webp +0 -0
  35. package/public/images/ShellyBLUMotion.webp +0 -0
  36. package/public/images/ShellyBluDoorWindow.webp +0 -0
  37. package/public/images/Skanbatt.jpg +0 -0
  38. package/public/images/SmartBatteryProtect.webp +0 -0
  39. package/public/images/SmartBatterySense.webp +0 -0
  40. package/public/images/SwitchBotMeterPlus.webp +0 -0
  41. package/public/images/SwitchBotTH.webp +0 -0
  42. package/public/images/TopbandBattery.webp +0 -0
  43. package/public/images/Ultrasonic.jpg +0 -0
  44. package/public/images/VictronBlueSmartACCharger.jpg +0 -0
  45. package/public/images/VictronBlueSolarMPPT.jpeg +0 -0
  46. package/public/images/VictronCerboGX.webp +0 -0
  47. package/public/images/VictronInverterRS.webp +0 -0
  48. package/public/images/VictronLynxSmartBMS.webp +0 -0
  49. package/public/images/VictronMultiPlus-II.webp +0 -0
  50. package/public/images/VictronOrionTrIsolated.webp +0 -0
  51. package/public/images/VictronOrionTrNonIsolated.webp +0 -0
  52. package/public/images/VictronPhoenixInverter.webp +0 -0
  53. package/public/images/VictronPhoenixSmart1600.webp +0 -0
  54. package/public/images/VictronSmartBatteryProtect.jpg +0 -0
  55. package/public/images/VictronSmartIP43.webp +0 -0
  56. package/public/images/VictronSmartLithiumBattery.jpg +0 -0
  57. package/public/images/VictronSmartSolarMPPT.webp +0 -0
  58. package/public/images/VictronVEBus.webp +0 -0
  59. package/public/images/iBeacon.jpg +0 -0
  60. package/public/main.js +1 -1
  61. package/public/remoteEntry.js +1 -1
  62. package/readUUID.exp +23 -0
  63. package/sensor_classes/ATC.js +3 -2
  64. package/sensor_classes/Aranet2.js +3 -1
  65. package/sensor_classes/Aranet4.js +1 -2
  66. package/sensor_classes/BankManager.js +1 -1
  67. package/sensor_classes/Beacon/AbstractBeaconMixin.js +85 -0
  68. package/sensor_classes/Beacon/Eddystone.js +77 -0
  69. package/sensor_classes/Beacon/iBeacon.js +58 -0
  70. package/sensor_classes/EctiveBMS.js +270 -0
  71. package/sensor_classes/FeasyComBeacon.js +68 -0
  72. package/sensor_classes/GobiusCTankMeter.js +4 -3
  73. package/sensor_classes/GoveeH5074.js +2 -0
  74. package/sensor_classes/GoveeH5075.js +2 -0
  75. package/sensor_classes/GoveeH510x.js +1 -0
  76. package/sensor_classes/Inkbird.js +1 -0
  77. package/sensor_classes/JBDBMS.js +1 -0
  78. package/sensor_classes/Junctek.js +14 -6
  79. package/sensor_classes/KilovaultHLXPlus.js +1 -0
  80. package/sensor_classes/LancolVoltageMeter.js +2 -0
  81. package/sensor_classes/MercurySmartcraft.js +1 -0
  82. package/sensor_classes/MopekaTankSensor.js +7 -204
  83. package/sensor_classes/RemoranWave3.js +2 -0
  84. package/sensor_classes/Renogy/RenogySensor.js +1 -0
  85. package/sensor_classes/RenogyBattery.js +3 -4
  86. package/sensor_classes/RenogyInverter.js +3 -6
  87. package/sensor_classes/RenogyRoverClient.js +3 -0
  88. package/sensor_classes/RuuviTag.js +11 -8
  89. package/sensor_classes/ShellySBDW002C.js +3 -1
  90. package/sensor_classes/ShellySBHT003C.js +7 -0
  91. package/sensor_classes/ShellySBMO003Z.js +3 -2
  92. package/sensor_classes/ShenzhenLiOnBMS.js +4 -0
  93. package/sensor_classes/SwitchBotMeterPlus.js +1 -1
  94. package/sensor_classes/SwitchBotTH.js +2 -1
  95. package/sensor_classes/UNKNOWN.js +2 -1
  96. package/sensor_classes/UltrasonicWindMeter.js +3 -0
  97. package/sensor_classes/Victron/VictronConstants.js +2 -0
  98. package/sensor_classes/Victron/VictronIdentifier.js +24 -0
  99. package/sensor_classes/Victron/VictronSensor.js +59 -49
  100. package/sensor_classes/VictronACCharger.js +1 -6
  101. package/sensor_classes/VictronBatteryMonitor.js +37 -26
  102. package/sensor_classes/VictronDCDCConverter.js +1 -4
  103. package/sensor_classes/VictronDCEnergyMeter.js +1 -4
  104. package/sensor_classes/VictronGXDevice.js +1 -4
  105. package/sensor_classes/VictronInverter.js +2 -3
  106. package/sensor_classes/VictronInverterRS.js +2 -4
  107. package/sensor_classes/VictronLynxSmartBMS.js +1 -4
  108. package/sensor_classes/VictronOrionXS.js +1 -3
  109. package/sensor_classes/VictronSmartBatteryProtect.js +1 -4
  110. package/sensor_classes/VictronSmartLithium.js +1 -4
  111. package/sensor_classes/VictronSolarCharger.js +1 -3
  112. package/sensor_classes/VictronVEBus.js +1 -4
  113. package/sensor_classes/XiaomiMiBeacon.js +5 -2
  114. package/sensor_classes/iBeaconSensor.js +40 -0
  115. package/src/components/PluginConfigurationPanel.js +134 -173
  116. package/Screenshot 2025-06-12 at 9.33.57/342/200/257AM.png +0 -0
  117. package/bt-sensors-plugin-sk copy.json +0 -170
  118. package/bt-sensors-plugin-sk.json.bak +0 -121
  119. package/public/847.js +0 -1
  120. package/sensor_classes/IBeacon.js +0 -45
  121. package/vsl_patch_17_06_25.patch +0 -13
  122. /package/public/images/{Aranet2_HOME_F_900x900_90OVA5J.original.webp → Aranet2.webp} +0 -0
  123. /package/public/images/{Bank Manager All-in-onewc.webp → BankManager.webp} +0 -0
  124. /package/public/images/{Gobius_C.png → GobiusCTankMeter.png} +0 -0
  125. /package/public/images/{Victron-SmartShunt.jpg → VictronSmartShunt.jpg} +0 -0
  126. /package/public/images/{smartsolarMPPT7515.png → VictronSmartSolarMPPT7515.png} +0 -0
@@ -0,0 +1,270 @@
1
+ const { delimiter } = require("node:path");
2
+ const BTSensor = require("../BTSensor");
3
+ const EventEmitter = require('node:events');
4
+
5
+
6
+ const testData=[
7
+ ['5e 43',
8
+ '34',
9
+ '33 33 30 30 30 30 44 32 46 37 46 46 46 46 34 38',
10
+ '45 38 30 31 30 30 30 45 30 30 34 41',
11
+ '30 30 39 30 30 42 30 30 38 30 30 37 42 34 45 44',
12
+ '30 43 46 30 30 43 46 32 30 43 46 35 30 43 30 30',
13
+ '30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30',
14
+ '30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30',
15
+ '30 30 30 30 30 30 30 30 30 30 30 30',
16
+ '30 30 30 43 31 31 00 00 00 00 00 00 00 00'],
17
+ ["5e 35 34 33 37 30 30 30 30 30 30 30 30 30 30 30 30",
18
+ "34 38 45 38 30 31 30 30 31 30 30 30 36 33 30 30",
19
+ "43 30 30 42 30 30 38 30 38 37 46 34",
20
+ "33 41 30 45 30 35 30 45 30 33 30 45 30 46 30 44",
21
+ "30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30",
22
+ "30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30",
23
+ "30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30",
24
+ "30 35 37 44 00 00 00 00 00 00 00 00"
25
+ ],
26
+ //bad data (!=0x21)
27
+ ["5e 35 34 33 37 30 30 30 30 30 30 30 30 30 30 30 30",
28
+ "34 38 45 38 30 21 30 30 31 30 30 30 36 33 30 30",
29
+ "43 30 30 42 30 30 38 30 38 37 46 34",
30
+ "33 41 30 45 30 35 30 45 30 33 30 45 30 46 30 44",
31
+ "30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30",
32
+ "30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30",
33
+ "30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30",
34
+ "30 35 37 44 00 00 00 00 00 00 00 00"
35
+ ]
36
+ ]
37
+ class EctiveDataManager extends EventEmitter{
38
+ static expectedLength = 120
39
+ static ImageFile = "TopbandBattery.webp"
40
+ buffer = Buffer.from([])
41
+
42
+ delimitedAt(data){
43
+ const delimiters = [0x5e,0xaf]
44
+ for (const d of delimiters){
45
+ if (data.includes(d)) return data.indexOf(d)
46
+ }
47
+ return -1
48
+ }
49
+
50
+ add(buff) {
51
+
52
+ const delimiterIndex = this.delimitedAt(buff)
53
+ if (delimiterIndex == 0)
54
+ this.buffer= buff.subarray(1)
55
+ else {
56
+ if (delimiterIndex==-1)
57
+ this.buffer=Buffer.concat([this.buffer, buff])
58
+ else {
59
+ this.buffer=Buffer.concat([this.buffer,buff.subarray(0, delimiterIndex)])
60
+ }
61
+ }
62
+ if ( this.buffer.length==this.constructor.expectedLength) {
63
+ const _data = new EctiveData (this.buffer)
64
+ if (_data.error) {
65
+ this.buffer=Buffer.from([])
66
+ throw new Error (`malformed packet: ${JSON.parse(JSON.stringify(_data)).ascii}`)
67
+ }
68
+ else {
69
+ this.emit("valuechanged", _data.hex )
70
+ this.buffer=Buffer.from([])
71
+ }
72
+ } else {
73
+ if (delimiterIndex>0) {
74
+ this.buffer=buff.subarray(delimiterIndex+1)
75
+ }
76
+ }
77
+
78
+
79
+ }
80
+ }
81
+
82
+ class EctiveData{
83
+ constructor(data){
84
+ this.ascii = data.toString("utf8").slice(0,data.indexOf(0))
85
+ this.hex = Buffer.from(this.ascii,"hex")
86
+ this.error = !this.verify()
87
+ }
88
+
89
+ verify(){
90
+ return (this.hex.length==this.ascii.toString("utf8").length/2)
91
+ }
92
+ }
93
+ class EctiveBMS extends BTSensor {
94
+ static Domain = BTSensor.SensorDomains.electrical
95
+
96
+ static RX_SERVICE = "0000ffe0-0000-1000-8000-00805f9b34fb"
97
+ static NOTIFY_CHAR_UUID = "0000ffe4-0000-1000-8000-00805f9b34fb"
98
+ static test(data, numCells=4){
99
+ const obj = new EctiveBMS()
100
+ obj.currentProperties={Name:"Topbrand BMS", Address:"<mac>"}
101
+ obj.numberOfCells=numCells
102
+ obj.initSchema()
103
+ obj.debug=(m)=>{console.log(m)}
104
+ for (const [tag,path] of Object.entries(obj._schema.properties.paths.properties)) {
105
+ obj.on(tag, val=>{console.log(`${tag} => ${val} `)})
106
+ }
107
+ obj._dataManager.on("valuechanged", (b)=>{
108
+ obj.emitValuesFrom(b)
109
+ })
110
+ data.forEach(d => {
111
+ const _d=d.replaceAll(" ","").toLowerCase()
112
+ const b=Buffer.from(_d,"hex")
113
+ try {
114
+ obj._dataManager.add(b)
115
+ } catch (e){
116
+ obj.debug(`(${obj.getName()}): ${e.message}`)
117
+ }
118
+ });
119
+ }
120
+ static testStream(filename, numCells=4){
121
+ const obj = new EctiveBMS()
122
+ obj.currentProperties={Name:"Topbrand BMS", Address:"<mac>"}
123
+ obj.numberOfCells=numCells
124
+ obj.initSchema()
125
+ obj.debug=(m)=>{console.log(m)}
126
+ for (const [tag,path] of Object.entries(obj._schema.properties.paths.properties)) {
127
+ obj.on(tag, val=>{console.log(`${tag} => ${val} `)})
128
+ }
129
+ obj._dataManager.on("valuechanged", (b)=>{
130
+ obj.emitValuesFrom(b)
131
+ })
132
+ const lineReader = require('readline').createInterface({ input: require('fs').createReadStream(filename)});
133
+ // Each line in input.txt will be successively available here as `line`.
134
+
135
+ (async ()=>{for await (const line of lineReader) {
136
+ const _d = line.slice(0,50).replaceAll(" ","").toLowerCase()
137
+ const b=Buffer.from(_d,"hex")
138
+ try {
139
+ obj._dataManager.add(b)
140
+ } catch (e){
141
+ obj.debug(`(${obj.getName()}): ${e.message}`)
142
+ }
143
+ }})()
144
+ }
145
+
146
+ static DisplayName(){
147
+ return "EctiveBMS: Topbrand, Skanbatt and other LiFePo4 batteries"
148
+ }
149
+ static identify(device){
150
+ return null
151
+ }
152
+
153
+ _dataManager = new EctiveDataManager()
154
+ initSchema(){
155
+ super.initSchema()
156
+ this.addDefaultParam("batteryID")
157
+ this.addParameter(
158
+ "numberOfCells",
159
+ {
160
+ title:'number of cells in battery',
161
+ type: 'integer',
162
+ default: 4,
163
+ isRequired: true
164
+ }
165
+ )
166
+
167
+ this.addDefaultPath('voltage','electrical.batteries.voltage')
168
+ .read=
169
+ (buffer)=>{return buffer.readUInt32LE(0) / 1000}
170
+
171
+ this.addDefaultPath('current','electrical.batteries.current')
172
+ .read=
173
+ (buffer)=>{return buffer.readInt32LE(4) / 1000}
174
+
175
+ this.addMetadatum(`cycleCharge`, 'C', `cycle charge`,
176
+ (buffer)=>{
177
+ return 3600*(buffer.readUInt32LE(8)/1000)
178
+ })
179
+ .default='electrical.batteries.{batteryID}.cycleCharge'
180
+
181
+
182
+ this.addMetadatum('cycleCount', '', 'number of cycles',
183
+ (buffer)=>{
184
+ return buffer.readUInt16LE(12)
185
+ })
186
+ .default='electrical.batteries.{batteryID}.cycles'
187
+
188
+ this.addDefaultPath('SOC','electrical.batteries.capacity.stateOfCharge')
189
+ .read=(buffer)=>{return buffer.readUInt16LE(14)/100}
190
+
191
+ this.addMetadatum('temp', 'K', 'Temperature reading',
192
+ (buffer)=>{
193
+ return buffer.readUInt16LE(16)/10
194
+ })
195
+ .default='electrical.batteries.{batteryID}.temperature'
196
+
197
+
198
+ this.addMetadatum('flags', '', 'Problem flags',
199
+ (buffer)=>{
200
+ return buffer.readUInt16LE(18).toString('2').padStart(16,'0')
201
+ })
202
+ .default='electrical.batteries.{batteryID}.problemFlags'
203
+
204
+
205
+ for (let i=0; i<this?.numberOfCells??4; i++){
206
+ this.addMetadatum(`cell${i+1}Voltage`, 'V', `Cell ${i+1} voltage`,
207
+ (buffer)=>{return buffer.readUInt16LE((22+(i*2)))/1000} )
208
+ .default=`electrical.batteries.{batteryID}.cell${i+1}.voltage`
209
+ }
210
+ }
211
+
212
+ hasGATT(){
213
+ return true
214
+ }
215
+
216
+
217
+ usingGATT(){
218
+ return true
219
+ }
220
+
221
+ emitGATT(){
222
+ //do nothing
223
+ }
224
+
225
+ verifyData(d1,d2){
226
+ if (d1.length!==d2.toString("utf8").length/2) {
227
+ this._dataError=true
228
+ this.debug(`(${this.getName()}) malformed packet received: ${d2.toString()}`)
229
+ }
230
+ return !this._dataError
231
+ }
232
+
233
+
234
+ async initGATTNotifications(){
235
+ await this.rxChar.startNotifications()
236
+ this.debug(`(${this.getName()}) Notifications started`)
237
+
238
+ this.rxChar.on("valuechanged", (buffer)=>{
239
+ try {
240
+ this._dataManager.add(buffer)
241
+ } catch (e){
242
+ this.debug(`(${this.getName()}): ${e.message}`)
243
+ }
244
+ })
245
+ this._dataManager.on("valuechanged", (b)=>{
246
+ this.emitValuesFrom(b)
247
+ } )
248
+ }
249
+
250
+ async initGATTConnection() {
251
+
252
+ await this.deviceConnect()
253
+ const gattServer = await this.device.gatt()
254
+ const rxService= await gattServer.getPrimaryService(this.constructor.RX_SERVICE)
255
+ this.rxChar = await rxService.getCharacteristic(this.constructor.NOTIFY_CHAR_UUID)
256
+
257
+ }
258
+
259
+
260
+ async stopListening(){
261
+ super.stopListening()
262
+ if (this.rxChar)
263
+ this.rxChar.stopNotifications()
264
+ if (this.device)
265
+ await this.device.disconnect()
266
+ }
267
+
268
+ }
269
+
270
+ module.exports = EctiveBMS;
@@ -0,0 +1,68 @@
1
+
2
+ const BTSensor = require("../BTSensor");
3
+ const Eddystone = require("./Beacon/Eddystone")
4
+ const iBeacon = require("./Beacon/iBeacon")
5
+
6
+ class FeasyComBeacon extends BTSensor {
7
+
8
+ static async identify (device){
9
+ return null
10
+ }
11
+ static IsRoaming = true;
12
+ static Domain = BTSensor.SensorDomains.beacons
13
+ static ImageFile = "BP108B.webp"
14
+
15
+ initSchema(){
16
+ super.initSchema()
17
+ this.addParameter("beaconType",
18
+ {
19
+ title:"type of beacon",
20
+ enum: ["Eddystone", "iBeacon"],
21
+ isRequired: true,
22
+ default:"EddyStone"
23
+ }
24
+ )
25
+ this.beacon.initSchema()
26
+ }
27
+
28
+ async init(){
29
+ const bt = this?.beaconType??"Eddystone"
30
+ if (bt=="Eddystone") {
31
+
32
+ this.beacon=new Eddystone(this)
33
+
34
+ }
35
+ else
36
+ if (bt=="iBeacon")
37
+ this.beacon=new iBeacon(this)
38
+ else
39
+ throw new Error (`(${this.getName()}) Unknown Beacon Type: ${bt}`)
40
+
41
+ await super.init()
42
+
43
+ }
44
+
45
+ initListen(){
46
+ super.initListen()
47
+ this.beacon.initListen()
48
+
49
+ }
50
+ elapsedTimeSinceLastContact(){
51
+
52
+ return this.beacon.elapsedTimeSinceLastContact(super.elapsedTimeSinceLastContact())
53
+ }
54
+
55
+ propertiesChanged(props){
56
+ super.propertiesChanged(props);
57
+ this.beacon.propertiesChanged(props)
58
+ }
59
+
60
+ getManufacturer(){
61
+ return "FeasyCom Inc.";
62
+ }
63
+ getTextDescription(){
64
+ return `${this.getName()} iBeacon/Eddystone device`
65
+ }
66
+ }
67
+
68
+ module.exports = FeasyComBeacon;
@@ -261,6 +261,8 @@ class GobiusCTankMeter extends BTSensor{
261
261
  else
262
262
  return null
263
263
  }
264
+ static ImageFile = "GobiusCTankMeter.jpg"
265
+
264
266
  hasGATT(){
265
267
  return true
266
268
  }
@@ -274,6 +276,7 @@ class GobiusCTankMeter extends BTSensor{
274
276
  )
275
277
 
276
278
  }
279
+
277
280
  initSchema(){
278
281
  super.initSchema()
279
282
  this.getGATTParams()["useGATT"].default=true
@@ -351,9 +354,7 @@ class GobiusCTankMeter extends BTSensor{
351
354
  })
352
355
  }))
353
356
  }
354
- getDescription(){
355
- return '<a href="https://gobiusc.com/"><img src="../bt-sensors-plugin-sk/images/Gobius_C.png" alt="Gobius C Tank Measure" "></a>'
356
- }
357
+
357
358
  async stopListening(){
358
359
  super.stopListening()
359
360
  if (this.characteristic && await this.characteristic.isNotifying()) {
@@ -4,6 +4,8 @@ class GoveeH5074 extends GoveeSensor {
4
4
  static getIDRegex() {
5
5
  return /^Govee_H5074_[a-f,A-F,0-9]{4}$/
6
6
  }
7
+ static ImageFile = "GoveeH5074.jpg"
8
+
7
9
  initSchema(){
8
10
  super.initSchema()
9
11
  this.addDefaultParam("zone")
@@ -15,6 +15,8 @@ class GoveeH5075 extends GoveeSensor {
15
15
  sensor.emitValuesFrom(Buffer.from([0x00,0x03,0xbb,0x94,0x64,0x00]))
16
16
 
17
17
  }
18
+ static ImageFile = "GoveeH5075.webp"
19
+
18
20
  initSchema(){
19
21
  super.initSchema()
20
22
  this.addDefaultParam("zone")
@@ -17,6 +17,7 @@ class GoveeH510x extends GoveeSensor{
17
17
 
18
18
  }
19
19
  static DATA_ID = 0x0001
20
+ static ImageFile = "GoveeH510x.jpg"
20
21
  initSchema(){
21
22
  super.initSchema()
22
23
  this.addDefaultParam("zone")
@@ -12,6 +12,7 @@ class Inkbird extends BTSensor{
12
12
  return null
13
13
 
14
14
  }
15
+ static ImageFile = "InkbirdTH3.jpg"
15
16
 
16
17
  initSchema() {
17
18
  super.initSchema()
@@ -29,6 +29,7 @@ class JBDBMS extends BTSensor {
29
29
  static identify(device){
30
30
  return null
31
31
  }
32
+ static ImageFile = "JBDBMS.webp"
32
33
 
33
34
  jbdCommand(command) {
34
35
  return [0xDD, 0xA5, command, 0x00, 0xFF, 0xFF - (command - 1), 0x77]
@@ -21,19 +21,27 @@ class JunctekBMS extends BTSensor{
21
21
 
22
22
  return null
23
23
  }
24
+ static ImageFile = "Junctek.webp"
24
25
 
25
- chargeDirection = 1
26
+ chargeDirection = 0
26
27
 
27
28
  hasGATT(){
28
29
  return true
29
30
  }
30
31
 
31
-
32
-
33
32
  async initSchema(){
34
33
  super.initSchema()
35
34
  this.addDefaultParam("batteryID")
36
35
 
36
+ this.addParameter("capacityAh",
37
+ {
38
+ title:"battery capacity in Ah",
39
+ type:"integer",
40
+ isRequired: true,
41
+ default: 200
42
+ }
43
+ )
44
+
37
45
  this.addDefaultPath("voltage","electrical.batteries.voltage")
38
46
 
39
47
  this.addDefaultPath("current","electrical.batteries.current")
@@ -78,16 +86,15 @@ class JunctekBMS extends BTSensor{
78
86
  break
79
87
 
80
88
  case 0xC1:
81
- emitObject["current"]=()=>{return (v/100)*this.chargeDirection}
89
+ if (this.chargeDirection)
90
+ emitObject["current"]=()=>{return (v/100)*this.chargeDirection}
82
91
  break
83
92
 
84
93
  case 0xD1:
85
- this.debug(v)
86
94
  if (v==0)
87
95
  this.chargeDirection=-1
88
96
  else
89
97
  this.chargeDirection= 1
90
- this.debug(this.chargeDirection)
91
98
  break
92
99
 
93
100
  case 0xD2:
@@ -125,6 +132,7 @@ class JunctekBMS extends BTSensor{
125
132
  break
126
133
  case 0xB1:
127
134
  emitObject["capacityActual"]=v /10
135
+ emitObject["soc"]=(this.capacityAh/(emitObject["capacityActual"]))/100
128
136
  break
129
137
  }
130
138
  }
@@ -41,6 +41,7 @@ class KilovaultHLXPlus extends BTSensor{
41
41
  super(device, config, gattConfig)
42
42
  this.accumulated_buffer = Buffer.alloc(0)
43
43
  }
44
+ static ImageFile = "KilovaultHLXPlus.jpg"
44
45
 
45
46
  static async identify(device){
46
47
  const regex = /^\d\d\-(12|24|36)00HLX\+\d{4}/
@@ -3,6 +3,8 @@ const BTSensor = require("../BTSensor");
3
3
  class LancolVoltageMeter extends BTSensor{
4
4
 
5
5
  static Domain = BTSensor.SensorDomains.electrical
6
+ static ImageFile = "LancolVoltageMeter.webp"
7
+
6
8
  static async identify(device){
7
9
 
8
10
  const name = await this.getDeviceProp(device,"Name")
@@ -26,6 +26,7 @@ class MercurySmartcraft extends BTSensor{
26
26
  else
27
27
  return null
28
28
  }
29
+ static ImageFile = "MercurySmartcraft.jpg"
29
30
 
30
31
 
31
32