Skip to content

Commit

Permalink
JDB BLE support (#499)
Browse files Browse the repository at this point in the history
* Implementing JBD BLE support. It is built upon Bleak
* Additionally, it provides some handling of for up to 4 temperature probes labels T1 (NTC2), T2 (NTC3), T3 (NTC4) and T4 (NTC5). NTC1 is the BMS module temperature itself
* The device page has been extend to provide more details about the actual used hardware (= product name), firmware version and BLE address
  • Loading branch information
idstein authored May 23, 2023
1 parent c0056c6 commit bb93ee3
Show file tree
Hide file tree
Showing 8 changed files with 408 additions and 73 deletions.
104 changes: 81 additions & 23 deletions etc/dbus-serialbattery/battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ def init_values(self):
self.temp_sensors = None
self.temp1 = None
self.temp2 = None
self.temp3 = None
self.temp4 = None
self.temp_mos = None
self.cells: List[Cell] = []
self.control_charging = None
Expand Down Expand Up @@ -127,6 +129,15 @@ def test_connection(self) -> bool:
# return false when failed, true if successful
return False

def connection_name(self) -> str:
return "Serial " + self.port

def custom_name(self) -> str:
return "SerialBattery(" + self.type + ")"

def product_name(self) -> str:
return "SerialBattery(" + self.type + ")"

@abstractmethod
def get_settings(self) -> bool:
"""
Expand Down Expand Up @@ -164,6 +175,10 @@ def to_temp(self, sensor: int, value: float) -> None:
self.temp1 = min(max(value, -20), 100)
if sensor == 2:
self.temp2 = min(max(value, -20), 100)
if sensor == 3:
self.temp3 = min(max(value, -20), 100)
if sensor == 4:
self.temp4 = min(max(value, -20), 100)

def manage_charge_voltage(self) -> None:
"""
Expand Down Expand Up @@ -808,14 +823,10 @@ def get_balancing(self) -> int:
return 1
return 0

def extract_from_temp_values(self, extractor) -> Union[float, None]:
if self.temp1 is not None and self.temp2 is not None:
return extractor(self.temp1, self.temp2)
if self.temp1 is not None and self.temp2 is None:
return self.temp1
if self.temp1 is None and self.temp2 is not None:
return self.temp2
else:
def get_temperatures(self) -> Union[List[float], None]:
temperatures = [self.temp1, self.temp2, self.temp3, self.temp4]
result = [(t, i) for (t, i) in enumerate(temperatures) if t is not None]
if not result:
return None

def get_temp(self) -> Union[float, None]:
Expand All @@ -824,46 +835,93 @@ def get_temp(self) -> Union[float, None]:
return self.temp1
elif utils.TEMP_BATTERY == 2:
return self.temp2
elif utils.TEMP_BATTERY == 3:
return self.temp3
elif utils.TEMP_BATTERY == 4:
return self.temp4
else:
return self.extract_from_temp_values(
extractor=lambda temp1, temp2: round(
(float(temp1) + float(temp2)) / 2, 2
)
)
temps = [
t
for t in [self.temp1, self.temp2, self.temp3, self.temp4]
if t is not None
]
n = len(temps)
if not temps or n == 0:
return None
data = sorted(temps)
if n % 2 == 1:
return data[n // 2]
else:
i = n // 2
return (data[i - 1] + data[i]) / 2
except TypeError:
return None

def get_min_temp(self) -> Union[float, None]:
try:
return self.extract_from_temp_values(
extractor=lambda temp1, temp2: min(temp1, temp2)
)
temps = [
t
for t in [self.temp1, self.temp2, self.temp3, self.temp4]
if t is not None
]
if not temps:
return None
return min(temps)
except TypeError:
return None

def get_min_temp_id(self) -> Union[str, None]:
try:
if self.temp1 < self.temp2:
temps = [
(t, i)
for i, t in enumerate([self.temp1, self.temp2, self.temp3, self.temp4])
if t is not None
]
if not temps:
return None
index = min(temps)[1]
if index == 0:
return utils.TEMP_1_NAME
else:
if index == 1:
return utils.TEMP_2_NAME
if index == 2:
return utils.TEMP_3_NAME
if index == 3:
return utils.TEMP_4_NAME
except TypeError:
return None

def get_max_temp(self) -> Union[float, None]:
try:
return self.extract_from_temp_values(
extractor=lambda temp1, temp2: max(temp1, temp2)
)
temps = [
t
for t in [self.temp1, self.temp2, self.temp3, self.temp4]
if t is not None
]
if not temps:
return None
return max(temps)
except TypeError:
return None

def get_max_temp_id(self) -> Union[str, None]:
try:
if self.temp1 > self.temp2:
temps = [
(t, i)
for i, t in enumerate([self.temp1, self.temp2, self.temp3, self.temp4])
if t is not None
]
if not temps:
return None
index = max(temps)[1]
if index == 0:
return utils.TEMP_1_NAME
else:
if index == 1:
return utils.TEMP_2_NAME
if index == 2:
return utils.TEMP_3_NAME
if index == 3:
return utils.TEMP_4_NAME
except TypeError:
return None

Expand Down
Loading

0 comments on commit bb93ee3

Please sign in to comment.