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
@@ -1,204 +1,4 @@
1
- /*
2
- """Parser for Gmopeka_iot BLE advertisements.
3
1
 
4
- Thanks to https://github.com/spbrogan/mopeka_pro_check for
5
- help decoding the advertisements.
6
-
7
- MIT License applies.
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- import logging
13
- from dataclasses import dataclass
14
- from bluetooth_data_tools import short_address
15
- from bluetooth_sensor_state_data import BluetoothData
16
- from home_assistant_bluetooth import BluetoothServiceInfo
17
- from sensor_state_data import (
18
- BinarySensorDeviceClass,
19
- SensorDeviceClass,
20
- SensorLibrary,
21
- Units,
22
- )
23
-
24
- from .models import MediumType
25
-
26
- _LOGGER = logging.getLogger(__name__)
27
-
28
-
29
- # converting sensor value to height
30
- MOPEKA_TANK_LEVEL_COEFFICIENTS = {
31
- MediumType.PROPANE: (0.573045, -0.002822, -0.00000535),
32
- MediumType.AIR: (0.153096, 0.000327, -0.000000294),
33
- MediumType.FRESH_WATER: (0.600592, 0.003124, -0.00001368),
34
- MediumType.WASTE_WATER: (0.600592, 0.003124, -0.00001368),
35
- MediumType.LIVE_WELL: (0.600592, 0.003124, -0.00001368),
36
- MediumType.BLACK_WATER: (0.600592, 0.003124, -0.00001368),
37
- MediumType.RAW_WATER: (0.600592, 0.003124, -0.00001368),
38
- MediumType.GASOLINE: (0.7373417462, -0.001978229885, 0.00000202162),
39
- MediumType.DIESEL: (0.7373417462, -0.001978229885, 0.00000202162),
40
- MediumType.LNG: (0.7373417462, -0.001978229885, 0.00000202162),
41
- MediumType.OIL: (0.7373417462, -0.001978229885, 0.00000202162),
42
- MediumType.HYDRAULIC_OIL: (0.7373417462, -0.001978229885, 0.00000202162),
43
- }
44
-
45
- MOPEKA_MANUFACTURER = 89
46
- MOKPEKA_PRO_SERVICE_UUID = "0000fee5-0000-1000-8000-00805f9b34fb"
47
-
48
-
49
- @dataclass
50
- class MopekaDevice:
51
- model: str
52
- name: str
53
- adv_length: int
54
-
55
-
56
- DEVICE_TYPES = {
57
- 0x3: MopekaDevice("M1017", "Pro Check", 10),
58
- 0x4: MopekaDevice("Pro-200", "Pro-200", 10),
59
- 0x5: MopekaDevice("Pro H20", "Pro Check H2O", 10),
60
- 0x6: MopekaDevice("M1017", "Lippert BottleCheck", 10),
61
- 0x8: MopekaDevice("M1015", "Pro Plus", 10),
62
- 0x9: MopekaDevice("M1015", "Pro Plus with Cellular", 10),
63
- 0xA: MopekaDevice("TD40/TD200", "TD40/TD200", 10),
64
- 0xB: MopekaDevice("TD40/TD200", "TD40/TD200 with Cellular", 10),
65
- 0xC: MopekaDevice("M1017", "Pro Check Universal", 10),
66
- }
67
-
68
-
69
- def hex(data: bytes) -> str:
70
- """Return a string object containing two hexadecimal digits for each byte in the instance."""
71
- return "b'{}'".format("".join(f"\\x{b:02x}" for b in data)) # noqa: E231
72
-
73
-
74
- def battery_to_voltage(battery: int) -> float:
75
- """Convert battery value to voltage"""
76
- return battery / 32.0
77
-
78
-
79
- def battery_to_percentage(battery: int) -> float:
80
- """Convert battery value to percentage."""
81
- return round(max(0, min(100, (((battery / 32.0) - 2.2) / 0.65) * 100)), 1)
82
-
83
-
84
- def temp_to_celsius(temp: int) -> int:
85
- """Convert temperature value to celsius."""
86
- return temp - 40
87
-
88
-
89
- def tank_level_to_mm(tank_level: int) -> int:
90
- """Convert tank level value to mm."""
91
- return tank_level * 10
92
-
93
-
94
- def tank_level_and_temp_to_mm(
95
- tank_level: int, temp: int, medium: MediumType = MediumType.PROPANE
96
- ) -> int:
97
- """Get the tank level in mm for a given fluid type."""
98
- coefs = MOPEKA_TANK_LEVEL_COEFFICIENTS[medium]
99
- return int(tank_level * (coefs[0] + (coefs[1] * temp) + (coefs[2] * (temp**2))))
100
-
101
-
102
- class MopekaIOTBluetoothDeviceData(BluetoothData):
103
- """Data for Mopeka IOT BLE sensors."""
104
-
105
- def __init__(self, medium_type: MediumType = MediumType.PROPANE) -> None:
106
- super().__init__()
107
- self._medium_type = medium_type
108
-
109
- def _start_update(self, service_info: BluetoothServiceInfo) -> None:
110
- """Update from BLE advertisement data."""
111
- _LOGGER.debug(
112
- "Parsing Mopeka IOT BLE advertisement data: %s, MediumType is: %s",
113
- service_info,
114
- self._medium_type,
115
- )
116
- manufacturer_data = service_info.manufacturer_data
117
- service_uuids = service_info.service_uuids
118
- address = service_info.address
119
- if (
120
- MOPEKA_MANUFACTURER not in manufacturer_data
121
- or MOKPEKA_PRO_SERVICE_UUID not in service_uuids
122
- ):
123
- _LOGGER.debug("Not a Mopeka IOT BLE advertisement: %s", service_info)
124
- return
125
- data = manufacturer_data[MOPEKA_MANUFACTURER]
126
- model_num = data[0]
127
- if not (device_type := DEVICE_TYPES.get(model_num)):
128
- _LOGGER.debug("Unsupported Mopeka IOT BLE advertisement: %s", service_info)
129
- return
130
- adv_length = device_type.adv_length
131
- if len(data) != adv_length:
132
- return
133
-
134
- self.set_device_manufacturer("Mopeka IOT")
135
- self.set_device_type(device_type.model)
136
- self.set_device_name(f"{device_type.name} {short_address(address)}")
137
- battery = data[1]
138
- battery_voltage = battery_to_voltage(battery)
139
- battery_percentage = battery_to_percentage(battery)
140
- button_pressed = bool(data[2] & 0x80 > 0)
141
- temp = data[2] & 0x7F
142
- temp_celsius = temp_to_celsius(temp)
143
- tank_level = ((int(data[4]) << 8) + data[3]) & 0x3FFF
144
- tank_level_mm = tank_level_and_temp_to_mm(tank_level, temp, self._medium_type)
145
- reading_quality = data[4] >> 6
146
- accelerometer_x = data[8]
147
- accelerometer_y = data[9]
148
-
149
- self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, temp_celsius)
150
- self.update_predefined_sensor(
151
- SensorLibrary.BATTERY__PERCENTAGE, battery_percentage
152
- )
153
- self.update_predefined_sensor(
154
- SensorLibrary.VOLTAGE__ELECTRIC_POTENTIAL_VOLT,
155
- battery_voltage,
156
- name="Battery Voltage",
157
- key="battery_voltage",
158
- )
159
- self.update_predefined_binary_sensor(
160
- BinarySensorDeviceClass.OCCUPANCY,
161
- button_pressed,
162
- key="button_pressed",
163
- name="Button pressed",
164
- )
165
- self.update_sensor(
166
- "tank_level",
167
- Units.LENGTH_MILLIMETERS,
168
- tank_level_mm if reading_quality >= 1 else None,
169
- SensorDeviceClass.DISTANCE,
170
- "Tank Level",
171
- )
172
- self.update_sensor(
173
- "accelerometer_x",
174
- None,
175
- accelerometer_x,
176
- None,
177
- "Position X",
178
- )
179
- self.update_sensor(
180
- "accelerometer_y",
181
- None,
182
- accelerometer_y,
183
- None,
184
- "Position Y",
185
- )
186
- self.update_sensor(
187
- "reading_quality_raw",
188
- None,
189
- reading_quality,
190
- None,
191
- "Reading quality raw",
192
- )
193
- self.update_sensor(
194
- "reading_quality",
195
- Units.PERCENTAGE,
196
- round(reading_quality / 3 * 100),
197
- None,
198
- "Reading quality",
199
- )
200
- # Reading stars = (3-reading_quality) * "★" + (reading_quality * "⭐")
201
- */
202
2
 
203
3
  class MopekaDevice{
204
4
 
@@ -246,6 +46,9 @@ class MopekaTankSensor extends BTSensor{
246
46
  static serviceID16 = 0xFEE5
247
47
 
248
48
  static manufacturerID = 0x0059
49
+ static Manufacturer = "Mopeka Products LLC"
50
+
51
+ static ImageFile="MopekaTankSensor.jpg"
249
52
  static async identify(device){
250
53
  if (await this.getManufacturerID(device)==this.manufacturerID ){
251
54
  const uuids = await this.getDeviceProp(device, 'UUIDs')
@@ -259,8 +62,8 @@ class MopekaTankSensor extends BTSensor{
259
62
 
260
63
  async init(){
261
64
  await super.init()
262
- const md = this.valueIfVariant(this.getManufacturerData(this.constructor.manufacturerID))
263
- this.modelID = md[0]
65
+ const md = this.getManufacturerData(this.constructor.manufacturerID)
66
+ this.modelID = md?md[0]:0
264
67
  }
265
68
 
266
69
  getMedium(){
@@ -323,12 +126,12 @@ class MopekaTankSensor extends BTSensor{
323
126
  this.addMetadatum("accX","Mg","acceleration on X-axis",
324
127
  (buffer)=>{ return buffer.readUInt8(8)}
325
128
  )
326
- .default="sensors.{macAndName}.accelerationXAxis"
129
+ .examples=["sensors.{macAndName}.accelerationXAxis"]
327
130
 
328
131
  this.addMetadatum("accY","Mg","acceleration on Y-axis",
329
132
  (buffer)=>{ return buffer.readUInt8(9)}
330
133
  )
331
- .default="sensors.{macAndName}.accelerationYAxis"
134
+ .examples=["sensors.{macAndName}.accelerationYAxis"]
332
135
  }
333
136
 
334
137
  propertiesChanged(props){
@@ -33,11 +33,13 @@ const states= ["Charging Needed", "Charging", "Floating", "Idle"]
33
33
  const BTSensor = require("../BTSensor");
34
34
  class RemoranWave3 extends BTSensor{
35
35
  static Domain = BTSensor.SensorDomains.electrical
36
+ static ImageFile = "RemoranWave3.jpeg"
36
37
  serviceUUID = "81d08df0-c0f8-422a-9d9d-e4379bb1ea3b"
37
38
  info1CharUUID = "62c91222-fafe-4f6e-95f0-afc02bd19f2e"
38
39
  info2CharUUID = "f5d12d34-4390-486c-b906-24ea8906af71"
39
40
  eventUUID = "f12a8e25-59f7-42f2-b7ae-ba96fb25c13c"
40
41
 
42
+
41
43
  static async identify(device){
42
44
 
43
45
  const name = await this.getDeviceProp(device,"Name")
@@ -13,6 +13,7 @@ class RenogySensor extends BTSensor{
13
13
  static WRITE_CHAR_UUID = "0000ffd1-0000-1000-8000-00805f9b34fb"
14
14
  static READ_FUNC = 3
15
15
  static WRITE_FUNC = 6
16
+ static Manufacturer = "Renogy USA"
16
17
  constructor(device,config,gattConfig){
17
18
  super(device,config,gattConfig)
18
19
  }
@@ -5,13 +5,12 @@
5
5
  const RenogySensor = require("./Renogy/RenogySensor.js");
6
6
  class RenogyBattery extends RenogySensor {
7
7
 
8
-
8
+ static ImageFile="RenogySmartLiFePo4Battery.webp"
9
9
 
10
10
  async init(){
11
- await super.init()
12
11
  this.numberOfCells = await this.retrieveNumberOfCells()
13
12
  this.deviceID = await this.retrieveDeviceID()
14
- this.initMetadata()
13
+ await super.init()
15
14
  }
16
15
 
17
16
  async getAllEmitterFunctions(){
@@ -19,7 +18,7 @@ class RenogyBattery extends RenogySensor {
19
18
  this.getAndEmitCellTemperatures.bind(this),
20
19
  this.getAndEmitCellVoltages.bind(this)]
21
20
  }
22
- initMetadata(){
21
+ initSchema(){
23
22
 
24
23
  this.addMetadatum('numberOfCells','', 'number of cells')
25
24
  this.addDefaultPath('current','electrical.batteries.current')
@@ -6,13 +6,10 @@ const RenogySensor = require("./Renogy/RenogySensor.js");
6
6
  const RC=require("./Renogy/RenogyConstants.js")
7
7
  class RenogyInverter extends RenogySensor {
8
8
 
9
-
10
- async init(){
11
- await super.init()
12
- this.initMetadata()
13
- }
9
+ static ImageFile = "RenogyInverter.jpg"
14
10
 
15
- initMetadata(){
11
+ initSchema(){
12
+ super.initSchema()
16
13
  this.addMetadatum('batteryType', '', "battery type")
17
14
 
18
15
  this.addMetadatum('ueiVoltage','V','UEI Voltage',
@@ -6,6 +6,9 @@ const RenogySensor = require("./Renogy/RenogySensor.js");
6
6
  const RC=require("./Renogy/RenogyConstants.js")
7
7
 
8
8
  class RenogyRoverClient extends RenogySensor {
9
+
10
+ static ImageFile = "RenogyRoverClient.jpg"
11
+
9
12
  /*
10
13
  "batteryType": "electrical.charger.battery.type",
11
14
  "batteryPercentage": "electrical.charger.battery.charge",
@@ -2,6 +2,7 @@ const BTSensor = require("../BTSensor");
2
2
  class RuuviTag extends BTSensor{
3
3
  static manufacturerID = 0x0499
4
4
  static Domain = BTSensor.SensorDomains.environmental
5
+ static ImageFile = "RuuviTag.jpg"
5
6
  static async identify(device){
6
7
  if (await this.getManufacturerID(device)==this.manufacturerID)
7
8
  return this
@@ -14,9 +15,11 @@ class RuuviTag extends BTSensor{
14
15
  this.addDefaultParam("zone")
15
16
 
16
17
  const md = this.valueIfVariant(this.getManufacturerData(this.constructor.manufacturerID))
17
- this.mode = md[0]
18
- if (this['_initModeV'+this.mode])
19
- this['_initModeV'+this.mode]()
18
+ if (md) {
19
+ this.mode = md[0]
20
+ if (this['_initModeV'+this.mode])
21
+ this['_initModeV'+this.mode]()
22
+ }
20
23
  else
21
24
  throw new Error("Unrecognized Ruuvitag data mode "+md[0])
22
25
 
@@ -50,15 +53,15 @@ class RuuviTag extends BTSensor{
50
53
 
51
54
  this.addMetadatum("accX","Mg","acceleration on X-axis",
52
55
  (buffer)=>{ return buffer.readInt16BE(7)}
53
- ).default="sensors.{macAndName}.accX"
56
+ ).examples=["sensors.{macAndName}.accX"]
54
57
 
55
58
  this.addMetadatum("accY","Mg","acceleration on Y-axis",
56
59
  (buffer)=>{ return buffer.readInt16BE(9)}
57
- ) .default="sensors.{macAndName}.accY"
60
+ ) .examples=["sensors.{macAndName}.accY"]
58
61
 
59
62
  this.addMetadatum("accZ","Mg","acceleration on Z-axis",
60
63
  (buffer)=>{ return buffer.readInt16BE(11)}
61
- ) .default="sensors.{macAndName}.accZ"
64
+ ) .examples=["sensors.{macAndName}.accZ"]
62
65
 
63
66
  this.addDefaultPath("battV","sensors.batteryVoltage")
64
67
  .read=(buffer)=>{ return parseFloat((1.6+(buffer.readUInt16BE(13)>>5)/1000).toFixed(2))}
@@ -66,12 +69,12 @@ class RuuviTag extends BTSensor{
66
69
  this.addMetadatum("mc","","movement counter",
67
70
  (buffer)=>{ return buffer.readUInt16BE(13) && 0x1F}
68
71
  )
69
- .default="sensors.{macAndName}.movementCounter"
72
+ .examples=["sensors.{macAndName}.movementCounter"]
70
73
 
71
74
  this.addMetadatum("msc","","measurement sequence counter",
72
75
  (buffer)=>{ return buffer.readUInt16BE(15)}
73
76
  )
74
- .default="sensors.{macAndName}.measurementSequenceCounter"
77
+ .examples=["sensors.{macAndName}.measurementSequenceCounter"]
75
78
 
76
79
  }
77
80
 
@@ -16,7 +16,9 @@ class ShellySBDW002C extends AbstractBTHomeSensor {
16
16
  static SHORTENED_LOCAL_NAME = "SBDW-002C";
17
17
  static LOCAL_NAME = "Shelly BLU Door/Window";
18
18
 
19
- getDescription() {
19
+ static ImageFile="ShellyBluDoorWindow.webp"
20
+
21
+ getTextDescription() {
20
22
  return `For more information about the sensor go here: <a href=https://us.shelly.com/products/shelly-blu-door-window-white target="_blank">Shelly Blu Door/Window</a>.`;
21
23
  }
22
24
 
@@ -15,6 +15,13 @@ class ShellySBHT003C extends AbstractBTHomeSensor {
15
15
  */
16
16
  static SHORTENED_LOCAL_NAME = "SBHT-003C";
17
17
  static LOCAL_NAME = "TBD"
18
+
19
+ static ImageFile="ShellyBLUHT.webp"
20
+
21
+
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>.`
24
+ }
18
25
 
19
26
  initSchema() {
20
27
  super.initSchema()
@@ -20,8 +20,9 @@ class ShellySBMO003Z extends AbstractBTHomeSensor {
20
20
  * @type {string}
21
21
  */
22
22
  static LOCAL_NAME="Shelly BLU Motion";
23
-
24
- getDescription(){
23
+ static ImageFile="ShellyBLUMotion.webp"
24
+
25
+ getTextDescription(){
25
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>.`
26
27
  }
27
28
 
@@ -20,6 +20,7 @@ const ProtectionStatus = {
20
20
 
21
21
  class ShenzhenLiONBMS extends BTSensor{
22
22
  static Domain = BTSensor.SensorDomains.electrical
23
+ static ImageFile = "LiTimeLiFePo4Battery.avif"
23
24
  static Commands = {
24
25
  product_registration: new Uint8Array([0x00, 0x00, 0x04, 0x01, 0x01, 0x55, 0xAA, 0x05]),
25
26
  disconnect_registration: new Uint8Array([0x00, 0x00, 0x04, 0x01, 0x02, 0x55, 0xAA, 0x06]),
@@ -34,6 +35,9 @@ class ShenzhenLiONBMS extends BTSensor{
34
35
  static async identify(device){
35
36
  return null
36
37
  }
38
+ static DisplayName(){
39
+ "Shenzhen LiTime BMS Batteries: Redodo, Litime, PowerQueen and others"
40
+ }
37
41
  async sendCommand(cmd){
38
42
  await this.txCharacteristic.writeValueWithResponse( Buffer.from(cmd))
39
43
  }
@@ -1,7 +1,7 @@
1
1
  const BTSensor = require("../BTSensor");
2
2
  class SwitchBotMeterPlus extends BTSensor{
3
3
  static Domain = BTSensor.SensorDomains.environmental
4
-
4
+ static ImageFile = "SwitchBotMeterPlus.webp"
5
5
  constructor(device, config={}){
6
6
  super(device,config)
7
7
  if (config.parser){
@@ -2,7 +2,8 @@ const BTSensor = require("../BTSensor");
2
2
 
3
3
  class SwitchBotTH extends BTSensor {
4
4
  static Domain = BTSensor.SensorDomains.environmental
5
-
5
+ static ImageFile = "SwitchBotTH.webp"
6
+
6
7
  static async test(){
7
8
 
8
9
  const p = {[this.ID.toString()]: [0xd8, 0x35, 0x34, 0x38, 0x4f, 0x70, 0x07, 0x02, 0x04, 0x96, 0x2c, 0x00]}
@@ -13,7 +13,8 @@ class UNKNOWN extends BTSensor{
13
13
  "sensorClass",
14
14
  {
15
15
  title: "Sensor Class",
16
- enum:Array.from(this.constructor.classMap.keys())
16
+ enum: Array.from(this.constructor.classMap.keys()),
17
+ enumNames: (Array.from(this.constructor.classMap.values()).map((cls)=>{return cls.DisplayName()}))
17
18
  }
18
19
  )
19
20
  this.listen()
@@ -11,6 +11,9 @@ class UltrasonicWindMeter extends BTSensor{
11
11
  else
12
12
  return null
13
13
  }
14
+ static ImageFile="Ultrasonic.jpg"
15
+ static Manufacturer="Calypso Instruments EMEA, S.L."
16
+
14
17
  hasGATT(){
15
18
  return true
16
19
  }
@@ -110,6 +110,8 @@ const Images = require('./VictronImages.js')
110
110
  0xA06F: "BlueSolar MPPT 150|45 rev2",
111
111
  0xA070: "BlueSolar MPPT 150|60 rev2",
112
112
  0xA071: "BlueSolar MPPT 150|70 rev2",
113
+ 0xA0EB: "Smart Lithium Battery 12.8v 200AH",
114
+ 0xA0EA: "Smart Lithium Battery 25.6v 200AH",
113
115
  0xA0F0: "Smart Lithium Battery 4 cells 12v 330AH",
114
116
  0xA0EE: "Smart Lithium Battery",
115
117
  0xA102: "SmartSolar MPPT VE.Can 150/70",
@@ -0,0 +1,24 @@
1
+
2
+ class VictronIdentifier{
3
+ static identify( md ){
4
+ if (md.length>=5 && md[0]==0x10){
5
+ switch (md[4]) {
6
+ case 0x1: return require("../VictronSolarCharger")
7
+ case 0x2: return require("../VictronBatteryMonitor")
8
+ case 0x3: return require("../VictronInverter")
9
+ case 0x4: return require("../VictronDCDCConverter")
10
+ case 0x5: return require("../VictronSmartLithium")
11
+ case 0x6: return require("../VictronInverterRS")
12
+ case 0x7: return require("../VictronGXDevice")
13
+ case 0x8: return require("../VictronACCharger")
14
+ case 0x9: return require("../VictronSmartBatteryProtect")
15
+ case 0xA: return require("../VictronLynxSmartBMS")
16
+ case 0xC: return require("../VictronVEBus")
17
+ case 0xD: return require("../VictronDCEnergyMeter");
18
+ case 0xF: return require("../VictronOrionXS")
19
+ default: return null
20
+ }
21
+ }
22
+ }
23
+ }
24
+ module.exports=VictronIdentifier