@rhizomatics/signalk-bluetti-plugin 1.4.1 → 1.5.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +40 -4
  3. package/cli.js +71 -11
  4. package/devices/ac180.yaml +58 -0
  5. package/devices/ac180p.yaml +34 -0
  6. package/devices/ac180t.yaml +58 -0
  7. package/devices/ac200l.yaml +48 -0
  8. package/devices/ac200m.yaml +48 -0
  9. package/devices/ac200p.yaml +89 -0
  10. package/devices/ac200pl.yaml +48 -0
  11. package/devices/ac2a.yaml +34 -0
  12. package/devices/ac2p.yaml +34 -0
  13. package/devices/ac300.yaml +57 -0
  14. package/devices/ac500.yaml +56 -0
  15. package/devices/ac50b.yaml +31 -0
  16. package/devices/ac60.yaml +33 -0
  17. package/devices/ac60p.yaml +33 -0
  18. package/devices/ac70.yaml +62 -0
  19. package/devices/ac70p.yaml +58 -0
  20. package/devices/ap300.yaml +34 -0
  21. package/devices/eb3a.yaml +41 -0
  22. package/devices/el100v2.yaml +43 -0
  23. package/devices/el30v2.yaml +38 -0
  24. package/devices/ep2000.yaml +75 -0
  25. package/devices/ep500.yaml +57 -0
  26. package/devices/ep500p.yaml +57 -0
  27. package/devices/ep600.yaml +151 -0
  28. package/devices/ep760.yaml +72 -0
  29. package/devices/ep800.yaml +21 -0
  30. package/devices/handsfree1.yaml +62 -0
  31. package/devices/pr100v2.yaml +34 -0
  32. package/devices/pr30v2.yaml +34 -0
  33. package/docs/assets/icon.svg +36 -0
  34. package/docs/assets/screenshots/bluetti_data.png +0 -0
  35. package/docs/examples/model_definition.yaml +112 -0
  36. package/index.js +75 -32
  37. package/lib/path-mapper.js +51 -9
  38. package/lib/register-loader.js +120 -0
  39. package/lib/scanner.js +1 -1
  40. package/package.json +13 -6
  41. package/lib/csv-loader.js +0 -160
  42. package/registers/ac200p.csv +0 -47
  43. package/registers/el100v2.csv +0 -27
@@ -0,0 +1,57 @@
1
+ # Bluetti EP500P register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/ep500p.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ battery_soc:
16
+ register: 43
17
+ unit: "%"
18
+ dc_input_power:
19
+ register: 36
20
+ unit: W
21
+ ac_input_power:
22
+ register: 37
23
+ unit: W
24
+ ac_output_power:
25
+ register: 38
26
+ unit: W
27
+ dc_output_power:
28
+ register: 39
29
+ unit: W
30
+ ac_output_voltage:
31
+ register: 71
32
+ scale: 0.1
33
+ unit: V
34
+ ac_output_frequency:
35
+ register: 74
36
+ scale: 0.01
37
+ unit: Hz
38
+ ac_input_voltage:
39
+ register: 77
40
+ scale: 0.1
41
+ unit: V
42
+ ac_input_frequency:
43
+ register: 80
44
+ scale: 0.01
45
+ unit: Hz
46
+ dc_input_voltage:
47
+ register: 86
48
+ scale: 0.1
49
+ unit: V
50
+ dc_input_current:
51
+ register: 88
52
+ scale: 0.1
53
+ unit: A
54
+ constants:
55
+ battery_chemistry: LiFePO4
56
+ battery_manufacturer_name: Bluetti
57
+ battery_manufacturer_model: EP500P
@@ -0,0 +1,151 @@
1
+ # Bluetti EP600 register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/ep600.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ battery_soc:
16
+ register: 102
17
+ unit: "%"
18
+ power_generation:
19
+ register: 1202
20
+ scale: 0.1
21
+ unit: kWh
22
+ dc_input_power:
23
+ register: 1212
24
+ unit: W
25
+ dc_input_voltage:
26
+ register: 1213
27
+ scale: 0.1
28
+ unit: V
29
+ dc_input_current:
30
+ register: 1214
31
+ scale: 0.1
32
+ unit: A
33
+ pv_s2_power:
34
+ register: 1220
35
+ unit: W
36
+ pv_s2_voltage:
37
+ register: 1221
38
+ scale: 0.1
39
+ unit: V
40
+ pv_s2_current:
41
+ register: 1222
42
+ scale: 0.1
43
+ unit: A
44
+ sm_p1_power:
45
+ register: 1228
46
+ unit: W
47
+ sm_p1_voltage:
48
+ register: 1229
49
+ scale: 0.1
50
+ unit: V
51
+ sm_p1_current:
52
+ register: 1230
53
+ unit: A
54
+ sm_p2_power:
55
+ register: 1236
56
+ unit: W
57
+ sm_p2_voltage:
58
+ register: 1237
59
+ scale: 0.1
60
+ unit: V
61
+ sm_p2_current:
62
+ register: 1238
63
+ unit: A
64
+ sm_p3_power:
65
+ register: 1244
66
+ unit: W
67
+ sm_p3_voltage:
68
+ register: 1245
69
+ scale: 0.1
70
+ unit: V
71
+ sm_p3_current:
72
+ register: 1246
73
+ unit: A
74
+ grid_frequency:
75
+ register: 1300
76
+ scale: 0.1
77
+ unit: Hz
78
+ grid_p1_power:
79
+ register: 1313
80
+ unit: W
81
+ grid_p1_voltage:
82
+ register: 1314
83
+ scale: 0.1
84
+ unit: V
85
+ grid_p1_current:
86
+ register: 1315
87
+ scale: 0.1
88
+ unit: A
89
+ grid_p2_power:
90
+ register: 1319
91
+ unit: W
92
+ grid_p2_voltage:
93
+ register: 1320
94
+ scale: 0.1
95
+ unit: V
96
+ grid_p2_current:
97
+ register: 1321
98
+ scale: 0.1
99
+ unit: A
100
+ grid_p3_power:
101
+ register: 1325
102
+ unit: W
103
+ grid_p3_voltage:
104
+ register: 1326
105
+ scale: 0.1
106
+ unit: V
107
+ grid_p3_current:
108
+ register: 1327
109
+ scale: 0.1
110
+ unit: A
111
+ ac_output_frequency:
112
+ register: 1500
113
+ scale: 0.1
114
+ unit: Hz
115
+ ac_p1_power:
116
+ register: 1510
117
+ unit: W
118
+ ac_p1_voltage:
119
+ register: 1511
120
+ scale: 0.1
121
+ unit: V
122
+ ac_p1_current:
123
+ register: 1512
124
+ scale: 0.1
125
+ unit: A
126
+ ac_p2_power:
127
+ register: 1517
128
+ unit: W
129
+ ac_p2_voltage:
130
+ register: 1518
131
+ scale: 0.1
132
+ unit: V
133
+ ac_p2_current:
134
+ register: 1519
135
+ scale: 0.1
136
+ unit: A
137
+ ac_p3_power:
138
+ register: 1524
139
+ unit: W
140
+ ac_p3_voltage:
141
+ register: 1525
142
+ scale: 0.1
143
+ unit: V
144
+ ac_p3_current:
145
+ register: 1526
146
+ scale: 0.1
147
+ unit: A
148
+ constants:
149
+ battery_chemistry: LiFePO4
150
+ battery_manufacturer_name: Bluetti
151
+ battery_manufacturer_model: EP600
@@ -0,0 +1,72 @@
1
+ # Bluetti EP760 register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/ep760.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ battery_soc:
16
+ register: 102
17
+ unit: "%"
18
+ dc_input_power:
19
+ register: 1212
20
+ unit: W
21
+ dc_input_voltage:
22
+ register: 1213
23
+ scale: 0.1
24
+ unit: V
25
+ dc_input_current:
26
+ register: 1214
27
+ scale: 0.1
28
+ unit: A
29
+ sm_p1_power:
30
+ register: 1228
31
+ unit: W
32
+ sm_p1_voltage:
33
+ register: 1229
34
+ scale: 0.1
35
+ unit: V
36
+ sm_p1_current:
37
+ register: 1230
38
+ unit: A
39
+ ac_input_frequency:
40
+ register: 1300
41
+ scale: 0.1
42
+ unit: Hz
43
+ ac_input_power:
44
+ register: 1313
45
+ unit: W
46
+ ac_input_voltage:
47
+ register: 1314
48
+ scale: 0.1
49
+ unit: V
50
+ ac_input_current:
51
+ register: 1315
52
+ scale: 0.1
53
+ unit: A
54
+ ac_output_frequency:
55
+ register: 1500
56
+ scale: 0.1
57
+ unit: Hz
58
+ ac_output_power:
59
+ register: 1510
60
+ unit: W
61
+ ac_output_voltage:
62
+ register: 1511
63
+ scale: 0.1
64
+ unit: V
65
+ ac_output_current:
66
+ register: 1512
67
+ scale: 0.1
68
+ unit: A
69
+ constants:
70
+ battery_chemistry: LiFePO4
71
+ battery_manufacturer_name: Bluetti
72
+ battery_manufacturer_model: EP760
@@ -0,0 +1,21 @@
1
+ # Bluetti EP800 register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/ep800.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ battery_soc:
16
+ register: 102
17
+ unit: "%"
18
+ constants:
19
+ battery_chemistry: LiFePO4
20
+ battery_manufacturer_name: Bluetti
21
+ battery_manufacturer_model: EP800
@@ -0,0 +1,62 @@
1
+ # Bluetti HANDSFREE1 register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/handsfree1.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ dc_output_power:
16
+ register: 140
17
+ unit: W
18
+ ac_output_power:
19
+ register: 142
20
+ unit: W
21
+ dc_input_power:
22
+ register: 144
23
+ unit: W
24
+ ac_input_power:
25
+ register: 146
26
+ unit: W
27
+ time_remaining_minutes:
28
+ register: 104
29
+ scale: 6
30
+ unit: min
31
+ dc_input_voltage:
32
+ register: 1213
33
+ scale: 0.1
34
+ unit: V
35
+ dc_input_current:
36
+ register: 1214
37
+ scale: 0.1
38
+ unit: A
39
+ ac_input_frequency:
40
+ register: 1300
41
+ scale: 0.1
42
+ unit: Hz
43
+ ac_input_voltage:
44
+ register: 1314
45
+ scale: 0.1
46
+ unit: V
47
+ ac_input_current:
48
+ register: 1315
49
+ scale: 0.1
50
+ unit: A
51
+ ac_output_frequency:
52
+ register: 1500
53
+ scale: 0.1
54
+ unit: Hz
55
+ ac_output_voltage:
56
+ register: 1511
57
+ scale: 0.1
58
+ unit: V
59
+ constants:
60
+ battery_chemistry: LiFePO4
61
+ battery_manufacturer_name: Bluetti
62
+ battery_manufacturer_model: Handsfree 1
@@ -0,0 +1,34 @@
1
+ # Bluetti PR100V2 register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/pr100v2.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ dc_output_power:
16
+ register: 140
17
+ unit: W
18
+ ac_output_power:
19
+ register: 142
20
+ unit: W
21
+ dc_input_power:
22
+ register: 144
23
+ unit: W
24
+ ac_input_power:
25
+ register: 146
26
+ unit: W
27
+ ac_input_voltage:
28
+ register: 1314
29
+ scale: 0.1
30
+ unit: V
31
+ constants:
32
+ battery_chemistry: LiFePO4
33
+ battery_manufacturer_name: Bluetti
34
+ battery_manufacturer_model: PR100 V2
@@ -0,0 +1,34 @@
1
+ # Bluetti PR30V2 register map
2
+ # Source: https://github.com/Patrick762/bluetti-bt-lib (bluetti_bt_lib/devices/pr30v2.py)
3
+ #
4
+ # field_name is a standard Bluetti register name — the code maps these to
5
+ # SignalK paths on its own (see lib/path-mapper.js). `path` on a field is an
6
+ # override, only needed if you're exposing a register the code doesn't
7
+ # recognise. `constants` are fixed, non-register facts about this model —
8
+ # a bare scalar (string/number) or { value, unit } for one that needs unit
9
+ # conversion (e.g. total_capacity in Wh -> J). No verified nominal capacity
10
+ # is bundled for most models — add a total_capacity constant yourself if you
11
+ # know it, to enable the derived remaining-capacity calculation.
12
+ #
13
+
14
+ fields:
15
+ dc_output_power:
16
+ register: 140
17
+ unit: W
18
+ ac_output_power:
19
+ register: 142
20
+ unit: W
21
+ dc_input_power:
22
+ register: 144
23
+ unit: W
24
+ ac_input_power:
25
+ register: 146
26
+ unit: W
27
+ ac_input_voltage:
28
+ register: 1314
29
+ scale: 0.1
30
+ unit: V
31
+ constants:
32
+ battery_chemistry: LiFePO4
33
+ battery_manufacturer_name: Bluetti
34
+ battery_manufacturer_model: PR30 V2
@@ -0,0 +1,36 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
4
+ <stop offset="0" stop-color="#0f4c5c"/>
5
+ <stop offset="1" stop-color="#093542"/>
6
+ </linearGradient>
7
+ <linearGradient id="body" x1="0" y1="0" x2="0" y2="1">
8
+ <stop offset="0" stop-color="#f4f6f7"/>
9
+ <stop offset="1" stop-color="#d7dde0"/>
10
+ </linearGradient>
11
+ </defs>
12
+
13
+ <!-- app icon background -->
14
+ <rect x="0" y="0" width="256" height="256" rx="48" fill="url(#bg)"/>
15
+
16
+ <!-- power station body -->
17
+ <rect x="56" y="58" width="144" height="132" rx="14" fill="url(#body)" stroke="#093542" stroke-width="4"/>
18
+
19
+ <!-- display -->
20
+ <rect x="74" y="74" width="56" height="34" rx="6" fill="#0f4c5c"/>
21
+ <!-- battery glyph inside display -->
22
+ <rect x="82" y="85" width="30" height="12" rx="2" fill="none" stroke="#7fd8c4" stroke-width="2.5"/>
23
+ <rect x="113" y="88.5" width="4" height="5" fill="#7fd8c4"/>
24
+ <rect x="85" y="88" width="18" height="6" fill="#7fd8c4"/>
25
+
26
+ <!-- lightning bolt -->
27
+ <path d="M156 72 L138 104 h14 l-6 30 26 -38 h-15 z" fill="#f4a340" stroke="#093542" stroke-width="3" stroke-linejoin="round"/>
28
+
29
+ <!-- ports along the bottom edge -->
30
+ <circle cx="80" cy="166" r="10" fill="none" stroke="#093542" stroke-width="4"/>
31
+ <circle cx="80" cy="166" r="3.5" fill="#093542"/>
32
+ <rect x="106" y="158" width="20" height="16" rx="3" fill="none" stroke="#093542" stroke-width="4"/>
33
+ <rect x="142" y="156" width="26" height="20" rx="3" fill="none" stroke="#093542" stroke-width="4"/>
34
+ <rect x="150" y="162" width="3.5" height="8" fill="#093542"/>
35
+ <rect x="157" y="162" width="3.5" height="8" fill="#093542"/>
36
+ </svg>
@@ -0,0 +1,112 @@
1
+ # Example register map for a Bluetti device this plugin doesn't bundle yet.
2
+ #
3
+ # Drop a copy of this file (renamed, e.g. my-device.yaml) into your custom
4
+ # register maps directory — see the plugin's "Custom register maps directory"
5
+ # setting, which defaults to <SignalK home>/bluetti (e.g. ~/.signalk/bluetti)
6
+ # — and it'll show up in the "Register map" dropdown for a device, keyed by
7
+ # its filename (without .yaml).
8
+ #
9
+ # Two top-level keys:
10
+ #
11
+ # fields: one entry per live Modbus holding register on the device.
12
+ # The key is the field name; standard names (see lib/path-mapper.js's
13
+ # STANDARD_FIELD_PATHS) are resolved to a SignalK path automatically —
14
+ # use whichever of these match what your device actually reports.
15
+ # Any other name gets a best-effort guess, or set `path:` explicitly.
16
+ #
17
+ # <field_name>:
18
+ # register: <number> # Modbus holding register address (required)
19
+ # type: uint16 # uint16 (default) | int16 | uint32 | int32 | float32 | bool
20
+ # count: <number> # registers this field spans; inferred from `type` if omitted
21
+ # scale: <number> # multiply the raw value by this (default 1)
22
+ # offset: <number> # add after scaling (default 0)
23
+ # unit: V # V | A | W | Wh | kWh | % | °C | Hz | min — drives SignalK unit conversion
24
+ # path: electrical.batteries.{name}.voltage # optional override; {name} is the per-device name from config
25
+ #
26
+ # constants: fixed, non-register facts about this model — a bare scalar
27
+ # (string or number) or, for a number that needs unit conversion
28
+ # (e.g. a capacity in Wh), an expanded { value, unit } form.
29
+ #
30
+ # Standard field names worth knowing: battery_soc, battery_voltage,
31
+ # battery_current, battery_power, battery_temperature, dc_input_power/voltage/current
32
+ # (solar), ac_output_power/voltage/current/frequency (inverter), ac_input_power/
33
+ # voltage/current/frequency (mains charger), time_remaining_minutes,
34
+ # total_capacity, battery_chemistry, battery_manufacturer_name, battery_manufacturer_model.
35
+
36
+ fields:
37
+ battery_percent:
38
+ register: 100
39
+ unit: "%"
40
+ battery_voltage:
41
+ register: 101
42
+ scale: 0.1
43
+ unit: V
44
+ battery_current:
45
+ register: 102
46
+ type: int16
47
+ scale: 0.1
48
+ unit: A
49
+ battery_power:
50
+ register: 103
51
+ type: int16
52
+ unit: W
53
+ battery_temperature:
54
+ register: 104
55
+ scale: 0.1
56
+ unit: "°C"
57
+ dc_input_power:
58
+ register: 107
59
+ unit: W
60
+ dc_input_voltage:
61
+ register: 108
62
+ scale: 0.1
63
+ unit: V
64
+ dc_input_current:
65
+ register: 109
66
+ scale: 0.1
67
+ unit: A
68
+ ac_output_power:
69
+ register: 110
70
+ unit: W
71
+ ac_output_voltage:
72
+ register: 111
73
+ scale: 0.1
74
+ unit: V
75
+ ac_output_current:
76
+ register: 112
77
+ scale: 0.1
78
+ unit: A
79
+ ac_output_frequency:
80
+ register: 113
81
+ scale: 0.1
82
+ unit: Hz
83
+ ac_input_power:
84
+ register: 114
85
+ unit: W
86
+ ac_input_voltage:
87
+ register: 115
88
+ scale: 0.1
89
+ unit: V
90
+ ac_input_current:
91
+ register: 116
92
+ scale: 0.1
93
+ unit: A
94
+ ac_input_frequency:
95
+ register: 117
96
+ scale: 0.1
97
+ unit: Hz
98
+ internal_temperature:
99
+ register: 118
100
+ scale: 0.1
101
+ unit: "°C"
102
+ time_remaining_minutes:
103
+ register: 119
104
+ unit: min
105
+
106
+ constants:
107
+ battery_chemistry: LiFePO4
108
+ battery_manufacturer_name: Bluetti
109
+ battery_manufacturer_model: My Device
110
+ total_capacity:
111
+ value: 2000
112
+ unit: Wh