bluetti-modbus 0.1.0__tar.gz
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.
- bluetti_modbus-0.1.0/LICENSE +21 -0
- bluetti_modbus-0.1.0/PKG-INFO +141 -0
- bluetti_modbus-0.1.0/README.md +122 -0
- bluetti_modbus-0.1.0/pyproject.toml +56 -0
- bluetti_modbus-0.1.0/setup.cfg +4 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus.egg-info/PKG-INFO +141 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus.egg-info/SOURCES.txt +32 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus.egg-info/dependency_links.txt +1 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus.egg-info/entry_points.txt +2 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus.egg-info/requires.txt +4 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus.egg-info/top_level.txt +1 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/__init__.py +2 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/base_devices/__init__.py +1 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/base_devices/bluetti_device.py +18 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/devices/__init__.py +4 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/devices/balco260.py +259 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/devices/ep2000.py +219 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/devices/getter.py +25 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/devices/smeter.py +157 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/enums/__init__.py +3 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/enums/inverter_fault.py +6 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/enums/inverter_status.py +13 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/enums/inverter_warning.py +6 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/fields/__init__.py +1 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/fields/custom_fields.py +108 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/modbus/__init__.py +1 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/modbus/client.py +69 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/py.typed +0 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/scripts/__init__.py +0 -0
- bluetti_modbus-0.1.0/src/bluetti_modbus_lib/scripts/bluetti_modread.py +35 -0
- bluetti_modbus-0.1.0/tests/test_base_devices.py +21 -0
- bluetti_modbus-0.1.0/tests/test_client.py +145 -0
- bluetti_modbus-0.1.0/tests/test_custom_fields.py +64 -0
- bluetti_modbus-0.1.0/tests/test_getter.py +18 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Patrick762
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bluetti-modbus
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial library for basic communication to Bluetti Power Stations via Modbus
|
|
5
|
+
Author: Patrick762, bluetti-community
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bluetti-community/bluetti-modbus-lib
|
|
8
|
+
Keywords: modbus,bluetti,home-assistant
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.13
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: modbus-connection>=4.10.0
|
|
16
|
+
Provides-Extra: cli
|
|
17
|
+
Requires-Dist: modbus-connection[pymodbus]>=4.10.0; extra == "cli"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# bluetti-modbus-lib
|
|
21
|
+
Unofficial library for basic communication to Bluetti Power Stations via Modbus.
|
|
22
|
+
|
|
23
|
+
Based on official documentation https://github.com/bluetti-official/bluetti-modbus-tcp-slave
|
|
24
|
+
|
|
25
|
+
You have to enable Modbus TCP in the webinterface of your device first.
|
|
26
|
+
|
|
27
|
+
## Relationship to Patrick762's `bluetti-modbus-lib`
|
|
28
|
+
|
|
29
|
+
This repository started as a fork of
|
|
30
|
+
[Patrick762/bluetti-modbus-lib](https://github.com/Patrick762/bluetti-modbus-lib)
|
|
31
|
+
and has since diverged significantly (packaging, testing, retry handling,
|
|
32
|
+
device coverage). Patrick762 is still actively maintaining his own version
|
|
33
|
+
independently and was asked directly whether he'd like to fold this work
|
|
34
|
+
back into his project or join `bluetti-community` - he's not in a position
|
|
35
|
+
to commit the time to that right now, which is completely fine.
|
|
36
|
+
|
|
37
|
+
Since the PyPI name `bluetti-modbus-lib` is his and still actively used,
|
|
38
|
+
this project is published on PyPI under a different name, **`bluetti-modbus`**,
|
|
39
|
+
to avoid any ambiguity between the two. The GitHub repository itself keeps
|
|
40
|
+
its original name.
|
|
41
|
+
|
|
42
|
+
## Disclaimer
|
|
43
|
+
This library is provided without any warranty or support by Bluetti. I do not take responsibility for any problems it may cause in all cases. Use it at your own risk.
|
|
44
|
+
|
|
45
|
+
## Supported devices and data
|
|
46
|
+
|
|
47
|
+
- Balco260
|
|
48
|
+
- EP2000
|
|
49
|
+
- SMeter (Bluetti's AC meter/CT device - untested against real hardware so far)
|
|
50
|
+
|
|
51
|
+
Field names, units, and Modbus registers come from
|
|
52
|
+
[bluetti-registers](https://github.com/bluetti-community/bluetti-registers) -
|
|
53
|
+
`devices/balco260.py`, `devices/ep2000.py`, and `devices/smeter.py` in this
|
|
54
|
+
repo are generated from it by `import.py`, not written by hand.
|
|
55
|
+
|
|
56
|
+
## Architecture
|
|
57
|
+
|
|
58
|
+
This library does not create or own a Modbus transport itself. It's built on
|
|
59
|
+
[modbus-connection](https://pypi.org/project/modbus-connection/)'s
|
|
60
|
+
device-modelling framework: `Balco260`, `EP2000`, and `SMeter`
|
|
61
|
+
(`bluetti_modbus_lib.devices`) each take a `ModbusUnit` supplied by the
|
|
62
|
+
caller, built from whichever backend and connection the caller already
|
|
63
|
+
manages. That's the integration surface for embedding this library into
|
|
64
|
+
another application (a Home Assistant integration, for example).
|
|
65
|
+
|
|
66
|
+
`BluettiModbusClient` (`bluetti_modbus_lib.modbus.client`) is different: it
|
|
67
|
+
owns and manages its own connection. It exists for the `bluetti-modread` CLI
|
|
68
|
+
below and standalone/manual use, not as something another application should
|
|
69
|
+
build on - doing so would open a second, competing connection to the device
|
|
70
|
+
instead of sharing one.
|
|
71
|
+
|
|
72
|
+
Field metadata is deliberately limited to what's true at the Modbus/protocol
|
|
73
|
+
level - address, type, scale, unit, whether it's writable. It does not carry
|
|
74
|
+
Home Assistant concepts like entity category, state class, or device class:
|
|
75
|
+
those describe how a value should be presented in an HA UI, not anything
|
|
76
|
+
about the register itself, and belong in whichever integration consumes this
|
|
77
|
+
library, not in the library.
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install bluetti-modbus
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Installing `bluetti-modbus` alone only pulls in `modbus-connection`'s
|
|
86
|
+
backend-neutral interface - enough to use the device classes directly against
|
|
87
|
+
a `ModbusUnit` you already have. The `bluetti-modread` CLI needs a concrete
|
|
88
|
+
backend, installed via the `cli` extra:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install "bluetti-modbus[cli]"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Sponsoring
|
|
95
|
+
|
|
96
|
+
If you want to support this project, you can sponsor [Patrick762 on GitHub](https://github.com/sponsors/Patrick762), the original author.
|
|
97
|
+
|
|
98
|
+
## Commands for testing
|
|
99
|
+
|
|
100
|
+
Commands included in this library should only be used for testing.
|
|
101
|
+
|
|
102
|
+
### Read device data for supported devices
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
usage: bluetti-modread [-h] [-c HOST] [-p PORT] [-t TYPE]
|
|
106
|
+
|
|
107
|
+
Read bluetti devices via modbus
|
|
108
|
+
|
|
109
|
+
options:
|
|
110
|
+
-h, --help show this help message and exit
|
|
111
|
+
-c HOST, --host HOST IP-address of the device
|
|
112
|
+
-p PORT, --port PORT Port of the device
|
|
113
|
+
-t TYPE, --type TYPE Device type
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
bluetti-modread -c 10.2.1.60 -p 502 -t balco260
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Example output, captured from a real Balco260 (truncated - `bluetti-modread` prints one line per field):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
d_num_inverters: 1
|
|
126
|
+
ac_o_p_total: 84 W
|
|
127
|
+
pv_i_p_total: 0 W
|
|
128
|
+
ac_o_e_total: 64.7 kWh
|
|
129
|
+
d_inverter_status: InverterStatus.GridConnectedOperation
|
|
130
|
+
g_i_f: 50.0 Hz
|
|
131
|
+
b_v: 27.1 V
|
|
132
|
+
b_soc: 100 %
|
|
133
|
+
b_cycle_count: 8
|
|
134
|
+
b_t_avg: 0 °C
|
|
135
|
+
b_i_e: 23420 Wh
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Note the two energy fields above: most cumulative energy fields (`ac_o_e_total`, etc.) are reported in kWh, but the battery charge/discharge ones (`b_i_e`, `b_o_e`) are in Wh - both correct as reported by the device, just worth knowing if you're comparing values across fields.
|
|
139
|
+
|
|
140
|
+
Field names follow the naming convention documented in
|
|
141
|
+
[bluetti-registers](https://github.com/bluetti-community/bluetti-registers#naming-convention-for-field-names).
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# bluetti-modbus-lib
|
|
2
|
+
Unofficial library for basic communication to Bluetti Power Stations via Modbus.
|
|
3
|
+
|
|
4
|
+
Based on official documentation https://github.com/bluetti-official/bluetti-modbus-tcp-slave
|
|
5
|
+
|
|
6
|
+
You have to enable Modbus TCP in the webinterface of your device first.
|
|
7
|
+
|
|
8
|
+
## Relationship to Patrick762's `bluetti-modbus-lib`
|
|
9
|
+
|
|
10
|
+
This repository started as a fork of
|
|
11
|
+
[Patrick762/bluetti-modbus-lib](https://github.com/Patrick762/bluetti-modbus-lib)
|
|
12
|
+
and has since diverged significantly (packaging, testing, retry handling,
|
|
13
|
+
device coverage). Patrick762 is still actively maintaining his own version
|
|
14
|
+
independently and was asked directly whether he'd like to fold this work
|
|
15
|
+
back into his project or join `bluetti-community` - he's not in a position
|
|
16
|
+
to commit the time to that right now, which is completely fine.
|
|
17
|
+
|
|
18
|
+
Since the PyPI name `bluetti-modbus-lib` is his and still actively used,
|
|
19
|
+
this project is published on PyPI under a different name, **`bluetti-modbus`**,
|
|
20
|
+
to avoid any ambiguity between the two. The GitHub repository itself keeps
|
|
21
|
+
its original name.
|
|
22
|
+
|
|
23
|
+
## Disclaimer
|
|
24
|
+
This library is provided without any warranty or support by Bluetti. I do not take responsibility for any problems it may cause in all cases. Use it at your own risk.
|
|
25
|
+
|
|
26
|
+
## Supported devices and data
|
|
27
|
+
|
|
28
|
+
- Balco260
|
|
29
|
+
- EP2000
|
|
30
|
+
- SMeter (Bluetti's AC meter/CT device - untested against real hardware so far)
|
|
31
|
+
|
|
32
|
+
Field names, units, and Modbus registers come from
|
|
33
|
+
[bluetti-registers](https://github.com/bluetti-community/bluetti-registers) -
|
|
34
|
+
`devices/balco260.py`, `devices/ep2000.py`, and `devices/smeter.py` in this
|
|
35
|
+
repo are generated from it by `import.py`, not written by hand.
|
|
36
|
+
|
|
37
|
+
## Architecture
|
|
38
|
+
|
|
39
|
+
This library does not create or own a Modbus transport itself. It's built on
|
|
40
|
+
[modbus-connection](https://pypi.org/project/modbus-connection/)'s
|
|
41
|
+
device-modelling framework: `Balco260`, `EP2000`, and `SMeter`
|
|
42
|
+
(`bluetti_modbus_lib.devices`) each take a `ModbusUnit` supplied by the
|
|
43
|
+
caller, built from whichever backend and connection the caller already
|
|
44
|
+
manages. That's the integration surface for embedding this library into
|
|
45
|
+
another application (a Home Assistant integration, for example).
|
|
46
|
+
|
|
47
|
+
`BluettiModbusClient` (`bluetti_modbus_lib.modbus.client`) is different: it
|
|
48
|
+
owns and manages its own connection. It exists for the `bluetti-modread` CLI
|
|
49
|
+
below and standalone/manual use, not as something another application should
|
|
50
|
+
build on - doing so would open a second, competing connection to the device
|
|
51
|
+
instead of sharing one.
|
|
52
|
+
|
|
53
|
+
Field metadata is deliberately limited to what's true at the Modbus/protocol
|
|
54
|
+
level - address, type, scale, unit, whether it's writable. It does not carry
|
|
55
|
+
Home Assistant concepts like entity category, state class, or device class:
|
|
56
|
+
those describe how a value should be presented in an HA UI, not anything
|
|
57
|
+
about the register itself, and belong in whichever integration consumes this
|
|
58
|
+
library, not in the library.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install bluetti-modbus
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Installing `bluetti-modbus` alone only pulls in `modbus-connection`'s
|
|
67
|
+
backend-neutral interface - enough to use the device classes directly against
|
|
68
|
+
a `ModbusUnit` you already have. The `bluetti-modread` CLI needs a concrete
|
|
69
|
+
backend, installed via the `cli` extra:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install "bluetti-modbus[cli]"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Sponsoring
|
|
76
|
+
|
|
77
|
+
If you want to support this project, you can sponsor [Patrick762 on GitHub](https://github.com/sponsors/Patrick762), the original author.
|
|
78
|
+
|
|
79
|
+
## Commands for testing
|
|
80
|
+
|
|
81
|
+
Commands included in this library should only be used for testing.
|
|
82
|
+
|
|
83
|
+
### Read device data for supported devices
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
usage: bluetti-modread [-h] [-c HOST] [-p PORT] [-t TYPE]
|
|
87
|
+
|
|
88
|
+
Read bluetti devices via modbus
|
|
89
|
+
|
|
90
|
+
options:
|
|
91
|
+
-h, --help show this help message and exit
|
|
92
|
+
-c HOST, --host HOST IP-address of the device
|
|
93
|
+
-p PORT, --port PORT Port of the device
|
|
94
|
+
-t TYPE, --type TYPE Device type
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Example:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
bluetti-modread -c 10.2.1.60 -p 502 -t balco260
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Example output, captured from a real Balco260 (truncated - `bluetti-modread` prints one line per field):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
d_num_inverters: 1
|
|
107
|
+
ac_o_p_total: 84 W
|
|
108
|
+
pv_i_p_total: 0 W
|
|
109
|
+
ac_o_e_total: 64.7 kWh
|
|
110
|
+
d_inverter_status: InverterStatus.GridConnectedOperation
|
|
111
|
+
g_i_f: 50.0 Hz
|
|
112
|
+
b_v: 27.1 V
|
|
113
|
+
b_soc: 100 %
|
|
114
|
+
b_cycle_count: 8
|
|
115
|
+
b_t_avg: 0 °C
|
|
116
|
+
b_i_e: 23420 Wh
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Note the two energy fields above: most cumulative energy fields (`ac_o_e_total`, etc.) are reported in kWh, but the battery charge/discharge ones (`b_i_e`, `b_o_e`) are in Wh - both correct as reported by the device, just worth knowing if you're comparing values across fields.
|
|
120
|
+
|
|
121
|
+
Field names follow the naming convention documented in
|
|
122
|
+
[bluetti-registers](https://github.com/bluetti-community/bluetti-registers#naming-convention-for-field-names).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "bluetti-modbus"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Unofficial library for basic communication to Bluetti Power Stations via Modbus"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Patrick762" }, { name = "bluetti-community" }]
|
|
13
|
+
keywords = ["modbus", "bluetti", "home-assistant"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
]
|
|
19
|
+
# Protocol + the device-modelling framework (modbus_connection.model). The
|
|
20
|
+
# caller injects a ModbusUnit built from whichever backend they choose - see
|
|
21
|
+
# README.md. This package does not create or own a Modbus transport itself.
|
|
22
|
+
dependencies = ["modbus-connection>=4.10.0"]
|
|
23
|
+
|
|
24
|
+
[project.optional-dependencies]
|
|
25
|
+
# Concrete backend for the bluetti-modread CLI (pip install bluetti-modbus[cli]).
|
|
26
|
+
cli = ["modbus-connection[pymodbus]>=4.10.0"]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/bluetti-community/bluetti-modbus-lib"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
bluetti-modread = "bluetti_modbus_lib.scripts.bluetti_modread:start"
|
|
33
|
+
|
|
34
|
+
[dependency-groups]
|
|
35
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.24", "pytest-cov>=5"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.package-data]
|
|
41
|
+
bluetti_modbus_lib = ["py.typed"]
|
|
42
|
+
|
|
43
|
+
[tool.ruff]
|
|
44
|
+
target-version = "py313"
|
|
45
|
+
src = ["src"]
|
|
46
|
+
|
|
47
|
+
[tool.mypy]
|
|
48
|
+
strict = true
|
|
49
|
+
packages = ["bluetti_modbus_lib"]
|
|
50
|
+
|
|
51
|
+
[tool.coverage.run]
|
|
52
|
+
omit = [
|
|
53
|
+
# The bluetti-modread CLI - README.md: "Commands included in this
|
|
54
|
+
# library should only be used for testing." Not library logic.
|
|
55
|
+
"src/bluetti_modbus_lib/scripts/*",
|
|
56
|
+
]
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bluetti-modbus
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial library for basic communication to Bluetti Power Stations via Modbus
|
|
5
|
+
Author: Patrick762, bluetti-community
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bluetti-community/bluetti-modbus-lib
|
|
8
|
+
Keywords: modbus,bluetti,home-assistant
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.13
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: modbus-connection>=4.10.0
|
|
16
|
+
Provides-Extra: cli
|
|
17
|
+
Requires-Dist: modbus-connection[pymodbus]>=4.10.0; extra == "cli"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# bluetti-modbus-lib
|
|
21
|
+
Unofficial library for basic communication to Bluetti Power Stations via Modbus.
|
|
22
|
+
|
|
23
|
+
Based on official documentation https://github.com/bluetti-official/bluetti-modbus-tcp-slave
|
|
24
|
+
|
|
25
|
+
You have to enable Modbus TCP in the webinterface of your device first.
|
|
26
|
+
|
|
27
|
+
## Relationship to Patrick762's `bluetti-modbus-lib`
|
|
28
|
+
|
|
29
|
+
This repository started as a fork of
|
|
30
|
+
[Patrick762/bluetti-modbus-lib](https://github.com/Patrick762/bluetti-modbus-lib)
|
|
31
|
+
and has since diverged significantly (packaging, testing, retry handling,
|
|
32
|
+
device coverage). Patrick762 is still actively maintaining his own version
|
|
33
|
+
independently and was asked directly whether he'd like to fold this work
|
|
34
|
+
back into his project or join `bluetti-community` - he's not in a position
|
|
35
|
+
to commit the time to that right now, which is completely fine.
|
|
36
|
+
|
|
37
|
+
Since the PyPI name `bluetti-modbus-lib` is his and still actively used,
|
|
38
|
+
this project is published on PyPI under a different name, **`bluetti-modbus`**,
|
|
39
|
+
to avoid any ambiguity between the two. The GitHub repository itself keeps
|
|
40
|
+
its original name.
|
|
41
|
+
|
|
42
|
+
## Disclaimer
|
|
43
|
+
This library is provided without any warranty or support by Bluetti. I do not take responsibility for any problems it may cause in all cases. Use it at your own risk.
|
|
44
|
+
|
|
45
|
+
## Supported devices and data
|
|
46
|
+
|
|
47
|
+
- Balco260
|
|
48
|
+
- EP2000
|
|
49
|
+
- SMeter (Bluetti's AC meter/CT device - untested against real hardware so far)
|
|
50
|
+
|
|
51
|
+
Field names, units, and Modbus registers come from
|
|
52
|
+
[bluetti-registers](https://github.com/bluetti-community/bluetti-registers) -
|
|
53
|
+
`devices/balco260.py`, `devices/ep2000.py`, and `devices/smeter.py` in this
|
|
54
|
+
repo are generated from it by `import.py`, not written by hand.
|
|
55
|
+
|
|
56
|
+
## Architecture
|
|
57
|
+
|
|
58
|
+
This library does not create or own a Modbus transport itself. It's built on
|
|
59
|
+
[modbus-connection](https://pypi.org/project/modbus-connection/)'s
|
|
60
|
+
device-modelling framework: `Balco260`, `EP2000`, and `SMeter`
|
|
61
|
+
(`bluetti_modbus_lib.devices`) each take a `ModbusUnit` supplied by the
|
|
62
|
+
caller, built from whichever backend and connection the caller already
|
|
63
|
+
manages. That's the integration surface for embedding this library into
|
|
64
|
+
another application (a Home Assistant integration, for example).
|
|
65
|
+
|
|
66
|
+
`BluettiModbusClient` (`bluetti_modbus_lib.modbus.client`) is different: it
|
|
67
|
+
owns and manages its own connection. It exists for the `bluetti-modread` CLI
|
|
68
|
+
below and standalone/manual use, not as something another application should
|
|
69
|
+
build on - doing so would open a second, competing connection to the device
|
|
70
|
+
instead of sharing one.
|
|
71
|
+
|
|
72
|
+
Field metadata is deliberately limited to what's true at the Modbus/protocol
|
|
73
|
+
level - address, type, scale, unit, whether it's writable. It does not carry
|
|
74
|
+
Home Assistant concepts like entity category, state class, or device class:
|
|
75
|
+
those describe how a value should be presented in an HA UI, not anything
|
|
76
|
+
about the register itself, and belong in whichever integration consumes this
|
|
77
|
+
library, not in the library.
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install bluetti-modbus
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Installing `bluetti-modbus` alone only pulls in `modbus-connection`'s
|
|
86
|
+
backend-neutral interface - enough to use the device classes directly against
|
|
87
|
+
a `ModbusUnit` you already have. The `bluetti-modread` CLI needs a concrete
|
|
88
|
+
backend, installed via the `cli` extra:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install "bluetti-modbus[cli]"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Sponsoring
|
|
95
|
+
|
|
96
|
+
If you want to support this project, you can sponsor [Patrick762 on GitHub](https://github.com/sponsors/Patrick762), the original author.
|
|
97
|
+
|
|
98
|
+
## Commands for testing
|
|
99
|
+
|
|
100
|
+
Commands included in this library should only be used for testing.
|
|
101
|
+
|
|
102
|
+
### Read device data for supported devices
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
usage: bluetti-modread [-h] [-c HOST] [-p PORT] [-t TYPE]
|
|
106
|
+
|
|
107
|
+
Read bluetti devices via modbus
|
|
108
|
+
|
|
109
|
+
options:
|
|
110
|
+
-h, --help show this help message and exit
|
|
111
|
+
-c HOST, --host HOST IP-address of the device
|
|
112
|
+
-p PORT, --port PORT Port of the device
|
|
113
|
+
-t TYPE, --type TYPE Device type
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
bluetti-modread -c 10.2.1.60 -p 502 -t balco260
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Example output, captured from a real Balco260 (truncated - `bluetti-modread` prints one line per field):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
d_num_inverters: 1
|
|
126
|
+
ac_o_p_total: 84 W
|
|
127
|
+
pv_i_p_total: 0 W
|
|
128
|
+
ac_o_e_total: 64.7 kWh
|
|
129
|
+
d_inverter_status: InverterStatus.GridConnectedOperation
|
|
130
|
+
g_i_f: 50.0 Hz
|
|
131
|
+
b_v: 27.1 V
|
|
132
|
+
b_soc: 100 %
|
|
133
|
+
b_cycle_count: 8
|
|
134
|
+
b_t_avg: 0 °C
|
|
135
|
+
b_i_e: 23420 Wh
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Note the two energy fields above: most cumulative energy fields (`ac_o_e_total`, etc.) are reported in kWh, but the battery charge/discharge ones (`b_i_e`, `b_o_e`) are in Wh - both correct as reported by the device, just worth knowing if you're comparing values across fields.
|
|
139
|
+
|
|
140
|
+
Field names follow the naming convention documented in
|
|
141
|
+
[bluetti-registers](https://github.com/bluetti-community/bluetti-registers#naming-convention-for-field-names).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/bluetti_modbus.egg-info/PKG-INFO
|
|
5
|
+
src/bluetti_modbus.egg-info/SOURCES.txt
|
|
6
|
+
src/bluetti_modbus.egg-info/dependency_links.txt
|
|
7
|
+
src/bluetti_modbus.egg-info/entry_points.txt
|
|
8
|
+
src/bluetti_modbus.egg-info/requires.txt
|
|
9
|
+
src/bluetti_modbus.egg-info/top_level.txt
|
|
10
|
+
src/bluetti_modbus_lib/__init__.py
|
|
11
|
+
src/bluetti_modbus_lib/py.typed
|
|
12
|
+
src/bluetti_modbus_lib/base_devices/__init__.py
|
|
13
|
+
src/bluetti_modbus_lib/base_devices/bluetti_device.py
|
|
14
|
+
src/bluetti_modbus_lib/devices/__init__.py
|
|
15
|
+
src/bluetti_modbus_lib/devices/balco260.py
|
|
16
|
+
src/bluetti_modbus_lib/devices/ep2000.py
|
|
17
|
+
src/bluetti_modbus_lib/devices/getter.py
|
|
18
|
+
src/bluetti_modbus_lib/devices/smeter.py
|
|
19
|
+
src/bluetti_modbus_lib/enums/__init__.py
|
|
20
|
+
src/bluetti_modbus_lib/enums/inverter_fault.py
|
|
21
|
+
src/bluetti_modbus_lib/enums/inverter_status.py
|
|
22
|
+
src/bluetti_modbus_lib/enums/inverter_warning.py
|
|
23
|
+
src/bluetti_modbus_lib/fields/__init__.py
|
|
24
|
+
src/bluetti_modbus_lib/fields/custom_fields.py
|
|
25
|
+
src/bluetti_modbus_lib/modbus/__init__.py
|
|
26
|
+
src/bluetti_modbus_lib/modbus/client.py
|
|
27
|
+
src/bluetti_modbus_lib/scripts/__init__.py
|
|
28
|
+
src/bluetti_modbus_lib/scripts/bluetti_modread.py
|
|
29
|
+
tests/test_base_devices.py
|
|
30
|
+
tests/test_client.py
|
|
31
|
+
tests/test_custom_fields.py
|
|
32
|
+
tests/test_getter.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bluetti_modbus_lib
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .bluetti_device import *
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from collections.abc import KeysView
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from modbus_connection.model import Component, RegisterField
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BluettiDevice(Component):
|
|
8
|
+
max_gap = 5
|
|
9
|
+
max_span = 50
|
|
10
|
+
|
|
11
|
+
def field_names(self) -> KeysView[str]:
|
|
12
|
+
return self._register_fields.keys()
|
|
13
|
+
|
|
14
|
+
def get_field(self, field_name: str) -> RegisterField[Any] | None:
|
|
15
|
+
return self._register_fields.get(field_name)
|
|
16
|
+
|
|
17
|
+
def get_sensors(self) -> KeysView[str]:
|
|
18
|
+
return self.field_names()
|