Skip to content

Commit

Permalink
Added telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
mr-manuel committed Jul 21, 2024
1 parent 94b1ce1 commit 122d928
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
* Added: `History()` class that holds all BMS history values by @mr-manuel
* Added: Automatically increase polling time, if polling take too long by @mr-manuel
* Added: Multiple BMS on one USB to RS485/Modbus adapter now possible. The BMS needs to be able to set different addresses to each battery by @mr-manuel
* Added: Send telemetry data to see which driver versions and BMS are used the most. Can be disabled in the `config.ini` by @mr-manuel
* Changed: Call `get_settings()` in `test_connection()` for all battery classes, removed `get_settings()` call from `setup_vedbus()` by @mr-manuel
* Changed: Fixed alarms for some BMS and cleaned up `Protection()` class
* Changed: Fixed how `velib_python` was integrated in this driver by @mr-manuel
Expand Down
4 changes: 4 additions & 0 deletions etc/dbus-serialbattery/battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ def __init__(self, port: str, baud: int, address: str):
self.online: bool = True
self.hardware_version: str = None
self.cell_count: int = None
self.start_time: int = int(time())
"""
Timestamp of when the battery was initialized
"""
# max battery charge/discharge current
self.max_battery_charge_current: float = utils.MAX_BATTERY_CHARGE_CURRENT
self.max_battery_discharge_current: float = utils.MAX_BATTERY_DISCHARGE_CURRENT
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/bms/daly_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(self, port, baud, address):
response_cell_balance = 0x18974001
response_alarm = 0x18984001

BATTERYTYPE = "Daly_Can"
BATTERYTYPE = "Daly CAN"
LENGTH_CHECK = 4
LENGTH_POS = 3
CURRENT_ZERO_CONSTANT = 30000
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/bms/ecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __init__(self, port, baud, address):
super(Ecs, self).__init__(port, baud, address)
self.type = self.BATTERYTYPE

BATTERYTYPE = "ECS_LiPro"
BATTERYTYPE = "ECS LiPro"
GREENMETER_ID_500A = 500
GREENMETER_ID_250A = 501
GREENMETER_ID_125A = 502
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/bms/jkbms_ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


class Jkbms_Ble(Battery):
BATTERYTYPE = "Jkbms_Ble"
BATTERYTYPE = "JKBMS BLE"
resetting = False

def __init__(self, port, baud, address):
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/bms/jkbms_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __del__(self):
self.can_bus = False
logger.debug("bus shutdown")

BATTERYTYPE = "Jkbms_Can"
BATTERYTYPE = "JKBMS CAN"
CAN_BUS_TYPE = "socketcan"

CURRENT_ZERO_CONSTANT = 400
Expand Down
2 changes: 1 addition & 1 deletion etc/dbus-serialbattery/bms/lltjbd_ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class LltJbd_Ble(LltJbd):
BATTERYTYPE = "LltJbd_Ble"
BATTERYTYPE = "LLT/JBD BLE"

def __init__(self, port: Optional[str], baud: Optional[int], address: str):
super(LltJbd_Ble, self).__init__(port, -1, address)
Expand Down
6 changes: 6 additions & 0 deletions etc/dbus-serialbattery/config.default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,12 @@ TEMP_4_NAME = Temp 4
; You have to scroll down to see the additional information
GUI_PARAMETERS_SHOW_ADDITIONAL_INFO = False

; Telemetry settings
; To help us improve the driver, we are collecting telemetry data. This data is anonymous and
; will only be used to improve the driver. The data is send once every week.
; You can disable this feature by setting this value to False.
; Some data we collect: Venus OS version, driver version, driver runtime, battery type, battery count,
TELEMETRY = True

; --------- BMS specific settings ---------

Expand Down
110 changes: 110 additions & 0 deletions etc/dbus-serialbattery/dbushelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
from utils import logger, publish_config_variables
import utils
from xml.etree import ElementTree
import requests
import threading

# add path to velib_python
sys.path.insert(1, os.path.join(os.path.dirname(__file__), "ext", "velib_python"))
from vedbus import VeDbusService # noqa: E402
from ve_utils import get_vrm_portal_id # noqa: E402
from settingsdevice import SettingsDevice # noqa: E402


Expand Down Expand Up @@ -58,6 +61,10 @@ def __init__(self, battery, bms_address=None):
self.battery.soc_calc if self.battery.soc_calc is not None else ""
),
}
self.telemetry_upload_error_count: int = 0
self.telemetry_upload_interval: int = 60 * 60 * 24 * 7 # 1 week
self.telemetry_upload_last: int = 0
self.telemetry_upload_running: bool = False

def create_pid_file(self) -> None:
"""
Expand Down Expand Up @@ -874,6 +881,9 @@ def publish_battery(self, loop):
# publish all the data from the battery object to dbus
self.publish_dbus()

# upload telemetry data
self.telemetry_upload()

except Exception:
traceback.print_exc()
loop.quit()
Expand Down Expand Up @@ -1420,3 +1430,103 @@ def saveCurrentBatteryState(self) -> bool:
)

return result

def telemetry_upload(self) -> None:
"""
Check if telemetry should be uploaded
"""
if utils.TELEMETRY:
# check if telemetry should be uploaded
if (
not self.telemetry_upload_running
and self.telemetry_upload_last + self.telemetry_upload_interval
< int(time())
):
self.telemetry_upload_thread = threading.Thread(
target=self.telemetry_upload_async
)
self.telemetry_upload_thread.start()

def telemetry_upload_async(self) -> None:
"""
Run telemetry upload in a separate thread
"""
self.telemetry_upload_running = True

# logger.info("Uploading telemetry data")

# read the version of Venus OS
with open("/opt/victronenergy/version", "r") as f:
venus_version = f.readline().strip()

# assemble the data to be uploaded
data = {
"vrm_id": get_vrm_portal_id(),
"venus_os_version": venus_version,
"driver_version": utils.DRIVER_VERSION,
"device_instance": self.instance,
"bms_type": self.battery.type,
"cell_count": self.battery.cell_count,
"connection_type": self.battery.connection_name(),
"driver_runtime": int(time()) - self.battery.start_time,
"error_code": (
self.battery.error_code if self.battery.error_code is not None else 0
),
}

# post data to the server as json
try:
response = requests.post(
"https://github.md0.eu/venus-os_dbus-serialbattery/telemetry.php",
data=data,
timeout=60,
# verify=False,
)
response.raise_for_status()

self.telemetry_upload_error_count = 0
self.telemetry_upload_last = int(time())

# logger.info(f"Telemetry uploaded: {response.text}")

except Exception:
self.telemetry_upload_error_count += 1

"""
(
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(
"Non blocking exception occurred: "
+ f"{repr(exception_object)} of type {exception_type} in {file} line #{line}"
)
"""

if self.telemetry_upload_error_count >= 5:
self.telemetry_upload_error_count = 0
self.telemetry_upload_last = int(time())

# logger.error(
# "Failed to upload telemetry 5 times."
# + f"Retry on next interval in {self.telemetry_upload_interval} s."
# )
else:

# Check if the main thread is still alive
#
main_thread = threading.main_thread()

# Wait 59 minutes before retrying
sleep_time = 60 * 59
sleep_count = 0

while main_thread.is_alive() and sleep_count < sleep_time:
# wait 14 minutes before retrying, 1 minute request timeout, 14 minutes sleep
sleep(1)
sleep_count += 1

self.telemetry_upload_running = False
4 changes: 3 additions & 1 deletion etc/dbus-serialbattery/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


# CONSTANTS
DRIVER_VERSION: str = "1.4.20240719dev"
DRIVER_VERSION: str = "1.4.20240721dev"
"""
current version of the driver
"""
Expand Down Expand Up @@ -414,6 +414,8 @@ def _get_list_from_config(
TEMP_3_NAME: str = config["DEFAULT"]["TEMP_3_NAME"]
TEMP_4_NAME: str = config["DEFAULT"]["TEMP_4_NAME"]

TELEMETRY: bool = "True" == config["DEFAULT"]["TELEMETRY"]

GUI_PARAMETERS_SHOW_ADDITIONAL_INFO: bool = (
"True" == config["DEFAULT"]["GUI_PARAMETERS_SHOW_ADDITIONAL_INFO"]
)
Expand Down

0 comments on commit 122d928

Please sign in to comment.