A library for parsing Renogy BLE data
Project description
Renogy BLE
A Python library for communicating with Renogy Bluetooth Low Energy (BLE) devices and parsing their Modbus responses.
Overview
Library for communicating with Renogy devices over BLE using BT-1 and BT-2 Bluetooth modules for controller-style devices, direct BLE notifications from Smart Shunt 300 devices, and dedicated BLE reads for Renogy inverters.
Currently supported devices:
- Renogy charge controllers (such as Rover, Wanderer, Adventurer)
- Renogy Smart Shunt 300
- Renogy inverters that expose the RIV-series BLE register layout
Future planned support:
- Renogy batteries
Installation
pip install renogy-ble
Usage
There are two common ways to use this library:
- Parse raw Modbus response bytes (if you already handle BLE I/O elsewhere).
- Use the built-in BLE client to connect, read, and parse data end-to-end.
Parse Raw Modbus Responses
Use this when you already have the raw Modbus response bytes and the register address you requested.
from renogy_ble import RenogyParser
# Raw BLE data received from your Renogy device
raw_data = b"\xff\x03\x02\x00\x04\x90S" # Example data
# Parse the data for a specific model and register
parsed_data = RenogyParser.parse(raw_data, device_type="controller", register=57348)
# Use the parsed data
print(parsed_data)
# Example output: {'battery_type': 'lithium'}
Notes:
raw_datamust include the full Modbus response, including address, function code, byte count, and CRC.- Parsed values may be scaled or mapped based on the register map (for example, voltages are scaled to volts).
Connect Over BLE and Read Data
The RenogyBleClient handles Modbus framing, BLE notification reads, and parsing.
This example discovers a BLE device, connects, reads the default command set, and
prints the parsed data.
import asyncio
from bleak import BleakScanner
from renogy_ble import RenogyBLEDevice, RenogyBleClient
async def main() -> None:
devices = await BleakScanner.discover()
ble_device = next(
device for device in devices if "Renogy" in (device.name or "")
)
renogy_device = RenogyBLEDevice(ble_device, device_type="controller")
client = RenogyBleClient()
result = await client.read_device(renogy_device)
if result.success:
print(result.parsed_data)
else:
print(f"Read failed: {result.error}")
if __name__ == "__main__":
asyncio.run(main())
Smart Shunt 300 Reads
Smart Shunt 300 devices do not use the same Modbus command flow as Renogy
controllers. device_type="shunt300" is handled by a dedicated
notification-based client.
For one-off reads, RenogyBleClient.read_device() will automatically delegate to
the shunt client:
import asyncio
from bleak import BleakScanner
from renogy_ble import RenogyBLEDevice, RenogyBleClient
async def main() -> None:
devices = await BleakScanner.discover()
ble_device = next(
device for device in devices if (device.name or "").startswith("RTMShunt300")
)
renogy_device = RenogyBLEDevice(ble_device, device_type="shunt300")
result = await RenogyBleClient().read_device(renogy_device)
print(result.parsed_data)
if __name__ == "__main__":
asyncio.run(main())
If you want the derived shunt energy totals to accumulate across repeated reads,
reuse a single ShuntBleClient instance:
from renogy_ble import RenogyBLEDevice, ShuntBleClient
client = ShuntBleClient()
device = RenogyBLEDevice(ble_device, device_type="shunt300")
result = await client.read_device(device)
Inverter Reads
Renogy inverters do not follow the same command flow as controller-style
devices. device_type="inverter" is handled by a dedicated client that:
- optionally reads an inverter-specific initialization characteristic
- subscribes to BLE notifications
- requests the default inverter command set
- parses the responses into a flat dictionary
For one-off reads, RenogyBleClient.read_device() automatically delegates to
InverterBleClient:
import asyncio
from bleak import BleakScanner
from renogy_ble import RenogyBLEDevice, RenogyBleClient
async def main() -> None:
devices = await BleakScanner.discover()
ble_device = next(
device for device in devices if (device.name or "").startswith("RNGRIU")
)
renogy_device = RenogyBLEDevice(ble_device, device_type="inverter")
result = await RenogyBleClient().read_device(renogy_device)
print(result.parsed_data)
if __name__ == "__main__":
asyncio.run(main())
If you need direct control over the inverter transport, use
InverterBleClient:
from renogy_ble import InverterBleClient, RenogyBLEDevice
client = InverterBleClient()
device = RenogyBLEDevice(ble_device, device_type="inverter")
result = await client.read_device(device)
The default inverter reads request these command groups:
main_datafrom register4000load_datafrom register4408device_idfrom register4109modelfrom register4311
Custom Commands or Device IDs
You can supply your own Modbus command set or device ID if needed.
RenogyBleClient forwards inverter-specific overrides when it delegates to
InverterBleClient.
from renogy_ble import COMMANDS, RenogyBleClient
custom_commands = {
"controller": {
**COMMANDS["controller"],
"battery": (3, 57348, 1),
}
}
client = RenogyBleClient(device_id=0xFF, commands=custom_commands)
For inverter-specific customization, the package also exports the dedicated defaults:
from renogy_ble import INVERTER_COMMANDS, INVERTER_DEVICE_ID, InverterBleClient
client = InverterBleClient(
device_id=INVERTER_DEVICE_ID,
commands=INVERTER_COMMANDS,
)
Features
- Connects to Renogy BLE devices and reads Modbus registers
- Connects to Renogy Smart Shunt 300 devices and parses BLE notifications
- Connects to supported Renogy inverters and reads BLE notification responses
- Builds Modbus read requests with CRC framing
- Parses raw BLE Modbus responses from Renogy devices
- Extracts controller, shunt, and inverter telemetry into a flat dictionary
- Returns data in a flat dictionary structure
- Applies scaling and mapping based on the register definitions
Data Handling
Input Format
The library accepts raw BLE Modbus response bytes and requires you to specify:
- The device type (for example,
device_type="controller"ordevice_type="inverter") - The register number being parsed (e.g.,
register=256)
Output Format
Returns a flat dictionary of parsed values:
{
"battery_voltage": 12.9,
"pv_power": 250,
"charging_status": "mppt" # Mapped from numeric values where applicable
}
Extending for Other Models
The library is designed to be easily extensible for other Renogy device types. To add support for a new type:
- Update the
REGISTER_MAPinregister_map.pywith the new device type's register mapping - Create a new type-specific parser class in
parser.py(if needed) - Update the
RenogyParser.parse()method to route to your new parser - If the new device needs custom BLE behavior, add a dedicated client and delegate from
RenogyBleClient.read_device()
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
References
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file renogy_ble-2.1.0b50.tar.gz.
File metadata
- Download URL: renogy_ble-2.1.0b50.tar.gz
- Upload date:
- Size: 53.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be57938e93aadba3f2fdddbb00efb237ab1713f272e1142710e729807602beff
|
|
| MD5 |
6478b7fb14fcd2d92c9a95a944742445
|
|
| BLAKE2b-256 |
33f70fd0bae00ccbaf0b15a6d4072e46d2bf6912dd5b22597ba74484050a46d0
|
File details
Details for the file renogy_ble-2.1.0b50-py3-none-any.whl.
File metadata
- Download URL: renogy_ble-2.1.0b50-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40ffab89fffc8f32050189c94ee1eda4c02f6a790c5ec4ba0cf7378d9009931b
|
|
| MD5 |
48efe70b2e58d9070421f5a9fbb17fcc
|
|
| BLAKE2b-256 |
11f7e653facd4f15178a2750d8f43765d8b292e724b70be9586f18b860f51986
|