Skip to content
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
6 changes: 2 additions & 4 deletions src/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,10 @@ def __should_poll(self) -> bool:
if len(refresh_modes) == 0 or all(
mode == RefreshMode.OFF for mode in refresh_modes
):
logging.debug(
"Not checking for new messages as all cars have RefreshMode.OFF"
)
LOG.debug("Not checking for new messages as all cars have RefreshMode.OFF")
return False
if self.relogin_handler.relogin_in_progress:
logging.warning(
LOG.warning(
"Not checking for new messages as we are waiting to log back in"
)
return False
Expand Down
6 changes: 2 additions & 4 deletions src/handlers/relogin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def relogin_in_progress(self) -> bool:

def relogin(self) -> None:
if self.__login_task is None:
logging.warning(
LOG.warning(
f"API Client got logged out, logging back in {self.__relogin_relay} seconds"
)
self.__login_task = self.__scheduler.add_job(
Expand All @@ -45,9 +45,7 @@ async def login(self) -> None:
login_response_message = await self.__api.login()
LOG.info("Logged in as %s", login_response_message.account)
except Exception as e:
logging.exception(
"Could not login to the SAIC API due to an error", exc_info=e
)
LOG.exception("Could not login to the SAIC API due to an error", exc_info=e)
raise e
finally:
if self.__scheduler.get_job(JOB_ID) is not None:
Expand Down
6 changes: 3 additions & 3 deletions src/handlers/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@
vehicle_status_processing_result,
) = await self.update_vehicle_status()

charge_status = None
charge_status_processing_result = None
if self.vin_info.is_ev:
try:
(
Expand All @@ -158,8 +160,6 @@
) = await self.update_charge_status()
except Exception as e:
LOG.exception("Error updating charge status", exc_info=e)
charge_status = None
charge_status_processing_result = None

try:
await self.update_scheduled_battery_heating_status()
Expand Down Expand Up @@ -267,7 +267,7 @@
)
return scheduled_battery_heating_status

async def handle_mqtt_command(self, *, topic: str, payload: str) -> None:

Check failure on line 270 in src/handlers/vehicle.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Ruff (PLR0915)

src/handlers/vehicle.py:270:15: PLR0915 Too many statements (244 > 50)

Check failure on line 270 in src/handlers/vehicle.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Ruff (C901)

src/handlers/vehicle.py:270:15: C901 `handle_mqtt_command` is too complex (61 > 13)

Check failure on line 270 in src/handlers/vehicle.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Ruff (PLR0915)

src/handlers/vehicle.py:270:15: PLR0915 Too many statements (244 > 50)

Check failure on line 270 in src/handlers/vehicle.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Ruff (C901)

src/handlers/vehicle.py:270:15: C901 `handle_mqtt_command` is too complex (61 > 13)
topic, result_topic = self.__get_command_topics(topic)
try:
should_force_refresh = True
Expand Down Expand Up @@ -477,7 +477,7 @@
msg = f"Error setting value for payload {payload}"
raise MqttGatewayException(msg) from e
else:
logging.info(
LOG.info(
"Unknown Target SOC: waiting for state update before changing charge current limit"
)
msg = f"Error setting charge current limit - SOC {self.vehicle_state.target_soc}"
Expand Down
2 changes: 1 addition & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Enable fault handler to get a thread dump on SIGQUIT
faulthandler.enable(file=sys.stderr, all_threads=True)
if hasattr(faulthandler, "register"):
if hasattr(faulthandler, "register") and hasattr(signal, "SIGQUIT"):
faulthandler.register(signal.SIGQUIT, chain=False)
configuration = process_arguments()

Expand Down
2 changes: 1 addition & 1 deletion src/publisher/mqtt_publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def __publish(self, topic: str, payload: Any) -> None:

@override
def is_connected(self) -> bool:
return cast(bool, self.client.is_connected)
return cast("bool", self.client.is_connected)

@override
def publish_json(
Expand Down
32 changes: 16 additions & 16 deletions src/status_publisher/charge/rvs_charge_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,40 +114,40 @@ def on_rvs_charge_status(
def get_actual_battery_capacity(
self, charge_status: RvsChargeStatus
) -> tuple[float, float]:
real_total_battery_capacity = self._vehicle_info.battery_capacity
if real_total_battery_capacity is not None and real_total_battery_capacity <= 0:
real_battery_capacity = self._vehicle_info.real_battery_capacity
if real_battery_capacity is not None and real_battery_capacity <= 0:
# Negative or 0 value for real capacity means we don't know that info
real_total_battery_capacity = None
real_battery_capacity = None

raw_total_battery_capacity = None
raw_battery_capacity = None
if (
charge_status.totalBatteryCapacity is not None
and charge_status.totalBatteryCapacity > 0
):
raw_total_battery_capacity = charge_status.totalBatteryCapacity / 10.0
raw_battery_capacity = charge_status.totalBatteryCapacity / 10.0

if raw_total_battery_capacity is not None:
if real_total_battery_capacity is not None:
if raw_battery_capacity is not None:
if real_battery_capacity is not None:
LOG.debug(
"Calculating full battery capacity correction factor based on "
"real=%f and raw=%f",
real_total_battery_capacity,
raw_total_battery_capacity,
real_battery_capacity,
raw_battery_capacity,
)
return (
real_total_battery_capacity,
real_total_battery_capacity / raw_total_battery_capacity,
real_battery_capacity,
real_battery_capacity / raw_battery_capacity,
)
LOG.debug(
"Setting real battery capacity to raw battery capacity %f",
raw_total_battery_capacity,
raw_battery_capacity,
)
return raw_total_battery_capacity, 1.0
if real_total_battery_capacity is not None:
return raw_battery_capacity, 1.0
if real_battery_capacity is not None:
LOG.debug(
"Setting raw battery capacity to real battery capacity %f",
real_total_battery_capacity,
real_battery_capacity,
)
return real_total_battery_capacity, 1.0
return real_battery_capacity, 1.0
LOG.warning("No battery capacity information available")
return 0, 1.0
10 changes: 6 additions & 4 deletions src/vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@
if result.processed:
self.notify_car_activity()

def should_refresh(self) -> bool:

Check failure on line 355 in src/vehicle.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Ruff (PLR0911)

src/vehicle.py:355:9: PLR0911 Too many return statements (8 > 6)

Check failure on line 355 in src/vehicle.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Ruff (PLR0911)

src/vehicle.py:355:9: PLR0911 Too many return statements (8 > 6)
match self.refresh_mode:
case RefreshMode.OFF:
LOG.debug(f"Refresh mode is OFF, skipping vehicle {self.vin} refresh")
Expand Down Expand Up @@ -612,8 +612,10 @@
soc_published = False

if charge_status is not None:
if (range := charge_status.raw_fuel_range_elec) is not None:
electric_range_published = self.__publish_electric_range(range)
if (raw_fuel_range_elec := charge_status.raw_fuel_range_elec) is not None:
electric_range_published = self.__publish_electric_range(
raw_fuel_range_elec
)

if (soc := charge_status.raw_soc) is not None:
soc_published = self.__publish_soc(soc / 10.0)
Expand All @@ -626,10 +628,10 @@
soc_published = self.__publish_soc(vehicle_status.raw_soc)

if not electric_range_published:
logging.warning("Could not extract a valid electric range")
LOG.warning("Could not extract a valid electric range")

if not soc_published:
logging.warning("Could not extract a valid SoC")
LOG.warning("Could not extract a valid SoC")

def handle_scheduled_battery_heating_status(
self, scheduled_battery_heating_status: ScheduledBatteryHeatingResp | None
Expand Down
32 changes: 28 additions & 4 deletions src/vehicle_info.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Final

from exceptions import MqttGatewayException

if TYPE_CHECKING:
from saic_ismart_client_ng.api.vehicle import VehicleModelConfiguration, VinInfo

LOG = logging.getLogger(__name__)


class VehicleInfo:
def __init__(
Expand Down Expand Up @@ -106,12 +109,26 @@ def supports_target_soc(self) -> bool:
return self.__get_property_value("Battery") == "1"

@property
def battery_capacity(self) -> float | None:
def real_battery_capacity(self) -> float | None:
if (
self.__custom_battery_capacity is not None
and self.__custom_battery_capacity > 0
):
return float(self.__custom_battery_capacity)
if self.series.startswith("EH32"):
return self.__mg4_real_battery_capacity()
if self.series.startswith("EP2"):
return self.__mg5_real_battery_capacity()
# Model: MG ZS EV 2021
if self.series.startswith("ZS EV"):
return self.__zs_ev_real_battery_capacity()
LOG.warning(
f"Unknown battery capacity for car series='{self.series}' and model='{self.model}'. "
"Please file an issue to improve data accuracy"
)
return None

def __mg4_real_battery_capacity(self) -> float | None:
# MG4 high trim level
if self.series.startswith("EH32 S"):
if self.model.startswith("EH32 X3"):
Expand All @@ -130,13 +147,20 @@ def battery_capacity(self) -> float | None:
return 64.0
# MG4 low trim level with LFP battery
return 51.0
return None

def __mg5_real_battery_capacity(self) -> float | None:
# Model: MG5 Electric, variant MG5 SR Comfort
if self.series.startswith("EP2CP3"):
return 50.3
# Model: MG5 Electric, variant MG5 MR Luxury
if self.series.startswith("EP2DP3"):
return 61.1
# ZS EV Standard 2021
if self.series.startswith("ZS EV S"):
return 49.0
return None

def __zs_ev_real_battery_capacity(self) -> float | None:
if self.supports_target_soc:
# Long Range with NMC battery
return 68.3
# Standard Range with LFP battery
return 49.0
Loading