Skip to content

Commit

Permalink
LLT/JBD BMS - Improved error handling and automatical driver restart
Browse files Browse the repository at this point in the history
in case of error. Should fix:
- Louisvdw#730
- Louisvdw#769
- Louisvdw#777
  • Loading branch information
mr-manuel committed Sep 5, 2023
1 parent b2b465e commit 044f066
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 24 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Added: Temperature names to dbus and mqtt by @mr-manuel
* Added: Use current average of the last 300 cycles for time to go and time to SoC calculation by @mr-manuel
* Added: Validate current, voltage, capacity and SoC for all BMS. This prevents that a device, which is no BMS, is detected as BMS. Fixes also https://github.com/Louisvdw/dbus-serialbattery/issues/479 by @mr-manuel
* Changed: Daly BMS - Fix readsentence by @transistorgit
* Changed: Enable BMS that are disabled by default by specifying it in the config file. No more need to edit scripts by @mr-manuel
* Changed: Fix daly readsentence by @transistorgit
* Changed: Fix Sinowealth not loading https://github.com/Louisvdw/dbus-serialbattery/issues/702 by @mr-manuel
Expand All @@ -26,11 +27,14 @@
* Changed: Improved battery voltage handling in linear absorption mode by @ogurevich
* Changed: Improved driver disable script by @md-manuel
* Changed: Improved driver reinstall when multiple Bluetooth BMS are enabled by @mr-manuel
* Changed: Improved Jkbms_Ble driver by @seidler2547 & @mr-manuel
* Changed: LLT/JBD - Fix cycle capacity with https://github.com/Louisvdw/dbus-serialbattery/pull/762 by @idstein
* Changed: JKBMS_BLE BMS - Improved driver by @seidler2547 & @mr-manuel
* Changed: LLT/JBD BMS - Fix cycle capacity with https://github.com/Louisvdw/dbus-serialbattery/pull/762 by @idstein
* Changed: LLT/JBD BMS - Fixed https://github.com/Louisvdw/dbus-serialbattery/issues/778 with https://github.com/Louisvdw/dbus-serialbattery/pull/798 by @idstein
* Changed: LLT/JBD BMS - Improved error handling and automatical driver restart in case of error. Should fix https://github.com/Louisvdw/dbus-serialbattery/issues/730, https://github.com/Louisvdw/dbus-serialbattery/issues/769 and https://github.com/Louisvdw/dbus-serialbattery/issues/777 by @mr-manuel
* Changed: LLT/JBD BMS - SOC different in Xiaoxiang app and dbus-serialbattery with https://github.com/Louisvdw/dbus-serialbattery/pull/760 by @idstein
* Changed: Make CCL and DCL limiting messages more clear by @mr-manuel
* Changed: Reduce the big inrush current if the CVL jumps from Bulk/Absorbtion to Float https://github.com/Louisvdw/dbus-serialbattery/issues/659 by @Rikkert-RS & @ogurevich
* Changed: Sinowealth BMS - Fix not loading https://github.com/Louisvdw/dbus-serialbattery/issues/702 by @mr-manuel
* Changed: Time-to-Go and Time-to-SoC use the current average of the last 5 minutes for calculation by @mr-manuel
* Changed: Time-to-SoC calculate only positive points by @mr-manuel
* Removed: Cronjob to restart Bluetooth service every 12 hours by @mr-manuel
Expand Down
126 changes: 108 additions & 18 deletions etc/dbus-serialbattery/bms/lltjbd_ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
import asyncio
import atexit
import functools
import os
import threading
import sys
from asyncio import CancelledError
from time import sleep
from typing import Union, Optional
from utils import logger
from bleak import BleakClient, BleakScanner, BLEDevice
from bleak.exc import BleakDBusError
from bms.lltjbd import LltJbdProtection, LltJbd

BLE_SERVICE_UUID = "0000ff00-0000-1000-8000-00805f9b34fb"
Expand Down Expand Up @@ -62,25 +65,66 @@ async def bt_main_loop(self):
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"Exception occurred: {repr(exception_object)} of type {exception_type} in {file} line #{line}"
f"BleakScanner(): Exception occurred: {repr(exception_object)} of type {exception_type} "
f"in {file} line #{line}"
)
self.device = None
await asyncio.sleep(0.5)
# allow the bluetooth connection to recover
sleep(5)

if not self.device:
self.run = False
return

async with BleakClient(
self.device, disconnected_callback=self.on_disconnect
) as client:
self.bt_client = client
self.bt_loop = asyncio.get_event_loop()
self.response_queue = asyncio.Queue()
self.ready_event.set()
while self.run and client.is_connected and self.main_thread.is_alive():
await asyncio.sleep(0.1)
self.bt_loop = None
try:
async with BleakClient(
self.device, disconnected_callback=self.on_disconnect
) as client:
self.bt_client = client
self.bt_loop = asyncio.get_event_loop()
self.response_queue = asyncio.Queue()
self.ready_event.set()
while self.run and client.is_connected and self.main_thread.is_alive():
await asyncio.sleep(0.1)
self.bt_loop = None

# Exception occurred: TimeoutError() of type <class 'asyncio.exceptions.TimeoutError'>
except asyncio.exceptions.TimeoutError:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"BleakClient(): asyncio.exceptions.TimeoutError: {repr(exception_object)} of type {exception_type} "
f"in {file} line #{line}"
)
# needed?
self.run = False
return

except TimeoutError:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"BleakClient(): TimeoutError: {repr(exception_object)} of type {exception_type} "
f"in {file} line #{line}"
)
# needed?
self.run = False
return

except Exception:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"BleakClient(): Exception occurred: {repr(exception_object)} of type {exception_type} "
f"in {file} line #{line}"
)
# needed?
self.run = False
return

def background_loop(self):
while self.run and self.main_thread.is_alive():
Expand Down Expand Up @@ -117,8 +161,13 @@ def test_connection(self):
result = super().test_connection()
if not result:
logger.error("No BMS found at " + self.address)
except Exception as err:
logger.error(f"Unexpected {err=}, {type(err)=}")
except Exception:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"Exception occurred: {repr(exception_object)} of type {exception_type} in {file} line #{line}"
)
result = False

return result
Expand Down Expand Up @@ -161,8 +210,23 @@ async def async_read_serial_data_llt(self, command):
except asyncio.TimeoutError:
logger.error(">>> ERROR: No reply - returning")
return False
except Exception as e:
logger.error(">>> ERROR: No reply - returning", e)
except BleakDBusError:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"BleakDBusError: {repr(exception_object)} of type {exception_type} in {file} line #{line}"
)
self.reset_bluetooth()
return False
except Exception:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"Exception occurred: {repr(exception_object)} of type {exception_type} in {file} line #{line}"
)
self.reset_bluetooth()
return False

def read_serial_data_llt(self, command):
Expand All @@ -172,12 +236,38 @@ def read_serial_data_llt(self, command):
data = asyncio.run(self.async_read_serial_data_llt(command))
return self.validate_packet(data)
except CancelledError as e:
logger.error(">>> ERROR: No reply - canceled - returning", e)
logger.error(">>> ERROR: No reply - canceled - returning")
logger.error(e)
return False
except Exception as e:
logger.error(">>> ERROR: No reply - returning", e)
# except Exception as e:
# logger.error(">>> ERROR: No reply - returning")
# logger.error(e)
# return False
except Exception:
exception_type, exception_object, exception_traceback = sys.exc_info()
file = exception_traceback.tb_frame.f_code.co_filename
line = exception_traceback.tb_lineno
logger.error(
f"Exception occurred: {repr(exception_object)} of type {exception_type} in {file} line #{line}"
)
return False

def reset_bluetooth(self):
logger.error("Reset of system Bluetooth daemon triggered")
self.bt_loop = False

# process kill is needed, since the service/bluetooth driver is probably freezed
# os.system('pkill -f "bluetoothd"')
# stop will not work, if service/bluetooth driver is stuck
os.system("/etc/init.d/bluetooth stop")
sleep(2)
os.system("rfkill block bluetooth")
os.system("rfkill unblock bluetooth")
os.system("/etc/init.d/bluetooth start")
logger.error("System Bluetooth daemon should have been restarted")
sleep(5)
sys.exit(1)


if __name__ == "__main__":
bat = LltJbd_Ble("Foo", -1, sys.argv[1])
Expand Down
13 changes: 10 additions & 3 deletions etc/dbus-serialbattery/reinstall-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,16 @@ if [ "$length" -gt 0 ]; then
opkg install python3-misc python3-pip

echo
pip3 install bleak==0.20.2
# pip3 install bleak==0.21.0

pip3 install bleak

# # ONLY FOR TESTING if there are version issues
# echo
# echo "Available bleak versions:"
# curl --silent https://api.github.com/repos/hbldh/bleak/releases | grep '"name": "v' | sed "s/ \"name\": \"v//g" | sed "s/\",//g"
# echo
# read -r -p "Specify the bleak version to install: " bleak_version
# pip3 install bleak=="$bleak_version"
# echo
echo
pip3 install dbus-fast==1.87.0
# pip3 install dbus-fast==1.87.3
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pyserial==3.5
minimalmodbus==2.0.1
bleak==0.20.2
bleak==0.21.0
dbus-fast==1.94.1

0 comments on commit 044f066

Please sign in to comment.