|
6 | 6 | from apscheduler.schedulers.blocking import BlockingScheduler |
7 | 7 | import pytest |
8 | 8 | from saic_ismart_client_ng.api.vehicle.schema import VinInfo |
| 9 | +from saic_ismart_client_ng.api.vehicle_charging import ( |
| 10 | + ChargeCurrentLimitCode, |
| 11 | + TargetBatteryCode, |
| 12 | +) |
9 | 13 |
|
10 | 14 | from configuration import Configuration |
11 | 15 | import mqtt_topics |
12 | | -from vehicle import VehicleState |
| 16 | +from vehicle import RefreshMode, VehicleState |
13 | 17 | from vehicle_info import VehicleInfo |
14 | 18 |
|
15 | 19 | from .common_mocks import ( |
@@ -124,6 +128,64 @@ def test_handle_charge_status_with_phev_ignore_values(self) -> None: |
124 | 128 | assert result.scheduled_charging is None |
125 | 129 | assert self.get_topic(mqtt_topics.DRIVETRAIN_SOC_TARGET) not in self.publisher.map |
126 | 130 |
|
| 131 | + def test_republish_command_states_after_configure_missing(self) -> None: |
| 132 | + self.vehicle_state.configure_missing() |
| 133 | + self.publisher.map.clear() |
| 134 | + |
| 135 | + self.vehicle_state.republish_command_states() |
| 136 | + |
| 137 | + self.assert_mqtt_topic( |
| 138 | + self.get_topic(mqtt_topics.REFRESH_PERIOD_ACTIVE), 30 |
| 139 | + ) |
| 140 | + self.assert_mqtt_topic( |
| 141 | + self.get_topic(mqtt_topics.REFRESH_PERIOD_INACTIVE), 86400 |
| 142 | + ) |
| 143 | + self.assert_mqtt_topic( |
| 144 | + self.get_topic(mqtt_topics.REFRESH_PERIOD_AFTER_SHUTDOWN), 120 |
| 145 | + ) |
| 146 | + self.assert_mqtt_topic( |
| 147 | + self.get_topic(mqtt_topics.REFRESH_PERIOD_INACTIVE_GRACE), 600 |
| 148 | + ) |
| 149 | + self.assert_mqtt_topic( |
| 150 | + self.get_topic(mqtt_topics.CLIMATE_REMOTE_TEMPERATURE), 22 |
| 151 | + ) |
| 152 | + self.assert_mqtt_topic( |
| 153 | + self.get_topic(mqtt_topics.REFRESH_MODE), RefreshMode.PERIODIC.value |
| 154 | + ) |
| 155 | + |
| 156 | + def test_republish_command_states_skips_unset_values(self) -> None: |
| 157 | + self.vehicle_state.republish_command_states() |
| 158 | + |
| 159 | + # Refresh periods are -1 and optional values are None, so they should not be published |
| 160 | + assert self.get_topic(mqtt_topics.REFRESH_PERIOD_ACTIVE) not in self.publisher.map |
| 161 | + assert self.get_topic(mqtt_topics.REFRESH_PERIOD_INACTIVE) not in self.publisher.map |
| 162 | + assert self.get_topic(mqtt_topics.REFRESH_PERIOD_AFTER_SHUTDOWN) not in self.publisher.map |
| 163 | + assert self.get_topic(mqtt_topics.REFRESH_PERIOD_INACTIVE_GRACE) not in self.publisher.map |
| 164 | + assert self.get_topic(mqtt_topics.DRIVETRAIN_SOC_TARGET) not in self.publisher.map |
| 165 | + assert self.get_topic(mqtt_topics.DRIVETRAIN_CHARGECURRENT_LIMIT) not in self.publisher.map |
| 166 | + assert self.get_topic(mqtt_topics.CLIMATE_REMOTE_TEMPERATURE) not in self.publisher.map |
| 167 | + # refresh_mode defaults to RefreshMode.OFF (never None), so it IS always published |
| 168 | + self.assert_mqtt_topic( |
| 169 | + self.get_topic(mqtt_topics.REFRESH_MODE), RefreshMode.OFF.value |
| 170 | + ) |
| 171 | + |
| 172 | + def test_republish_command_states_includes_api_values(self) -> None: |
| 173 | + self.vehicle_state.configure_missing() |
| 174 | + self.vehicle_state.update_target_soc(TargetBatteryCode.P_80) |
| 175 | + self.vehicle_state.update_charge_current_limit(ChargeCurrentLimitCode.C_MAX) |
| 176 | + self.publisher.map.clear() |
| 177 | + |
| 178 | + self.vehicle_state.republish_command_states() |
| 179 | + |
| 180 | + self.assert_mqtt_topic( |
| 181 | + self.get_topic(mqtt_topics.DRIVETRAIN_SOC_TARGET), |
| 182 | + TargetBatteryCode.P_80.percentage, |
| 183 | + ) |
| 184 | + self.assert_mqtt_topic( |
| 185 | + self.get_topic(mqtt_topics.DRIVETRAIN_CHARGECURRENT_LIMIT), |
| 186 | + ChargeCurrentLimitCode.C_MAX.limit, |
| 187 | + ) |
| 188 | + |
127 | 189 | @staticmethod |
128 | 190 | def get_topic(sub_topic: str) -> str: |
129 | 191 | return f"/vehicles/{VIN}/{sub_topic}" |
0 commit comments