bt-sensors-plugin-sk 1.1.0-beta.2.1.3.3 → 1.1.0-beta.2.1.4.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 +1 -1
- package/index.js +2 -5
- package/package.json +2 -2
- package/sensor_classes/ATC.js +5 -9
- package/sensor_classes/BlackListedDevice.js +2 -1
- package/sensor_classes/GoveeTH.js +66 -0
- package/sensor_classes/Inkbird.js +8 -11
- package/sensor_classes/MopekaTankSensor.js +9 -14
- package/sensor_classes/RuuviTag.js +4 -8
- package/sensor_classes/UltrasonicWindMeter.js +18 -11
- package/sensor_classes/Victron/VictronConstants.js +1 -0
- package/sensor_classes/Victron/VictronSensor.js +41 -19
- package/sensor_classes/VictronACCharger.js +24 -17
- package/sensor_classes/VictronDCDCConverter.js +3 -0
- package/sensor_classes/VictronDCEnergyMeter.js +14 -6
- package/sensor_classes/VictronGXDevice.js +7 -4
- package/sensor_classes/VictronInverter.js +11 -6
- package/sensor_classes/VictronLynxSmartBMS.js +22 -11
- package/sensor_classes/VictronSmartBatteryProtect.js +3 -0
- package/sensor_classes/VictronSmartLithium.js +24 -24
- package/sensor_classes/VictronSolarCharger.js +1 -1
- package/sensor_classes/VictronVEBus.js +35 -16
- package/sensor_classes/XiaomiMiBeacon.js +8 -8
- package/sensor_classes/_BitReader.js +28 -0
package/BTSensor.js
CHANGED
|
@@ -152,7 +152,7 @@ class BTSensor extends EventEmitter {
|
|
|
152
152
|
*/
|
|
153
153
|
class Metadatum{
|
|
154
154
|
|
|
155
|
-
constructor(tag, unit, description, read
|
|
155
|
+
constructor(tag, unit, description, read, gatt=null, type){
|
|
156
156
|
this.tag = tag
|
|
157
157
|
this.unit = unit
|
|
158
158
|
this.description = description
|
package/index.js
CHANGED
|
@@ -90,15 +90,13 @@ module.exports = function (app) {
|
|
|
90
90
|
}, x);
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
async function instantiateSensor(device,config){
|
|
94
94
|
try{
|
|
95
95
|
for (var [clsName, cls] of classMap) {
|
|
96
|
+
if (clsName.startsWith("_")) continue
|
|
96
97
|
const c = await cls.identify(device)
|
|
97
98
|
if (c) {
|
|
98
|
-
|
|
99
|
-
if (c.name.startsWith("_")) continue
|
|
100
99
|
c.debug=app.debug
|
|
101
|
-
c.debug.bind(c)
|
|
102
100
|
const sensor = new c(device,config?.params, config?.gattParams)
|
|
103
101
|
sensor.debug=app.debug
|
|
104
102
|
await sensor.init()
|
|
@@ -356,7 +354,6 @@ module.exports = function (app) {
|
|
|
356
354
|
})
|
|
357
355
|
.catch((error)=>
|
|
358
356
|
{
|
|
359
|
-
|
|
360
357
|
const msg =`Sensor at ${deviceConfig.mac_address} unavailable. Reason: ${error}`
|
|
361
358
|
app.debug(msg)
|
|
362
359
|
app.debug(error)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bt-sensors-plugin-sk",
|
|
3
|
-
"version": "1.1.0-beta.2.1.
|
|
4
|
-
"description": "Bluetooth Sensors for Signalk -- support for Victron devices, RuuviTag, Xiaomi, ATC and Inkbird",
|
|
3
|
+
"version": "1.1.0-beta.2.1.4.1",
|
|
4
|
+
"description": "Bluetooth Sensors for Signalk -- support for Victron devices, RuuviTag, Xiaomi, ATC and Inkbird, Ultrasonic, Mopeka tank reader and preliminary support for Govee GVH51xx temp sensors",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"dbus-next": "^0.10.2",
|
package/sensor_classes/ATC.js
CHANGED
|
@@ -8,16 +8,12 @@ class ATC extends BTSensor{
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
static async identify(device){
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
} catch (e){
|
|
11
|
+
const regex = /^ATC_[A-Fa-f0-9]{6}$/
|
|
12
|
+
const name = await this.getDeviceProp(device,"Name")
|
|
13
|
+
if (name && name.match(regex))
|
|
14
|
+
return this
|
|
15
|
+
else
|
|
18
16
|
return null
|
|
19
|
-
}
|
|
20
|
-
return null
|
|
21
17
|
}
|
|
22
18
|
|
|
23
19
|
async init() {
|
|
@@ -3,7 +3,8 @@ class BLACKLISTED extends BTSensor{
|
|
|
3
3
|
static async identify(device){
|
|
4
4
|
if (await this.getManufacturerID(device)===0x004C) //apple devices use
|
|
5
5
|
return this //randomised macs and clog up our list
|
|
6
|
-
|
|
6
|
+
else
|
|
7
|
+
return null
|
|
7
8
|
}
|
|
8
9
|
async init(){
|
|
9
10
|
await super.init()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const BTSensor = require("../BTSensor");
|
|
2
|
+
function decodeTempHumid(tempHumidBytes) {
|
|
3
|
+
// Convert the bytes to a 24-bit integer
|
|
4
|
+
const baseNum = (tempHumidBytes[0] << 16) + (tempHumidBytes[1] << 8) + tempHumidBytes[2];
|
|
5
|
+
|
|
6
|
+
// Check if the temperature is negative
|
|
7
|
+
const isNegative = (baseNum & 0x800000) !== 0;
|
|
8
|
+
|
|
9
|
+
// Extract the temperature and humidity values
|
|
10
|
+
const tempAsInt = baseNum & 0x7FFFFF;
|
|
11
|
+
const tempAsFloat = (tempAsInt / 1000) / 10.0;
|
|
12
|
+
const humid = (tempAsInt % 1000) / 10.0;
|
|
13
|
+
|
|
14
|
+
// Apply the negative sign if necessary
|
|
15
|
+
if (isNegative) {
|
|
16
|
+
return {t:-tempAsFloat, h: humid};
|
|
17
|
+
} else {
|
|
18
|
+
return {t: tempAsFloat, h: humid};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
class GoveeTH extends BTSensor{
|
|
22
|
+
|
|
23
|
+
static async identify(device){
|
|
24
|
+
const regex = /^GVH5[0-9]{3}_[a-f,A-F,0-9]{4}$/
|
|
25
|
+
const name = await this.getDeviceProp(device,"Name")
|
|
26
|
+
const uuids = await this.getDeviceProp(device,'UUIDs')
|
|
27
|
+
|
|
28
|
+
if (name && name.match(regex) &&
|
|
29
|
+
uuids && uuids.length > 0 &&
|
|
30
|
+
uuids[0] == '0000ec88-0000-1000-8000-00805f9b34fb')
|
|
31
|
+
return this
|
|
32
|
+
else
|
|
33
|
+
return null
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async init(){
|
|
38
|
+
await super.init()
|
|
39
|
+
}
|
|
40
|
+
initMetadata(){
|
|
41
|
+
this.addMetadatum('temp','K', 'temperature')
|
|
42
|
+
this.addMetadatum('battery','ratio', 'battery strength')
|
|
43
|
+
this.addMetadatum('humidity','ratio', 'humidity')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
emitValuesFrom(buffer){
|
|
47
|
+
const th = decodeTempHumid(buffer.subarray(2,5))
|
|
48
|
+
this.emit("temp", parseFloat((273.15+th.t).toFixed(2))) ;
|
|
49
|
+
this.emit("humidity", th.h/100 )
|
|
50
|
+
this.emit('battery', buffer[5]/100)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getManufacturer(){
|
|
54
|
+
return "Govee"
|
|
55
|
+
}
|
|
56
|
+
async propertiesChanged(props){
|
|
57
|
+
super.propertiesChanged(props)
|
|
58
|
+
if (props.ManufacturerData) {
|
|
59
|
+
const buffer = this.getManufacturerData(0x0001)
|
|
60
|
+
if (buffer) {
|
|
61
|
+
this.emitValuesFrom(buffer)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
module.exports=GoveeTH
|
|
@@ -2,18 +2,15 @@ const BTSensor = require("../BTSensor");
|
|
|
2
2
|
|
|
3
3
|
class Inkbird extends BTSensor{
|
|
4
4
|
|
|
5
|
-
static async
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} catch (e){
|
|
13
|
-
this.debug(e)
|
|
5
|
+
static async identify(device){
|
|
6
|
+
|
|
7
|
+
const uuids = await this.getDeviceProp(device,'UUIDs')
|
|
8
|
+
const name = await this.getDeviceProp(device,"Name")
|
|
9
|
+
if ((name == 'tps' || name=='sps') && (uuids.length > 0 && uuids[0] == '0000fff0-0000-1000-8000-00805f9b34fb'))
|
|
10
|
+
return this
|
|
11
|
+
else
|
|
14
12
|
return null
|
|
15
|
-
|
|
16
|
-
return null
|
|
13
|
+
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
async init(){
|
|
@@ -243,19 +243,14 @@ class MopekaTankSensor extends BTSensor{
|
|
|
243
243
|
|
|
244
244
|
static manufacturerID = 0x0059
|
|
245
245
|
static async identify(device){
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
} catch (e){
|
|
256
|
-
this.debug.log(e)
|
|
257
|
-
}
|
|
258
|
-
return null
|
|
246
|
+
if (await this.getManufacturerID(device)==this.manufacturerID ){
|
|
247
|
+
const uuids = await this.getDeviceProp(device, 'UUIDs')
|
|
248
|
+
if (uuids && uuids.length>0 && uuids.includes(this.serviceID))
|
|
249
|
+
return this
|
|
250
|
+
else
|
|
251
|
+
return null
|
|
252
|
+
} else
|
|
253
|
+
return null
|
|
259
254
|
}
|
|
260
255
|
|
|
261
256
|
async init(){
|
|
@@ -287,7 +282,7 @@ class MopekaTankSensor extends BTSensor{
|
|
|
287
282
|
}).bind(this)
|
|
288
283
|
)
|
|
289
284
|
this.addMetadatum("battStrength","ratio","sensor battery strength",
|
|
290
|
-
(buffer)=>{ return Math.max(0, Math.min(
|
|
285
|
+
(buffer)=>{ return Math.max(0, Math.min(1, (((this.battVolt) - 2.2) / 0.65))) }
|
|
291
286
|
)
|
|
292
287
|
this.addMetadatum("temp","K","temperature",
|
|
293
288
|
((buffer)=>{
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
const BTSensor = require("../BTSensor");
|
|
2
2
|
class RuuviTag extends BTSensor{
|
|
3
3
|
static manufacturerID = 0x0499
|
|
4
|
-
static
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} catch (e){
|
|
9
|
-
console.log(e)
|
|
4
|
+
static async identify(device){
|
|
5
|
+
if (await this.getManufacturerID(device)==this.manufacturerID)
|
|
6
|
+
return this
|
|
7
|
+
else
|
|
10
8
|
return null
|
|
11
|
-
}
|
|
12
|
-
return null
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
async init(){
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
const BTSensor = require("../BTSensor");
|
|
2
2
|
class UltrasonicWindMeter extends BTSensor{
|
|
3
3
|
static async identify(device){
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} catch (e){
|
|
11
|
-
this.debug(e)
|
|
4
|
+
|
|
5
|
+
const uuids = await this.getDeviceProp(device,'UUIDs')
|
|
6
|
+
const name = await this.getDeviceProp(device,"Name")
|
|
7
|
+
if (name == 'ULTRASONIC')
|
|
8
|
+
return this
|
|
9
|
+
else
|
|
12
10
|
return null
|
|
13
|
-
}
|
|
14
|
-
return null
|
|
15
11
|
}
|
|
16
12
|
hasGATT(){
|
|
17
13
|
return true
|
|
18
14
|
}
|
|
19
|
-
|
|
15
|
+
emitGATT(){
|
|
20
16
|
this.battCharacteristic.readValue()
|
|
21
17
|
.then((buffer)=>
|
|
22
18
|
this.emitData("batt", buffer)
|
|
@@ -32,6 +28,17 @@ class UltrasonicWindMeter extends BTSensor{
|
|
|
32
28
|
)
|
|
33
29
|
|
|
34
30
|
}
|
|
31
|
+
async init(){
|
|
32
|
+
await super.init()
|
|
33
|
+
this.addMetadatum("batt","","Battery strength",
|
|
34
|
+
(buffer)=>{return buffer.readUInt8()})
|
|
35
|
+
this.addMetadatum("awa","","Apparent Wind Angle",
|
|
36
|
+
(buffer)=>{return buffer.readInt16LE()}
|
|
37
|
+
)
|
|
38
|
+
this.addMetadatum("aws","","Apparent Wind Speed",
|
|
39
|
+
(buffer)=>{return buffer.readInt16LE()}
|
|
40
|
+
)
|
|
41
|
+
}
|
|
35
42
|
|
|
36
43
|
initGATTConnection(){
|
|
37
44
|
return new Promise((resolve,reject )=>{ this.device.connect().then(async ()=>{
|
|
@@ -196,6 +196,7 @@ module.exports = {
|
|
|
196
196
|
0xA2A2: "Phoenix Inverter 24V 3000VA 230V",
|
|
197
197
|
0xA2A4: "Phoenix Inverter 48V 3000VA 230V",
|
|
198
198
|
0xA31A: "Blue Smart AC Charger IP67",
|
|
199
|
+
0xA33B: "Blue Smart AC Charger IP65",
|
|
199
200
|
0xA33C: "Blue Smart AC Charger IP65",
|
|
200
201
|
0xA340: "Phoenix Smart IP43 Charger 12|50 (1+1)",
|
|
201
202
|
0xA341: "Phoenix Smart IP43 Charger 12|50 (3)",
|
|
@@ -4,34 +4,57 @@ const int24 = require('int24')
|
|
|
4
4
|
const util = require('util')
|
|
5
5
|
const VC = require('./VictronConstants.js');
|
|
6
6
|
const BLACKLISTED = require("../BlackListedDevice.js");
|
|
7
|
-
|
|
7
|
+
const { resolve } = require("node:path");
|
|
8
|
+
const { setMaxIdleHTTPParsers } = require("node:http");
|
|
9
|
+
function sleep(x) {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
resolve(x);
|
|
13
|
+
}, x);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
8
16
|
class VictronSensor extends BTSensor{
|
|
9
17
|
|
|
10
18
|
constructor(device,config,gattConfig){
|
|
11
19
|
super(device,config,gattConfig)
|
|
12
20
|
this.encryptionKey = config?.encryptionKey
|
|
13
21
|
}
|
|
14
|
-
|
|
22
|
+
|
|
23
|
+
|
|
15
24
|
static async identifyMode(device, mode){
|
|
25
|
+
|
|
26
|
+
var md = await this.getDeviceProp(device,'ManufacturerData')
|
|
27
|
+
if (md==undefined || !Object.hasOwn(md,0x2e1))
|
|
28
|
+
return null
|
|
29
|
+
else {
|
|
30
|
+
|
|
31
|
+
if (md[0x2e1].value[0]==0x10) {
|
|
32
|
+
if (md[0x2e1].value[4]==mode)
|
|
33
|
+
return this
|
|
34
|
+
else
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
16
37
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
var hasDataPacket=false
|
|
39
|
+
device.helper._prepare()
|
|
40
|
+
device.helper.on("PropertiesChanged",
|
|
41
|
+
(props)=> {
|
|
42
|
+
if (Object.hasOwn(props,'ManufacturerData')){
|
|
43
|
+
md = props['ManufacturerData'].value
|
|
44
|
+
hasDataPacket=md[0x2e1].value[0]==0x10
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
while (!hasDataPacket) {
|
|
48
|
+
await sleep(500)
|
|
23
49
|
}
|
|
24
|
-
|
|
50
|
+
device.helper.removeListeners()
|
|
51
|
+
if (md[0x2e1].value[4]==mode)
|
|
25
52
|
return this
|
|
26
|
-
else
|
|
53
|
+
else
|
|
27
54
|
return null
|
|
28
|
-
|
|
29
|
-
} catch (e){
|
|
30
|
-
console.log(e)
|
|
31
|
-
return null
|
|
32
|
-
}
|
|
33
|
-
|
|
55
|
+
}
|
|
34
56
|
}
|
|
57
|
+
|
|
35
58
|
|
|
36
59
|
|
|
37
60
|
async init(){
|
|
@@ -79,9 +102,8 @@ const BLACKLISTED = require("../BlackListedDevice.js");
|
|
|
79
102
|
|
|
80
103
|
try{
|
|
81
104
|
const md = this.getManufacturerData(0x2e1)
|
|
82
|
-
if (md.length && md[0]==0x10){
|
|
83
|
-
const
|
|
84
|
-
const decData=this.decrypt(buff)
|
|
105
|
+
if (md && md.length && md[0]==0x10){
|
|
106
|
+
const decData=this.decrypt(md)
|
|
85
107
|
this.emitValuesFrom(decData)
|
|
86
108
|
}
|
|
87
109
|
}
|
|
@@ -20,7 +20,7 @@ Startbit Nr of bits Meaning Units Range NA value Remark
|
|
|
20
20
|
|
|
21
21
|
const VictronSensor = require ("./Victron/VictronSensor.js")
|
|
22
22
|
const VC = require("./Victron/VictronConstants.js")
|
|
23
|
-
const
|
|
23
|
+
const BitReader = require("./_BitReader")
|
|
24
24
|
|
|
25
25
|
class VictronACCharger extends VictronSensor{
|
|
26
26
|
|
|
@@ -38,29 +38,36 @@ class VictronACCharger extends VictronSensor{
|
|
|
38
38
|
this.addMetadatum('error','', 'error code',
|
|
39
39
|
(buff)=>{return VC.ChargerError.get(buff.readUInt8(1))})
|
|
40
40
|
|
|
41
|
-
this.addMetadatum('batt1','V', 'battery 1 voltage'
|
|
42
|
-
(buff)=>{return this.NaNif((buff.readUInt16LE(2)&0x1FFF), 0x1FFF)/100})
|
|
41
|
+
this.addMetadatum('batt1','V', 'battery 1 voltage')
|
|
43
42
|
|
|
44
|
-
this.addMetadatum('curr1','A', 'battery 1 current'
|
|
45
|
-
(buff)=>{return this.NaNif(buff.readUInt16BE(3)&0x7FF,0x7FF)/10})
|
|
43
|
+
this.addMetadatum('curr1','A', 'battery 1 current')
|
|
46
44
|
|
|
47
|
-
this.addMetadatum('batt2','V', 'battery 2 voltage'
|
|
48
|
-
(buff)=>{return this.NaNif((buff.readUInt16LE(5)&0x1FFF), 0x1FFF)/100})
|
|
45
|
+
this.addMetadatum('batt2','V', 'battery 2 voltage')
|
|
49
46
|
|
|
50
|
-
this.addMetadatum('curr2','A', 'battery 2 current'
|
|
51
|
-
(buff)=>{return this.NaNif(buff.readUInt16BE(7)&0x7FF,0x7FF)/10})
|
|
47
|
+
this.addMetadatum('curr2','A', 'battery 2 current')
|
|
52
48
|
|
|
53
|
-
this.addMetadatum('batt3','V', 'battery 3 voltage'
|
|
54
|
-
(buff)=>{return this.NaNif((buff.readUInt16LE(8)&0x1FFF), 0x1FFF)/100})
|
|
49
|
+
this.addMetadatum('batt3','V', 'battery 3 voltage')
|
|
55
50
|
|
|
56
|
-
this.addMetadatum('curr3','A', 'battery 3 current'
|
|
57
|
-
(buff)=>{return this.NaNif(buff.readUInt16BE(9)&0x7FF,0x7FF)/10})
|
|
51
|
+
this.addMetadatum('curr3','A', 'battery 3 current')
|
|
58
52
|
|
|
59
|
-
this.addMetadatum('temp', 'K', 'battery temperature'
|
|
60
|
-
(buff)=>{return this.NaNif(buff.readUInt8(11)&0x7F,0x7F)+233.15}) //-40 plus K conversion
|
|
53
|
+
this.addMetadatum('temp', 'K', 'battery temperature')
|
|
61
54
|
|
|
62
|
-
this.addMetadatum('acCurr','A', 'AC current'
|
|
63
|
-
|
|
55
|
+
this.addMetadatum('acCurr','A', 'AC current')
|
|
56
|
+
}
|
|
57
|
+
emitValuesFrom(buffer){
|
|
58
|
+
super.emitValuesFrom(buffer)
|
|
59
|
+
|
|
60
|
+
const br = new BitReader(buffer.subarray(2))
|
|
61
|
+
this.emit("batt1", this.NaNif(br.read_unsigned_int(13),0x1FFF)/100)
|
|
62
|
+
this.emit("curr1", this.NaNif(br.read_unsigned_int(11),0x7FF)/10)
|
|
63
|
+
|
|
64
|
+
this.emit("batt2", this.NaNif(br.read_unsigned_int(13),0x1FFF)/100)
|
|
65
|
+
this.emit("curr2", this.NaNif(br.read_unsigned_int(11),0x7FF)/10)
|
|
66
|
+
|
|
67
|
+
this.emit("batt3", this.NaNif(br.read_unsigned_int(13),0x1FFF)/100)
|
|
68
|
+
this.emit("curr3", this.NaNif(br.read_unsigned_int(11),0x7FF)/10)
|
|
69
|
+
this.emit("temp", this.NaNif(br.read_unsigned_int(7),0x7F)+233.15)
|
|
70
|
+
this.emit("acCurr", this.NaNif(br.read_unsigned_int(9),0x1FF)/10)
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
73
|
module.exports=VictronACCharger
|
|
@@ -9,6 +9,9 @@ class VictronDCDCConverter extends VictronSensor{
|
|
|
9
9
|
|
|
10
10
|
async init(){
|
|
11
11
|
await super.init()
|
|
12
|
+
this.initMetadata()
|
|
13
|
+
}
|
|
14
|
+
initMetadata(){
|
|
12
15
|
this.addMetadatum('deviceState','', 'device state',
|
|
13
16
|
(buff)=>{return VC.OperationMode.get(buff.readUInt8(0))})
|
|
14
17
|
this.addMetadatum('chargerError','', 'charger error',
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
|
|
1
2
|
const VictronSensor = require("./Victron/VictronSensor");
|
|
2
3
|
const VC=require("./Victron/VictronConstants.js")
|
|
3
|
-
|
|
4
|
+
const int24 = require("int24");
|
|
5
|
+
const _BitReader = require("./_BitReader.js");
|
|
4
6
|
class VictronDCEnergyMeter extends VictronSensor{
|
|
5
7
|
|
|
6
8
|
static async identify(device){
|
|
@@ -14,9 +16,11 @@ class VictronDCEnergyMeter extends VictronSensor{
|
|
|
14
16
|
(buff)=>{return buff.readInt16LE(2)/100})
|
|
15
17
|
this.addMetadatum('alarm','', 'alarm',
|
|
16
18
|
(buff)=>{return buff.readUInt16LE(4)})
|
|
17
|
-
this.
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
if (this.encryptionKey){
|
|
20
|
+
const decData = this.decrypt(this.getManufacturerData(0x02e1))
|
|
21
|
+
if (decData)
|
|
22
|
+
this.auxMode=decData.readInt8(8)&0x3
|
|
23
|
+
}
|
|
20
24
|
switch(this.auxMode){
|
|
21
25
|
case VC.AuxMode.STARTER_VOLTAGE:
|
|
22
26
|
this.addMetadatum('starterVoltage','V', 'starter battery voltage',
|
|
@@ -36,6 +40,8 @@ class VictronDCEnergyMeter extends VictronSensor{
|
|
|
36
40
|
default:
|
|
37
41
|
break
|
|
38
42
|
}
|
|
43
|
+
this.addMetadatum('current','A', 'current')
|
|
44
|
+
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
emitValuesFrom(decData){
|
|
@@ -56,8 +62,10 @@ class VictronDCEnergyMeter extends VictronSensor{
|
|
|
56
62
|
break;
|
|
57
63
|
default:
|
|
58
64
|
break
|
|
59
|
-
}
|
|
60
|
-
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.emit("current",
|
|
68
|
+
this.NaNif( new _BitReader(decData.subarray(8,11)).read_signed_int(22),0x3FFFFF)/1000)
|
|
61
69
|
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -28,16 +28,19 @@ TBD
|
|
|
28
28
|
|
|
29
29
|
async init() {
|
|
30
30
|
await super.init()
|
|
31
|
+
this.initMetadata()
|
|
32
|
+
}
|
|
33
|
+
initMetadata(){
|
|
31
34
|
this.addMetadatum('voltage','V', 'channel #1 voltage',
|
|
32
35
|
(buff)=>{return this.NaNif(buff.readInt16LE(0),0xFFFF)/100})
|
|
33
36
|
this.addMetadatum('pvPower','W','DC input power in watts',
|
|
34
|
-
(buff)=>{return this.NaNif(int24.
|
|
37
|
+
(buff)=>{return this.NaNif(int24.readInt24LE(buff,2)>>4,0xFFFFF)})
|
|
35
38
|
this.addMetadatum('soc','ratio', 'state of charge',
|
|
36
|
-
(buff)=>{ return ((buff.
|
|
39
|
+
(buff)=>{ return ((buff.readUInt16LE(4)&0xfff)>>5)/100})
|
|
37
40
|
this.addMetadatum('batteryPower','W', 'battery power',
|
|
38
|
-
(buff)=>{return (this.NaNif(int24.
|
|
41
|
+
(buff)=>{return (this.NaNif(int24.readInt24LE(buff,5)&0x1ffff),0x0FFFFF )})
|
|
39
42
|
this.addMetadatum('DCPower','W', 'DCpower',
|
|
40
|
-
(buff)=>{return this.NaNif(int24.
|
|
43
|
+
(buff)=>{return this.NaNif(int24.readInt24LE(buff,8)>>3,0x0FFFFF )})
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
module.exports=VictronGXDevice
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const VictronSensor = require("./Victron/VictronSensor");
|
|
2
2
|
const VC=require("./Victron/VictronConstants.js")
|
|
3
|
-
|
|
3
|
+
const BitReader = require('./_BitReader')
|
|
4
4
|
|
|
5
5
|
class VictronInverter extends VictronSensor{
|
|
6
6
|
static async identify(device){
|
|
@@ -9,6 +9,9 @@ class VictronInverter extends VictronSensor{
|
|
|
9
9
|
|
|
10
10
|
async init() {
|
|
11
11
|
await super.init()
|
|
12
|
+
this.initMetadata()
|
|
13
|
+
}
|
|
14
|
+
initMetadata(){
|
|
12
15
|
this.addMetadatum('deviceState','', 'inverter device state',
|
|
13
16
|
(buff)=>{return VC.OperationMode.get(buff.readIntU8(0))})
|
|
14
17
|
const md = this.addMetadatum('alarmReason','', 'reason for alarm',
|
|
@@ -19,17 +22,19 @@ class VictronInverter extends VictronSensor{
|
|
|
19
22
|
(buff)=>{return this.NaNif(buff.readInt16LE(3),0x7FFF)/100})
|
|
20
23
|
this.addMetadatum('acPower','W', 'AC power (in watts: Apparent Power * Power Factor)',
|
|
21
24
|
(buff)=>{return this.NaNif( buff.readUInt16LE(5), 0xFFFF )*this.powerFactor})
|
|
22
|
-
this.addMetadatum('acVoltage','V','AC Voltage'
|
|
23
|
-
|
|
24
|
-
this.addMetadatum('acCurrent','A', 'AC Current',
|
|
25
|
-
(buff)=>{return this.NaNif(((buff.readUInt32BE(5)&0x7ffff)>>6),0x7FF)/10}
|
|
26
|
-
)
|
|
25
|
+
this.addMetadatum('acVoltage','V','AC Voltage')
|
|
26
|
+
this.addMetadatum('acCurrent','A', 'AC Current')
|
|
27
27
|
|
|
28
28
|
}
|
|
29
29
|
powerFactor = .8 //parameterize anon
|
|
30
30
|
|
|
31
31
|
emitValuesFrom(decData){
|
|
32
32
|
super.emitValuesFrom(decData)
|
|
33
|
+
const br = new BitReader(decData.subarray(5))
|
|
34
|
+
this.emit('acVoltage',
|
|
35
|
+
this.NaNif(br.read_unsigned_int(15),0x7FFF)/100)
|
|
36
|
+
this.addMetadatum('acCurrent',
|
|
37
|
+
this.NaNif(br.read_unsigned_int(11),0x7FF)/10)
|
|
33
38
|
const alarm = this.getMetadatum("alarmReason").read(decData)
|
|
34
39
|
if (alarm>0){
|
|
35
40
|
this.emit(
|
|
@@ -15,8 +15,7 @@ Start Bit Nr of Bits Meaning Units Range NA Value Remark
|
|
|
15
15
|
|
|
16
16
|
const VictronSensor = require ("./Victron/VictronSensor.js")
|
|
17
17
|
const VC = require("./Victron/VictronConstants.js")
|
|
18
|
-
const
|
|
19
|
-
|
|
18
|
+
const BitReader = require("./_BitReader")
|
|
20
19
|
class VictronLynxSmartBMS extends VictronSensor{
|
|
21
20
|
|
|
22
21
|
static async identify(device){
|
|
@@ -25,6 +24,9 @@ class VictronLynxSmartBMS extends VictronSensor{
|
|
|
25
24
|
|
|
26
25
|
async init() {
|
|
27
26
|
await super.init()
|
|
27
|
+
this.initMetadata()
|
|
28
|
+
}
|
|
29
|
+
initMetadata(){
|
|
28
30
|
this.addMetadatum('error','', 'error code',
|
|
29
31
|
(buff)=>{return buff.readUInt8(0)})
|
|
30
32
|
|
|
@@ -35,15 +37,24 @@ class VictronLynxSmartBMS extends VictronSensor{
|
|
|
35
37
|
this.addMetadatum('current','A','channel 1 current',
|
|
36
38
|
(buff)=>{return this.NaNif(buff.readInt16LE(5),0x7FFF)/10})
|
|
37
39
|
this.addMetadatum('ioStatus','','IO Status', //TODO
|
|
38
|
-
(buff)=>{return buff.
|
|
39
|
-
this.addMetadatum('warningsAndAlarms','','warnings and alarms'
|
|
40
|
-
|
|
41
|
-
this.addMetadatum('
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
(buff)=>{return buff.readUInt16LE(7)})
|
|
41
|
+
this.addMetadatum('warningsAndAlarms','','warnings and alarms')
|
|
42
|
+
this.addMetadatum('soc','','state of charge')
|
|
43
|
+
this.addMetadatum('consumedAh','Ah','amp-hours consumed')
|
|
44
|
+
this.addMetadatum('temp', 'K', 'battery temperature')
|
|
45
|
+
}
|
|
46
|
+
emitValuesFrom(buffer){
|
|
47
|
+
super.emitValuesFrom(buffer)
|
|
48
|
+
const br = new BitReader(buffer.subarray(9))
|
|
49
|
+
|
|
50
|
+
this.emit('warningsAndAlarms',br.read_unsigned_int(18))
|
|
51
|
+
this.emit('soc',
|
|
52
|
+
this.NaNif((br.read_unsigned_int(10),0x3FF)/1000))
|
|
53
|
+
this.emit('consumedAh',
|
|
54
|
+
this.NaNif(br.read_unsigned_int(20),0xFFFFF)/10 )
|
|
55
|
+
this.emit('temp',
|
|
56
|
+
this.NaNif( br.read_unsigned_int(7),0x7f) +233.15)
|
|
57
|
+
|
|
47
58
|
}
|
|
48
59
|
}
|
|
49
60
|
module.exports=VictronLynxSmartBMS
|
|
@@ -25,6 +25,9 @@ class VictronSmartBatteryProtect extends VictronSensor{
|
|
|
25
25
|
|
|
26
26
|
async init() {
|
|
27
27
|
await super.init()
|
|
28
|
+
this.initMetadata()
|
|
29
|
+
}
|
|
30
|
+
initMetadata(){
|
|
28
31
|
this.addMetadatum('deviceState','', 'device state',
|
|
29
32
|
(buff)=>{return VC.OperationMode.get(buff.readUInt8(1))})
|
|
30
33
|
this.addMetadatum('outputStatus','', 'output status', //TODO
|
|
@@ -16,9 +16,13 @@ Start Bit Nr of Bits Meaning Units Range NA Value Remark
|
|
|
16
16
|
152 7 Battery temperature 1°C -40..86 °C 0x7F VE_REG_BAT_TEMPERATURE Temperature = Record value - 40
|
|
17
17
|
159 1 Unused
|
|
18
18
|
VE_REG_BATTERY_CELL_VOLTAGE 0x00 ( 0) when cell voltage < 2.61V 0x01 ( 1) when cell voltage == 2.61V 0x7D (125) when cell voltage == 3.85V 0x7E (126) when cell voltage > 3.85 0x7F (127) when cell voltage is not available / unknown
|
|
19
|
-
*/const VictronSensor = require ("./Victron/VictronSensor
|
|
20
|
-
const VC = require("./Victron/VictronConstants
|
|
19
|
+
*/const VictronSensor = require ("./Victron/VictronSensor")
|
|
20
|
+
const VC = require("./Victron/VictronConstants")
|
|
21
|
+
const BitReader = require("./_BitReader")
|
|
21
22
|
|
|
23
|
+
function _toCellVoltage(val){
|
|
24
|
+
return val==0x7F?NaN:2.6+(val/100)
|
|
25
|
+
}
|
|
22
26
|
class VictronSmartLithium extends VictronSensor{
|
|
23
27
|
|
|
24
28
|
static async identify(device){
|
|
@@ -30,36 +34,32 @@ class VictronSmartLithium extends VictronSensor{
|
|
|
30
34
|
this.initMetadata()
|
|
31
35
|
}
|
|
32
36
|
initMetadata(){
|
|
33
|
-
|
|
34
|
-
return val==0x7F?NaN:2.6+(val/100)
|
|
35
|
-
}
|
|
37
|
+
|
|
36
38
|
this.addMetadatum('bmsFlags','', 'BMS Flags',
|
|
37
|
-
(buff)=>{return buff.
|
|
39
|
+
(buff)=>{return buff.readUInt32LE(0)})
|
|
38
40
|
|
|
39
41
|
this.addMetadatum('smartLithiumErrors','', 'Smart Lithium Errors Flags',
|
|
40
|
-
(buff)=>{return buff.
|
|
41
|
-
this.addMetadatum('cell1Voltage','V', 'cell #1 voltage'
|
|
42
|
-
|
|
43
|
-
this.addMetadatum('
|
|
44
|
-
|
|
45
|
-
this.addMetadatum('
|
|
46
|
-
|
|
47
|
-
this.addMetadatum('
|
|
48
|
-
|
|
49
|
-
this.addMetadatum('cell5Voltage','V', 'cell #5 voltage',
|
|
50
|
-
(buff)=>{return _toCellVoltage(((buff.readUInt16BE(9))&0x0ffe)>>5)})
|
|
51
|
-
this.addMetadatum('cell6Voltage','V', 'cell #6 voltage',
|
|
52
|
-
(buff)=>{return _toCellVoltage(((buff.readUInt16BE(10))&0x1ffe)>>6)})
|
|
53
|
-
this.addMetadatum('cell7Voltage','V', 'cell #7 voltage',
|
|
54
|
-
(buff)=>{return _toCellVoltage(((buff.readUInt16BE(11))&0x3ffe)>>7)})
|
|
55
|
-
this.addMetadatum('cell8Voltage','V', 'cell #8 voltage',
|
|
56
|
-
(buff)=>{return _toCellVoltage((buff.readUInt8(12))&0x7e)})
|
|
42
|
+
(buff)=>{return buff.readUInt16LE(4)})
|
|
43
|
+
this.addMetadatum('cell1Voltage','V', 'cell #1 voltage')
|
|
44
|
+
this.addMetadatum('cell2Voltage','V', 'cell #2 voltage')
|
|
45
|
+
this.addMetadatum('cell3Voltage','V', 'cell #3 voltage')
|
|
46
|
+
this.addMetadatum('cell4Voltage','V', 'cell #4 voltage')
|
|
47
|
+
this.addMetadatum('cell5Voltage','V', 'cell #5 voltage')
|
|
48
|
+
this.addMetadatum('cell6Voltage','V', 'cell #6 voltage')
|
|
49
|
+
this.addMetadatum('cell7Voltage','V', 'cell #7 voltage')
|
|
50
|
+
this.addMetadatum('cell8Voltage','V', 'cell #8 voltage')
|
|
57
51
|
this.addMetadatum('batteryVoltage','V', 'battery voltage',
|
|
58
52
|
(buff)=>{return this.NaNif((buff.readUInt16LE(13)&0xFFF),0xFFF)/100})
|
|
59
53
|
this.addMetadatum('balancerStatus','', 'balancer status', //TODO
|
|
60
|
-
(buff)=>{return this.NaNif((buff.readUInt8(14)
|
|
54
|
+
(buff)=>{return this.NaNif((buff.readUInt8(14)>>4),0xF)})
|
|
61
55
|
this.addMetadatum('batteryTemp','K', 'battery temperature',
|
|
62
56
|
(buff)=>{return this.NaNif((buff.readUInt8(15)&0x7F),0x7F)+233.15})
|
|
63
57
|
}
|
|
58
|
+
emitValuesFrom(buffer){
|
|
59
|
+
super.emitValuesFrom(buffer)
|
|
60
|
+
const br = new BitReader(buffer.subarray(6,13))
|
|
61
|
+
for (let i = 1; i<8; i++)
|
|
62
|
+
this.emit(`cell${i+1}Voltage`,_toCellVoltage(br.read_unsigned_int(7)))
|
|
63
|
+
}
|
|
64
64
|
}
|
|
65
65
|
module.exports=VictronSmartLithium
|
|
@@ -24,7 +24,7 @@ class VictronSolarCharger extends VictronSensor{
|
|
|
24
24
|
this.addMetadatum('solarPower','W', 'solar power',
|
|
25
25
|
(buff)=>{return this.NaNif(buff.readUInt16LE(8),0xFFFF)})
|
|
26
26
|
this.addMetadatum('externalDeviceLoad','A', 'external device load',
|
|
27
|
-
(buff)=>{return this.NaNif(buff.
|
|
27
|
+
(buff)=>{return this.NaNif(buff.readUInt16LE(10)&0x1FF,0x1FF)/10})
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
module.exports=VictronSolarCharger
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const VictronSensor = require ("./Victron/VictronSensor.js")
|
|
2
2
|
const VC = require("./Victron/VictronConstants.js")
|
|
3
|
-
const
|
|
3
|
+
const BitReader = require("./_BitReader")
|
|
4
4
|
AC_IN_STATE=["AC in 1","AC in 2","NOT CONNECTED", "NA"]
|
|
5
5
|
ALARM_STATE=["None","warning", "alarm","NA"]
|
|
6
6
|
class VictronVEBus extends VictronSensor{
|
|
@@ -11,7 +11,9 @@ class VictronVEBus extends VictronSensor{
|
|
|
11
11
|
|
|
12
12
|
async init() {
|
|
13
13
|
await super.init()
|
|
14
|
-
|
|
14
|
+
this.initMetadata()
|
|
15
|
+
}
|
|
16
|
+
initMetadata(){
|
|
15
17
|
this.addMetadatum('chargeState','', 'charge state',
|
|
16
18
|
(buff)=>{return VC.OperationMode.get(buff.readUInt8(0))})
|
|
17
19
|
|
|
@@ -21,27 +23,44 @@ class VictronVEBus extends VictronSensor{
|
|
|
21
23
|
this.addMetadatum('current','A','charger battery current',
|
|
22
24
|
(buff)=>{return this.NaNif(buff.readInt16LE(2),0x7FFF)/10})
|
|
23
25
|
|
|
24
|
-
this.addMetadatum('voltage','V', 'charger battery voltage'
|
|
25
|
-
(buff)=>{return this.NaNif(buff.readUInt16LE(4) & 0x3FFF,0x3FFF)/100})
|
|
26
|
+
this.addMetadatum('voltage','V', 'charger battery voltage')
|
|
26
27
|
|
|
27
|
-
this.addMetadatum('acInState','', 'AC in state'
|
|
28
|
-
(buff)=>{return AC_IN_STATE[readUInt8(5)>>6]})
|
|
28
|
+
this.addMetadatum('acInState','', 'AC in state')
|
|
29
29
|
|
|
30
|
-
this.addMetadatum('acInPower','W','AC power IN in watts'
|
|
31
|
-
(buff)=>{return this.NaNif(int24.readInt24LE(buff,6)>>5,0x3FFFF)*(raw & 0x40000)?-1:1})
|
|
30
|
+
this.addMetadatum('acInPower','W','AC power IN in watts')
|
|
32
31
|
|
|
33
|
-
this.addMetadatum('acOutPower','W','AC power OUT in watts'
|
|
34
|
-
(buff)=>{return this.NaNif((int24.readInt24LE(buff,8) & 0x1FFFF) >> 2,0x3FFFF) * (raw & 0b1)?-1:1})
|
|
32
|
+
this.addMetadatum('acOutPower','W','AC power OUT in watts')
|
|
35
33
|
|
|
36
|
-
this.addMetadatum('alarm','','alarm state 0=no alarm, 1=warning, 2=alarm'
|
|
37
|
-
(buff)=>{return ALARM_STATE[buff.readUInt8(10)&0x3] })
|
|
34
|
+
this.addMetadatum('alarm','','alarm state 0=no alarm, 1=warning, 2=alarm')
|
|
38
35
|
|
|
39
|
-
this.addMetadatum('batteryTemperature','K', 'battery temperature'
|
|
40
|
-
(buff)=>{return this.NaNif((buff.readInt8(10)&0x1FF)>>1,0x7F) +233.15})
|
|
36
|
+
this.addMetadatum('batteryTemperature','K', 'battery temperature')
|
|
41
37
|
|
|
42
|
-
this.addMetadatum('soc', 'ratio', 'state of charge'
|
|
43
|
-
(buff)=>{return this.NaNif((buff.readInt16BE(10)&0x1FF)>>2,0x7F)/100})
|
|
38
|
+
this.addMetadatum('soc', 'ratio', 'state of charge')
|
|
44
39
|
|
|
45
40
|
}
|
|
41
|
+
emitValuesFrom(buffer){
|
|
42
|
+
super.emitValuesFrom(buffer)
|
|
43
|
+
const br = new BitReader(buffer.subarray(4))
|
|
44
|
+
this.emit('voltage',
|
|
45
|
+
this.NaNif(br.read_unsigned_int(14),0x3FFF)/100)
|
|
46
|
+
|
|
47
|
+
this.emit('acInState',
|
|
48
|
+
AC_IN_STATE[br.read_unsigned_int(2)])
|
|
49
|
+
|
|
50
|
+
this.emit('acInPower',
|
|
51
|
+
this.NaNif(br.read_signed_int(19),0x3FFFF))
|
|
52
|
+
|
|
53
|
+
this.emit('acOutPower',
|
|
54
|
+
this.NaNif(br.read_signed_int(19),0x3FFFF))
|
|
55
|
+
|
|
56
|
+
this.emit('alarm', ALARM_STATE[br.read_unsigned_int(2)])
|
|
57
|
+
|
|
58
|
+
this.emit('batteryTemperature',
|
|
59
|
+
this.NaNif((br.read_unsigned_int(7),0x7F))+233.15)
|
|
60
|
+
|
|
61
|
+
this.emit('soc',
|
|
62
|
+
this.NaNif((br.read_unsigned_int(7),0x7F))/100)
|
|
63
|
+
|
|
64
|
+
}
|
|
46
65
|
}
|
|
47
66
|
module.exports=VictronVEBus
|
|
@@ -80,16 +80,16 @@ class XiaomiMiBeacon extends BTSensor{
|
|
|
80
80
|
static SERVICE_MIBEACON = "0000fe95-0000-1000-8000-00805f9b34fb"
|
|
81
81
|
|
|
82
82
|
static async identify(device){
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (sd == null || sd.length==0) return null
|
|
86
|
-
const keys = Object.keys(sd)
|
|
87
|
-
if (keys[0]==this.SERVICE_MIBEACON) return this
|
|
88
|
-
} catch (e){
|
|
89
|
-
console.log(e)
|
|
83
|
+
var sd = await this.getDeviceProp(device, 'ServiceData')
|
|
84
|
+
if (sd == null || sd.length==0)
|
|
90
85
|
return null
|
|
86
|
+
else{
|
|
87
|
+
const keys = Object.keys(sd)
|
|
88
|
+
if (keys[0]==this.SERVICE_MIBEACON)
|
|
89
|
+
return this
|
|
90
|
+
else
|
|
91
|
+
return null
|
|
91
92
|
}
|
|
92
|
-
return null
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
GATTwarning = "WARNING: Xiaomi GATT connections are known to be unreliable on Debian distributions with Bluez 5.55 and up (earlier BlueZ versions are untested). Using GATT on the Xiaomi may put the system Bluetooth stack into an inconsistent state disrupting and disabling other plugin Bluetooth connections. If by some chance you're successful using GATT with the Xiaomi, let the plugin developer know your configuration. Refer to the plugin documentation for getting the Xiamoi bindKey for non-GATT connections and more information on Xiaomi GATT issues."
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Ported from Python original by Keshav Varma https://github.com/keshavdv
|
|
3
|
+
*/
|
|
4
|
+
class _BitReader{
|
|
5
|
+
constructor( data){
|
|
6
|
+
this._data = data
|
|
7
|
+
this._index = 0
|
|
8
|
+
}
|
|
9
|
+
read_bit(){
|
|
10
|
+
const bit = (this._data[this._index >> 3] >> (this._index & 7)) & 1
|
|
11
|
+
this._index++
|
|
12
|
+
return bit
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
read_unsigned_int(num_bits){
|
|
16
|
+
var value =''
|
|
17
|
+
for (let i = 0; i < num_bits; i++)
|
|
18
|
+
value = this.read_bit().toString()+value
|
|
19
|
+
return parseInt(value,2)
|
|
20
|
+
}
|
|
21
|
+
read_signed_int(num_bits){
|
|
22
|
+
const value = this.read_unsigned_int(num_bits)
|
|
23
|
+
return value & (1 << (num_bits - 1))?value - (1 << num_bits):value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports=_BitReader
|