cyrils / renogy-bt Goto Github PK
View Code? Open in Web Editor NEWPython library to read Renogy compatible BT-1 or BT-2 bluetooth modules using Raspberry Pi.
License: GNU General Public License v3.0
Python library to read Renogy compatible BT-1 or BT-2 bluetooth modules using Raspberry Pi.
License: GNU General Public License v3.0
I am running a Raspi4 B with native installation of HA.
It seems like there is no easy way to build libscrc on that machine. I was wondering if anybody could supply a binary for that or one could get rid of the dependency, so we could run this script on native HA?
Hi
I am runnng into the error
ERROR:root:base client cannot be used directly
`
INFO:root:[E0:7D:EA:83:xx:xx] Resolved services
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
ERROR:root:base client cannot be used directly
INFO:root:characteristic_enable_notifications_succeeded
`
any root cause known?
what am I missing
thanks a lot
I can see the device in Linux when running bluetoothctl
scan on.
[NEW] Device 60:98:66:EF:9D:A6 60-98-66-EF-9D-A6
But when I run the example.py
python example.py
INFO:root:Starting client: BT-TH-66EF9DA6 => 60:98:66:EF:9D:A6
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 2
INFO:root:Devices found: 7
INFO:root:Devices found: 10
INFO:root:Devices found: 10
INFO:root:Devices found: 12
ERROR:root:Device not found: BT-TH-66EF9DA6 => 60:98:66:EF:9D:A6, please check the details provided.
Wondered if there is something missing with this newer BT1 module. I have it connected to a Wanderer 30A Controller
Test if the library works with bt-2 type adapter. Some existing libraries (ex: neilsheps/Renogy-BT2-Reader) indicates the characteristics and register values are same, but I was unable to test it with a bt-2 adapter as I don't have one.
I just set this up using the Renogy Wanderer/ Raspberry Pi Zero W and it's working perfectly. Thank you!
Is there a way to get the history data that the Renogy app can retrieve?
Hello,
When setting "enable_polling" to true, the software still exsits after the first fetch/send.
Is that functionality expected? Shouldn't it continuously loop to fetch/send data every "poll_interval" set?
Thanks
Hey Cyril,
Thanks for writing this software, it works great.
I am trying to use a converter/cable to go directly from the Rover RS232 port to computer, without using the Bluetooth module. Have you tried doing this before?
Aleks
I can run the example.py program from the command line on a Raspberry Pi Zero W. I have modified the program to log data to a Google spreadsheet. Running it from the command line works great.
But when I try running it with crontab, it doesn't seem to run. On a subsequent run from the command line, I get this error:
INFO:root:on_data_received: response for read operation
ERROR:dbus.connection:Exception in handler for D-Bus signal:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/dbus/connection.py", line 230, in maybe_handle_message
self._handler(*args, **kwargs)
File "/home/pi/.local/lib/python3.7/site-packages/gatt/gatt_linux.py", line 539, in properties_changed
self.service.device.characteristic_value_updated(characteristic=self, value=bytes(value))
File "/home/pi/Documents/solar/renogy-bt/renogybt/BLE.py", line 86, in characteristic_value_updated
self.data_callback(value)
File "/home/pi/Documents/solar/renogy-bt/renogybt/RoverClient.py", line 59, in on_data_received
super().on_data_received(response)
File "/home/pi/Documents/solar/renogy-bt/renogybt/BaseClient.py", line 62, in on_data_received
index, section = self.find_section_by_response(response)
TypeError: cannot unpack non-iterable NoneType object
My crontab entry:
*/5 * * * * python3 /home/pi/Documents/solar/renogy-bt/example.py
Any idea why it won't work with crontab but it does work from the command line?
Hi,
I tried to get my new Renogy RBT12100LFP-BT working, the example.py throws an error.
The connections seems to be established, but reading values fails.
INFO:root:Init RoverClient: RNGPRO12BATT4600xxxx => 4c:e1:74:49:xx:xx
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 5
INFO:root:Found matching device RNGPRO12BATT4600xxxx => [4c:e1:74:49:xx:xx]
INFO:root:[4c:e1:74:49:xx:xx] Connected
INFO:root:[4c:e1:74:49:xx:x] Resolved services
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
DEBUG:root:create_request_payload 12 => [255, 3, 0, 12, 0, 8, 145, 209]
INFO:root:characteristic_enable_notifications_failed
INFO:root:characteristic_enable_notifications_succeeded
INFO:root:characteristic_write_value_failed
WARNING:root:on_data_received: unknown operation=131
^CERROR:root:Exception occured: KeyboardInterrupt
INFO:root:Exit: Disconnecting device: RNGPRO12BATT46000121 [4c:e1:74:49:xx:xx]
Any help is appreciated.
Thanks, Stefan.
I've added the MQTT Discovery function that auto create the components in Home Assistant.
1 - We need to add this to DataLogger.py (for some reason i cant paste the code here it's broke the editor)
2 - some changes need to be done on log_mqtt function still in DataLogger.py
3 - We need to create the call for the new function on example.py or whathever you are using to start the renogy
4 - We neet to indicate in the config.ini the instance name of our home assistant
A video fo the thing working:
https://github.com/cyrils/renogy-bt/assets/148077119/13f61b24-5d9e-4b15-a75d-4f838eb8766e
Would it be possible to read directly from the Core One?
My mppt and battery are connected to it, but I've noticed that I can't tap to the BT-2 and sending data to my mqtt server.
Has anyone noticed that or thought about how to resolve that? (not sure if it's considered as an issue or maybe enhancement request?)
Regards,
Didi
Hi
thanks for your software
working also for SKU: RCC40RVRE
and bT-2
Looks like ony BT-2 is connect device ID is set to 17. at least for mine.
you might want to add this to the documentation
I was able to pull data from my DCC50S via the Renogy hub on ID 96. Perhaps this is different between the DCC controllers and the Rover controllers? Might be worth mentioning in the readme.
Hi
as this is a perfect implementation for pulling data from the Renogy BT
I am wondering if this can be migrated to esphome esp32-ble as well.
Thanks for checking
I'm trying to write a simple script to toggle the charge controller's load on and off.
client.set_load(1) works as expected and the controller's load turns on
but client.set_load(0) throws an error and does not turn off the load
---Error Log--
INFO:root:on_read_operation_complete
Data received
INFO:root:setting load 0
ERROR:dbus.connection:Exception in handler for D-Bus signal:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/dbus/connection.py", line 232, in maybe_handle_message
self._handler(*args, **kwargs)
File "/home/pi/.local/lib/python3.9/site-packages/gatt/gatt_linux.py", line 539, in properties_changed
self.service.device.characteristic_value_updated(characteristic=self, value=bytes(value))
File "/home/pi/renogy-bt/renogybt/BLE.py", line 86, in characteristic_value_updated
self.data_callback(value)
File "/home/pi/renogy-bt/renogybt/RoverClient.py", line 57, in on_data_received
super().on_data_received(response)
File "/home/pi/renogy-bt/renogybt/BaseClient.py", line 74, in on_data_received
self.on_read_operation_complete()
File "/home/pi/renogy-bt/renogybt/BaseClient.py", line 88, in on_read_operation_complete
self.on_data_callback(self, self.data)
File "/home/pi/renogy-bt/toggle.py", line 24, in on_data_received
client.set_load(0)
File "/home/pi/renogy-bt/renogybt/RoverClient.py", line 67, in set_load
self.device.characteristic_write_value(request)
File "/home/pi/renogy-bt/renogybt/BLE.py", line 89, in characteristic_write_value
self.write_characteristic.write_value(value)
File "/home/pi/.local/lib/python3.9/site-packages/gatt/gatt_linux.py", line 565, in write_value
bytes = [dbus.Byte(b) for b in value]
TypeError: 'NoneType' object is not iterable
--My code--
def on_data_received(client, data):
print("Data received")
loadswitch = 0
if data["load_status"] == "off": loadswitch = 1
client.set_load(loadswitch)
client.disconnect()
#Connect
RoverClient(config, on_data_received).connect()
Test compatibility of Renogy Battery RBT50LFP48S
Device: Renogy Rover LI 40A
Bluetooth-Modul BT-1
Log from starting the ./example.py
INFO:root:Starting client: BT-TH-7749A78E => f4:60:77:49:a7:8e
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 9
INFO:root:Found matching device BT-TH-7749A78E => [f4:60:77:49:a7:8e]
INFO:root:[f4:60:77:49:a7:8e] Discovered, alias = BT-TH-7749A78E
INFO:root:[f4:60:77:49:a7:8e] Discovered, alias = BT-TH-7749A78E
INFO:root:[f4:60:77:49:a7:8e] Connected
INFO:root:[f4:60:77:49:a7:8e] Discovered, alias = BT-TH-7749A78E
INFO:root:[f4:60:77:49:a7:8e] Disconnected
ERROR:root:Connection failed: Disconnected
The mac address an the device alias is correct, why doesn't it work?
Using android Bluetooth HCI snooping while running the Renogy DC Home app, I can see traffic to my BT-2 device in Wireshark and I can see battery info in the app. However the device never appears in the bluetooth menus of my phone, mac laptop, windows laptop, or in bluetoothctl scan on
on a raspberry pi.
When I run example.py with the alias/mac info from the wireshark trace, it appears to cycle through the discoverable devices in the area and then report device not found
I'm having trouble understanding how this should work if the BT-2 device isn't discoverable by design. Am I missing a firmware update or setting on the BT-2 to make it discoverable?
python3 ./example.py config.ini
INFO:root:Init BatteryClient: BT-TH-774C10AA => f4:60:****
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 1
INFO:root:Checking device Ice Box => [34:94:****]
INFO:root:Devices found: 1
INFO:root:Checking device Ice Box => [34:94:****]
INFO:root:Devices found: 1
INFO:root:Checking device Ice Box => [34:94:****]
INFO:root:Devices found: 1
INFO:root:Checking device Ice Box => [34:94:****]
INFO:root:Devices found: 1
INFO:root:Checking device Ice Box => [34:94:****]
ERROR:root:Device not found: BT-TH-774C10AA => f4:60:****, please check the details provided.
In the above log, Ice Box is my fridge. It never finds the BT-2 device even though it's on, working, and a couple feet away (within a similar range as the phone app).
That Checking
log line comes from a modification to BLE.py
to see what it was looping though:
while discovering:
time.sleep(1)
logging.info("Devices found: %s", len(self.devices()))
for dev in self.devices():
logging.info("Checking device %s => [%s]", dev.alias(), dev.mac_address)
if dev.mac_address != None and (dev.mac_address.upper() == mac_address or dev.alias() == self.device_alias) and discovering:
logging.info("Found matching device %s => [%s]", dev.alias(), dev.mac_address)
discovering = False; self.device_found = True
I've tried running both example.py and bluetoothctl scanning at different times: during & shortly after running the app (in case something special needs to wake it up), and also tried after the app hasn't been connected (in case it'll only talk to one device at a time). The BT-2 device never appears.
My Renogy Rover 60A works like a champ! I thought I would try to use the same code for the Renogy Shunt 300 with Bluetooth, but that didn't work so well :-( It doesn't like the request payload.
DEBUG:root:create_request_payload 5000 => [33, 3, 19, 136, 0, 17, 6, 8]
I used the RNG_BATT in hopes they were close, but I guess not. I tried many device_IDs but couldn't get it to read.
Output Data:
INFO:root:Init BatteryClient: RTMShunt300xxxxxxxx => xx:xx:xx:xx:xx:xx
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 55
INFO:root:Found matching device RTMShunt3005xxxxxxxx => [(xx:xx:xx:xx:xx:xx)]
INFO:root:[xx:xx:xx:xx:xx:xx] Connected
INFO:root:[xx:xx:xx:xx:xx:xx] Resolved services
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
DEBUG:root:create_request_payload 5000 => [33, 3, 19, 136, 0, 17, 6, 8]
INFO:root:characteristic_enable_notifications_failed
INFO:root:characteristic_write_value_succeeded
ERROR:root:on_read_timeout => please check your device_id!
INFO:root:Exit: Disconnecting device: RTMShunt300xxxxxxxx [(xx:xx:xx:xx:xx:xx)]
Is there a way to get past this easily and pull/read the data from this device? Seems you already built the rest out. Maybe just the right data feeds and added parser. Happy to assist!
Is there a wireshark ish app for Bluetooth on RPie4? I am happy to assist if you are open to the idea.
Confirmed working with Rich Solar 60 and Rich Solar labeled BT-1:
{'function': 'READ', 'model': 'ML4860N15', 'device_id': 1, 'battery_percentage': 100, 'battery_voltage': 13.6, 'battery_current': 16.94, 'battery_temperature': 93.2, 'controller_temperature': 107.6, 'load_status': 'off', 'load_voltage': 0.0, 'load_current': 0.0, 'load_power': 0, 'pv_voltage': 55.6, 'pv_current': 4.31, 'pv_power': 240, 'max_charging_power_today': 303, 'max_discharging_power_today': 0, 'charging_amp_hours_today': 18, 'discharging_amp_hours_today': 0, 'power_generation_today': 254, 'power_consumption_today': 0, 'power_generation_total': 54642, 'charging_status': 'mppt', 'battery_type': 'lithium', '__device': 'BT-TH-73C4AA5D', '__client': 'RoverClient'}
I occasionally see the app not reading the values from the BT-1. The data shows only values that do not change, ie function
, model
, etc. Here is the log:
pi@raspberrypi:~/Documents/renogy-bt $ python3 example.py
INFO:root:Init RoverClient: BT-TH-161DADB1 => ac:4d:16:1d:ad:b1
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 1
INFO:root:Found matching device BT-TH-161DADB1 => [ac:4d:16:1d:ad:b1]
INFO:root:[ac:4d:16:1d:ad:b1] Connected
INFO:root:[ac:4d:16:1d:ad:b1] Resolved services
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
DEBUG:root:create_request_payload 12 => [255, 3, 0, 12, 0, 8, 145, 209]
INFO:root:characteristic_enable_notifications_succeeded
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
DEBUG:root:create_request_payload 256 => [255, 3, 1, 0, 0, 34, 209, 241]
INFO:root:on_data_received: response for read operation
DEBUG:root:create_request_payload 57348 => [255, 3, 224, 4, 0, 1, 231, 213]
INFO:root:characteristic_write_value_failed
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
INFO:root:on_read_operation_complete
DEBUG:root:BT-TH-161DADB1 => {'function': 'READ', 'model': 'RNG-CTRL-WND10', '__device': 'BT-TH-161DADB1', '__client': 'RoverClient'}
This happened four times in a row over the course of an hour, running at 15 minute intervals. Other times, it works fine. Could this be a hardware problem? Or an async issue?
Hi hope you are well, i have been trying to do this for weeks now, please help
I have installed Home Assistant using the Raspberry Pi imager 32bit version. i have a Pi 4
I can't seem to get it to work, everytime I run python3 ./example.py,
it says I don't have something installed, when I run python3 -m pip install -r requirements.txt,
libscrc errors out, then managed to get that installed, then says Module 'dbus' not found is missing, manage to install that, then it say ModuleNotFoundError: No module named 'gi'
cant install any further, then when I reboot, it looses everything and says nothing is installed and I have to start again.
can I check how you are installing Home assistant on the pi, maybe I'm doing that start bit wrong.
Thanks for any help
Howdy,
I consider myself an idiot. I have practically zero Python experience but did code a bit back at uni.
While trying to run example.py as instructed with a config file as an argument, I would always get:
config_file = sys.argv.get[1] if len(sys.argv) > 1 else 'config.ini'
^^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'get'
From my understanding of the error and a quick google-fu, you just need sys.argv[1]. I modified the line to:
config_file = sys.argv[1] if len(sys.argv) > 1 else 'config.ini'
and now it works properly, using the entered config file
Posting this so if anyone else like me ends up with the error can make the module work, and if I am wrong I can be told where I am messing up!
Thanks
Traceback (most recent call last):
File "c:\GitHub\renogy-bt1\example.py", line 25, in
BTOneClient(config, on_data_received).connect()
File "c:\GitHub\renogy-bt1\renogybt\BTOneClient.py", line 36, in connect
self.manager = DeviceManager(adapter_name=self.config['device']['adapter'], mac_address=self.config['device']['mac_addr'], alias=self.config['device']['alias'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\GitHub\renogy-bt1\renogybt\BLE.py", line 9, in init
super(). init(adapter_name, mac_address, alias)
TypeError: object.init() takes exactly one argument (the instance to initialize)
Hey I'm new to Python and am trying to log basic info (voltages and currents) from a Renogy BT-1 module as part of a mechanical engineering project at university. What would be the best way to make a loop to get the highest possible resolution out of this code (e.g. 30second intervals)? I'm going to pipe the terminal output to a csv file so I can manipulate the data using Excel. Any help and guidance will by greatly appreciated! Thank you!
Hello,
will you support renogy bluetooth batteries? https://github.com/chadj/renogy-smart-battery this is working but is webbased. i have no idea how your script or the other works but i can test it if you want to support batteries, too.
Test compatibility with Renogy inverter models:
The InverterClient
is experimental and may be incomplete/ incompatible with some models.
Just realized this as I was looking into my Home assistant MQTT logs.
Got the script running every 5 mins via crontab.Polling is disabled. It seems python never exits and hammers the mqtt server (obfuscated ip and username):
2024-01-21 22:04:14: New connection from IP_ADDRESS:42671 on port 1883.
2024-01-21 22:04:14: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:14: New client connected from IP_ADDRESS:42671 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:14: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:14: New client connected from IP_ADDRESS:60953 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:15: New connection from IP_ADDRESS:55569 on port 1883.
2024-01-21 22:04:15: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:15: New client connected from IP_ADDRESS:55569 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:15: New connection from IP_ADDRESS:35631 on port 1883.
2024-01-21 22:04:15: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:15: New client connected from IP_ADDRESS:35631 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:15: New connection from IP_ADDRESS:50761 on port 1883.
2024-01-21 22:04:15: New connection from IP_ADDRESS:33767 on port 1883.
2024-01-21 22:04:15: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:15: New client connected from IP_ADDRESS:33767 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:15: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:15: New client connected from IP_ADDRESS:50761 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:15: New connection from IP_ADDRESS:51817 on port 1883.
2024-01-21 22:04:15: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:15: New client connected from IP_ADDRESS:51817 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:16: New connection from IP_ADDRESS:54751 on port 1883.
2024-01-21 22:04:16: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:16: New client connected from IP_ADDRESS:54751 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:16: New connection from IP_ADDRESS:45733 on port 1883.
2024-01-21 22:04:16: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:16: New client connected from IP_ADDRESS:45733 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:16: New connection from IP_ADDRESS:39235 on port 1883.
2024-01-21 22:04:16: New connection from IP_ADDRESS:34031 on port 1883.
2024-01-21 22:04:16: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:16: New client connected from IP_ADDRESS:39235 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:16: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:16: New client connected from IP_ADDRESS:34031 as renogy-bt (p2, c1, k60, u'USERNAME').
2024-01-21 22:04:16: New connection from IP_ADDRESS:52739 on port 1883.
2024-01-21 22:04:16: Client renogy-bt already connected, closing old connection.
2024-01-21 22:04:16: New client connected from IP_ADDRESS:52739 as renogy-bt (p2, c1, k60, u'USERNAME').
If I reboot the pi, there will be a 5 minute delay between connections, but eventually it will hammer it.
Anyone else having this issue?
Successfully got this working on a pi zero with a smart battery (RBT100LFP12SH) and rover 40 mppt connected via separate bt1 and bt2 modules.
Battery stats are fine and some of the rover stats are good too, but many of the controller stats are zero:
I will see if I can debug the bytestream and report back, but for now here is the parsed payload:
DEBUG:root:BT-TH-Exxxxxxx => {'function': 'READ', 'model': 'RNG-CTRL-RVR', 'battery_percentage': 99, 'battery_voltage': 13.100000000000001, 'battery_current': 0.0, 'battery_temperature': 19, 'controller_temperature': 21, 'load_status': 'on', 'load_voltage': 13.100000000000001, 'load_current': 0.0, 'load_power': 0, 'pv_voltage': 14.0, 'pv_current': 0.0, 'pv_power': 0, 'max_charging_power_today': 6, 'max_discharging_power_today': 26, 'charging_amp_hours_today': 0, 'discharging_amp_hours_today': 1, 'power_generation_today': 0, 'power_consumption_today': 13, 'power_generation_total': 160652, 'charging_status': 'mppt', 'battery_type': 'lithium', '__device': 'BT-TH-Exxxxxxx', '__client': 'RoverClient'}
INFO:root:mqtt logging
INFO:root:Exit: Disconnecting device: BT-TH-Exxxxxxx [c4:xx:xx:xx:xx:xx]
Hello again. I've been running this project for a bit now and only made minor changes to the example file in the form of the code below:
import logging
import requests
import json
import time
from BTOneApp import BTOneApp
logging.basicConfig(level=logging.DEBUG)
def on_connected(app: BTOneApp):
app.poll_params() # OR app.set_load(1)
def on_data_received(app: BTOneApp, data):
data['ts'] = time.time_ns()
logging.debug(data)
requests_session = requests.session()
requests_session.headers.update({'Content-Type': 'application/json'})
requests_session.headers.update({'charset':'utf-8'})
requests_response = requests_session.post(url="https://<my domain>/webhook/solar", data=json.dumps(data))
#print(requests_response.content)
MAC_ADDR = "<my device>"
DEVICE_ALIAS = "<my device alias>"
bt1 = BTOneApp("hci0", MAC_ADDR, DEVICE_ALIAS, on_connected, on_data_received, 60)
bt1.connect()
And today I woke up with really weird statistics in my home assistant. I checked the logs, and instead of every 60 seconds, it was sending data every second or so. Here's a bit of that output:
2022-12-18T08:36:02.869414549Z INFO:root:on_data_received: response for read operation
2022-12-18T08:36:02.869585753Z DEBUG:root:{'function': 'READ', 'battery_percentage': 42, 'battery_voltage': 12.0, 'battery_current': 0.0, 'battery_temperature': 4, 'controller_temperature': 7, 'load_status': 'on', 'load_voltage': 12.0, 'load_current': 0.27, 'load_power': 3, 'pv_voltage': 12.100000000000001, 'pv_current': 0.0, 'pv_power': 0, 'max_charging_power_today': 0, 'max_discharging_power_today': 11, 'charging_amp_hours_today': 0, 'discharging_amp_hours_today': 5, 'power_generation_today': 0, 'power_consumption_today': 60, 'power_generation_total': 263491, 'charging_status': 'deactivated', 'ts': 1671352562869496073}
2022-12-18T08:36:02.870463166Z DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): <my domain>:443
2022-12-18T08:36:03.040157327Z DEBUG:urllib3.connectionpool:https://<my domain>:443 "POST /webhook/solar HTTP/1.1" 200 None
2022-12-18T08:36:03.041826780Z INFO:root:on_data_received: response for read operation
2022-12-18T08:36:03.042231327Z DEBUG:root:{'function': 'READ', 'battery_percentage': 34, 'battery_voltage': 11.8, 'battery_current': 1.06, 'battery_temperature': 7, 'controller_temperature': 11, 'load_status': 'on', 'load_voltage': 11.8, 'load_current': 0.8300000000000001, 'load_power': 9, 'pv_voltage': 22.1, 'pv_current': 0.58, 'pv_power': 13, 'max_charging_power_today': 12, 'max_discharging_power_today': 13, 'charging_amp_hours_today': 1, 'discharging_amp_hours_today': 6, 'power_generation_today': 11, 'power_consumption_today': 71, 'power_generation_total': 263502, 'charging_status': 'mppt', 'ts': 1671352563041834475}
2022-12-18T08:36:03.043185585Z DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): <my domain>:443
2022-12-18T08:36:03.133959861Z DEBUG:urllib3.connectionpool:https://<my domain>:443 "POST /webhook/solar HTTP/1.1" 200 None
2022-12-18T08:36:03.135823813Z INFO:root:on_data_received: response for read operation
2022-12-18T08:36:03.136212409Z DEBUG:root:{'function': 'READ', 'battery_percentage': 42, 'battery_voltage': 12.0, 'battery_current': 0.0, 'battery_temperature': 4, 'controller_temperature': 7, 'load_status': 'on', 'load_voltage': 12.0, 'load_current': 0.29, 'load_power': 3, 'pv_voltage': 12.100000000000001, 'pv_current': 0.0, 'pv_power': 0, 'max_charging_power_today': 0, 'max_discharging_power_today': 11, 'charging_amp_hours_today': 0, 'discharging_amp_hours_today': 5, 'power_generation_today': 0, 'power_consumption_today': 60, 'power_generation_total': 263491, 'charging_status': 'deactivated', 'ts': 1671352563135680121}
2022-12-18T08:36:03.137305871Z DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): <my domain>:443
2022-12-18T08:36:03.367598803Z DEBUG:urllib3.connectionpool:https://<my domain>:443 "POST /webhook/solar HTTP/1.1" 200 None
The worst part is, if you check power_generation_total
of each data set, it seems to repeatedly send old data. It goes from 263491
to 263502
(the correct value), back to 263491
. This completely throws off Home Assistants energy dashboard, and is now reporting my battery produced over 100kWh today alone haha.
I'll turn off the polling timeout for now and simply call the script in a set interval. If this is actually a problem with my code, please let me know. I am fairly certain the poll timer is somehow broken though.
Thanks again for this amazing project though. Makes sending data so much easier :)
I have the system running on my RPI4 and its tied into Node Red. Ultimate goal is a "wireless" weather station for my dad. BTW Thanks for this.
Looking to see if anyone has worked with the code to specifically control the load power? I want to sense the battery level, send a last gasp email to me before it goes down and then shut down PI and power before I drain bat to zero.
I see the modbus document talks about it but didn't see any specific write functions in the code.
I would like to just dump the output to a text file, or a local json file but I see no way to do that - a redirect "python example.py >>output.txt" does not work. The php post seems to work (code 200) but I am not skilled enough with php to have it dump to a file - how does it even execute on the server side? I presume $json_data is getting populated but a file_put_contents doesn't do anything. Likely my misunderstanding of how php works regarding dumping output to a local file on the server...
Thanks for any suggestions.
I have things up and running, and connecting successfully to my BT-2 adapter, but I'm not getting any on_data_received logs. I am connected to three 100AH batteries (daisy-chained.) Do the changes you made as part of #15 not work when daisy-chaining? As I say that, I realize I can test it out myself by just unplugging the input cable to the battery connected to my BT-2; I'll try that and report back asap.
Either way, having this report on all batteries attached to the module would be great.
Output:
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
DEBUG:root:create_request_payload 5000 => [48, 3, 19, 136, 0, 17, 5, 73]
INFO:root:characteristic_enable_notifications_succeeded
INFO:root:characteristic_write_value_succeeded
DEBUG:root:create_request_payload 5000 => [48, 3, 19, 136, 0, 17, 5, 73]
INFO:root:characteristic_write_value_succeeded
...
I can connect to the battery and retrieve data but with MQTT enabled i get the below error.
Any ideas?
INFO:root:Init BatteryClient: BT-TH =>
INFO:root:Adapter status - Powered: True
INFO:root:Starting discovery...
INFO:root:Devices found: 7
INFO:root:Found matching device BT-TH => []
INFO:root:[] Connected
INFO:root:[] Resolved services
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-
INFO:root:resolved services
DEBUG:root:create_request_payload 5000 => [255, 3, 19, 136, 0, 17, 20, 182]
INFO:root:characteristic_enable_notifications_succeeded
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
DEBUG:root:create_request_payload 5017 => [255, 3, 19, 153, 0, 17, 68, 179]
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
DEBUG:root:create_request_payload 5042 => [255, 3, 19, 178, 0, 6, 116, 181]
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
DEBUG:root:create_request_payload 5122 => [255, 3, 20, 2, 0, 8, 245, 226]
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
DEBUG:root:create_request_payload 5223 => [255, 3, 20, 103, 0, 1, 37, 251]
INFO:root:characteristic_write_value_succeeded
INFO:root:on_data_received: response for read operation
INFO:root:on_read_operation_complete
DEBUG:root:BT-TH=> {'function': 'READ', 'cell_count': 4, 'cell_voltage_0': 3.3, 'cell_voltage_1': 3.3, 'cell_voltage_2': 3.3, 'cell_voltage_3': 3.3, 'sensor_count': 2, 'temperature_0': 13.0, 'temperature_1': 13.0, 'current': 0.0, 'voltage': 13.3, 'remaining_charge': 199.2, 'capacity': 200.0, 'model': 'RBT200LFP12-BT', 'device_id': 33, '__device': 'BT-TH', '__client': 'BatteryClient'}
INFO:root:mqtt logging
ERROR:dbus.connection:Exception in handler for D-Bus signal:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/dbus/connection.py", line 218, in maybe_handle_message
self._handler(*args, **kwargs)
File "/usr/local/lib/python3.11/dist-packages/gatt/gatt_linux.py", line 539, in properties_changed
self.service.device.characteristic_value_updated(characteristic=self, value=bytes(value))
File "/home/pi/renogy-bt/renogybt/BLE.py", line 86, in characteristic_value_updated
self.data_callback(value)
File "/home/pi/renogy-bt/renogybt/BaseClient.py", line 74, in on_data_received
self.on_read_operation_complete()
File "/home/pi/renogy-bt/renogybt/BaseClient.py", line 88, in on_read_operation_complete
self.on_data_callback(self, self.data)
File "/home/pi/renogy-bt/./example.py", line 22, in on_data_received
data_logger.log_mqtt(json_data=filtered_data)
File "/home/pi/renogy-bt/renogybt/DataLogger.py", line 25, in log_mqtt
publish.single(
File "/usr/local/lib/python3.11/dist-packages/paho/mqtt/publish.py", line 240, in single
multiple([msg], hostname, port, client_id, keepalive, will, auth, tls,
File "/usr/local/lib/python3.11/dist-packages/paho/mqtt/publish.py", line 176, in multiple
client.connect(hostname, port, keepalive)
File "/usr/local/lib/python3.11/dist-packages/paho/mqtt/client.py", line 914, in connect
return self.reconnect()
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/paho/mqtt/client.py", line 1044, in reconnect
sock = self._create_socket_connection()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/paho/mqtt/client.py", line 3685, in _create_socket_connection
return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/socket.py", line 851, in create_connection
raise exceptions[0]
File "/usr/lib/python3.11/socket.py", line 836, in create_connection
sock.connect(sa)
TimeoutError: timed out
I forgot to mention its the latest copy.
Hi, Is it possible to run 2 config files at same time and if so, how?
I can run them both individually config1.ini and config.ini
The reason I have to do this is because I am using both Bt1 and Bt2 devices.
closed user error
My battery temperatures have been reporting at 11,000+ degrees f, given the lack of fires I believe this to be false.
I think the issue is that the battery temperature returns a signed int, and it's being handled as if it's unsigned.
switching line 37 of BatteryClient.py to
celcius = bytes_to_int(bs, 5 + i*2, 2, scale = 0.1, signed=True)
seems to have it reporting more reasonable temperatures.
I've been using your repo on a very old raspberry pi model B v 2.0 running Linux raspberry pi 6.1.21+ with great success. I had to use a USB dongle for Bluetooth, but it worked without a hitch.
I recently upgraded to a raspberry pi model 4B running Linux raspberrypi 6.1.0-rpi6-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.58-1+rpt2, and I cant for the life of me get connected. The error message comes from gatt I believe, and isn't very helpful:
(.venv) pi@raspberrypi:~/renogy-bt $ python example.py INFO:root:Init RoverClient: BT-TH-774B0D88 => f4:60:77:4b:0d:88 INFO:root:Adapter status - Powered: True INFO:root:Starting discovery... INFO:root:Devices found: 16 INFO:root:Found matching device BT-TH-774B0D88 => [f4:60:77:4b:0d:88] ERROR:root:Connection failed: le-connection-abort-by-local
I've tried using both the pi 4's native Bluetooth hardware and the old functioning Bluetooth dongle with similar results. bluetooth, bluez, and gatt are all the most recent versions.
Also tried:
Any advice in terms of avenues I should pursue for further debugging?
Hi
running the example I faced this errors.
`
INFO:root:Devices found: 4
INFO:root:Found matching device BT-TH-EAxxx => [e0:7d:ea:83xxx]
INFO:root:[E0:7D:EA:83:xx] Connected
INFO:root:[E0:7D:EA:83:xx] Resolved services
INFO:root:subscribed to notification 0000fff1-0000-1000-8000-00805f9b34fb
INFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
ERROR:root:base client cannot be used directly
INFO:root:characteristic_enable_notifications_succeeded
ERROR:dbus.connection:Exception in handler for D-Bus signal:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/dbus/connection.py", line 232, in maybe_handle_message
self._handler(*args, **kwargs)
File "/home/pi/.local/lib/python3.9/site-packages/gatt/gatt_linux.py", line 539, in properties_changed
self.service.device.characteristic_value_updated(characteristic=self, value=bytes(value))
File "/opt/renogy-bt/renogybt/BLE.py", line 86, in characteristic_value_updated
self.data_callback(value)
File "/opt/renogy-bt/renogybt/RoverClient.py", line 58, in on_data_received
super().on_data_received(response)
File "/opt/renogy-bt/renogybt/BaseClient.py", line 61, in on_data_received
self.read_timer.cancel()
AttributeError: 'NoneType' object has no attribute 'cancel'
NFO:root:found write characteristic 0000ffd1-0000-1000-8000-00805f9b34fb
INFO:root:resolved services
ERROR:root:base client cannot be used directly
INFO:root:characteristic_enable_notifications_succeeded
ERROR:dbus.connection:Exception in handler for D-Bus signal:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/dbus/connection.py", line 232, in maybe_handle_message
self._handler(*args, **kwargs)
File "/home/pi/.local/lib/python3.9/site-
'
thanks T
hey i have been unable to get this to funtion on my pi zero i cant complet the config
Hi
Is there an option to migrate this to esphome?
Thanks
Hello!
First of, I would like to thank you for this project. I use it to send off data updates to InfluxDB and Home Assistant :)
Now, to the problem. Its getting quite cold, and the temperature at the battery probe went below 0°C.
It's unclear whether this is the Rover 20a having a problem, or how the data is retrieved. Just to make sure I'm opening this ticket. I checked both InfluxDB and Home Assistant and they both report the same value. I then went ahead and checked the webhook I use to receive the data I'm sending with your neat project, and my code doesn't seem to change any negative values (I sent mock data to check and it works perfectly), so that leaves me to believe it might be a bug in your code. If I knew more about python I'd have a look but it's not really my forte haha.
The resulting graph from last night looks like this haha
It went up to 129°C, which looks like an underflow to me.
If you need any more information, I'm happy to help out with whatever you need.
EDIT: Here's the raw data: It goes from 0 directly to 129°C.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.