Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes 2023.09.05 #799

Merged
merged 3 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@
* 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
* Changed: Fixed Building wheel for dbus-fast won't finish on weak systems https://github.com/Louisvdw/dbus-serialbattery/issues/785 by @mr-manuel
* Changed: Fixed error in `reinstall-local.sh` script for Bluetooth installation by @mr-manuel
* Changed: Fixed meaningless Time to Go values by @transistorgit
* Changed: Fixed typo in `config.ini` sample by @hoschult
* Changed: For BMS_TYPE now multiple BMS can be specified by @mr-manuel
* Changed: Improved battery error handling on connection loss by @mr-manuel
* 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
14 changes: 11 additions & 3 deletions etc/dbus-serialbattery/disable.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ bash /opt/victronenergy/swupdate-scripts/remount-rw.sh

# remove driver from serial starter
rm -f /data/conf/serial-starter.d/dbus-serialbattery.conf
# remove serial-starter.d if empty
rmdir /data/conf/serial-starter.d >/dev/null 2>&1
# kill serial starter, to reload changes
pkill -f "/opt/victronenergy/serial-starter/serial-starter.sh"

Expand All @@ -16,14 +18,20 @@ rm -rf /service/dbus-serialbattery.*
rm -rf /service/dbus-blebattery.*

# kill driver, if running
pkill -f "dbus-serialbattery"
pkill -f "dbus-blebattery"
# serial
pkill -f "supervise dbus-serialbattery.*"
pkill -f "multilog .* /var/log/dbus-serialbattery.*"
pkill -f "python .*/dbus-serialbattery.py /dev/tty.*"
# bluetooth
pkill -f "supervise dbus-blebattery.*"
pkill -f "multilog .* /var/log/dbus-blebattery.*"
pkill -f "python .*/dbus-serialbattery.py .*_Ble"

# remove install script from rc.local
sed -i "/bash \/data\/etc\/dbus-serialbattery\/reinstall-local.sh/d" /data/rc.local

# remove cronjob
sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root
sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root >/dev/null 2>&1


### needed for upgrading from older versions | start ###
Expand Down
41 changes: 34 additions & 7 deletions etc/dbus-serialbattery/reinstall-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ if [ ! -f "$filename" ]; then
fi

# kill driver, if running. It gets restarted by the service daemon
pkill -f "supervise dbus-serialbattery.*"
pkill -f "multilog .* /var/log/dbus-serialbattery.*"
pkill -f "python .*/dbus-serialbattery.py /dev/tty.*"


Expand Down Expand Up @@ -168,22 +170,47 @@ if [ "$length" -gt 0 ]; then
echo "Found $length Bluetooth BMS in the config file!"
echo

/etc/init.d/bluetooth stop
echo

# install required packages
# TO DO: Check first if packages are already installed
echo "Installing required packages to use Bluetooth connection..."

# dbus-fast: skip compiling/building the wheel
# else weak system crash and are not able to install it,
# see https://github.com/Bluetooth-Devices/dbus-fast/issues/237
# and https://github.com/Louisvdw/dbus-serialbattery/issues/785
export SKIP_CYTHON=false

opkg update
opkg install python3-misc python3-pip

echo
pip3 install bleak
# pip3 install bleak==0.20.2
# pip3 install bleak==0.21.0
pip3 install dbus-fast==1.87.0
# pip3 install dbus-fast==1.87.3
# pip3 install dbus-fast==1.87.4

# # 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
# echo "Available dbus-fast versions:"
# curl --silent https://api.github.com/repos/Bluetooth-Devices/dbus-fast/releases | grep '"name": "v' | sed "s/ \"name\": \"v//g" | sed "s/\",//g"
# echo
# read -r -p "Specify the dbus-fast version to install: " dbus_fast_version
# pip3 install dbus-fast=="$dbus_fast_version"
# echo

echo "done."
echo

/etc/init.d/bluetooth start
echo

# function to install ble battery
install_blebattery_service() {
if [ -z "$1" ]; then
Expand Down Expand Up @@ -253,12 +280,12 @@ if [ "$length" -gt 0 ]; then
# grep -qxF "5 0,12 * * * /etc/init.d/bluetooth restart" /var/spool/cron/root || echo "5 0,12 * * * /etc/init.d/bluetooth restart" >> /var/spool/cron/root

# remove cronjob
sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root
sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root >/dev/null 2>&1

else

# remove cronjob
sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root
sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root >/dev/null 2>&1

echo
echo "No Bluetooth battery configuration found in \"/data/etc/dbus-serialbattery/config.ini\"."
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def _get_list_from_config(


# Constants
DRIVER_VERSION = "1.0.20230904dev"
DRIVER_VERSION = "1.0.20230905dev"
zero_char = chr(48)
degree_sign = "\N{DEGREE SIGN}"

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