Fix Teslemetry cabin overheat protection temperature for streaming vehicles (#183420)

This commit is contained in:
Brett Adams
2026-09-29 11:01:07 +02:00
committed by GitHub
parent e9366e97f9
commit 2e6ea54bea
2 changed files with 91 additions and 3 deletions
+11 -2
View File
@@ -62,6 +62,8 @@ async def async_setup_entry(
) -> None:
"""Set up the Teslemetry Climate platform from a config entry."""
# Streaming vehicles are never polled, so their vehicle_config comes from metadata
vehicles_metadata = entry.runtime_data.metadata_coordinator.data["vehicles"]
async_add_entities(
chain(
(
@@ -80,7 +82,13 @@ async def async_setup_entry(
)
if vehicle.poll or not firmware_at_least(vehicle.firmware, "2024.44.25")
else TeslemetryStreamingCabinOverheatProtectionEntity(
vehicle, entry.runtime_data.scopes
vehicle,
entry.runtime_data.scopes,
bool(
vehicles_metadata[vehicle.vin]
.get("config", {})
.get("cop_user_set_temp_supported")
),
)
for vehicle in entry.runtime_data.vehicles
),
@@ -507,6 +515,7 @@ class TeslemetryStreamingCabinOverheatProtectionEntity(
self,
data: TeslemetryVehicleData,
scopes: list[Scope],
cop_temp_supported: bool,
) -> None:
"""Initialize the climate."""
@@ -523,7 +532,7 @@ class TeslemetryStreamingCabinOverheatProtectionEntity(
self._attr_supported_features = (
ClimateEntityFeature.TURN_ON | ClimateEntityFeature.TURN_OFF
)
if data.coordinator.data.get("vehicle_config_cop_user_set_temp_supported"):
if cop_temp_supported:
self._attr_supported_features |= ClimateEntityFeature.TARGET_TEMPERATURE
# Scopes
+80 -1
View File
@@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, patch
import pytest
from syrupy.assertion import SnapshotAssertion
from tesla_fleet_api.const import CabinOverheatProtectionTemp
from tesla_fleet_api.exceptions import InvalidCommand
from teslemetry_stream import Signal
@@ -18,9 +19,15 @@ from homeassistant.components.climate import (
SERVICE_SET_TEMPERATURE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, Platform
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_SUPPORTED_FEATURES,
STATE_UNKNOWN,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import entity_registry as er
@@ -29,6 +36,7 @@ from . import assert_entities, reload_platform, setup_platform
from .const import (
COMMAND_ERRORS,
COMMAND_IGNORED_REASON,
COMMAND_OK,
METADATA,
METADATA_NOSCOPE,
VEHICLE_DATA_ALT,
@@ -370,3 +378,74 @@ async def test_select_streaming(
"climate.test_cabin_overheat_protection",
):
assert hass.states.get(entity_id) == snapshot(name=entity_id)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@pytest.mark.parametrize(
("config", "supported_features"),
[
pytest.param(
{"cop_user_set_temp_supported": True},
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF,
id="supported",
),
pytest.param(
{"cop_user_set_temp_supported": False},
ClimateEntityFeature.TURN_ON | ClimateEntityFeature.TURN_OFF,
id="unsupported",
),
pytest.param(
{},
ClimateEntityFeature.TURN_ON | ClimateEntityFeature.TURN_OFF,
id="missing",
),
],
)
async def test_cabin_overheat_protection_streaming_features(
hass: HomeAssistant,
mock_metadata: AsyncMock,
config: dict[str, bool],
supported_features: ClimateEntityFeature,
) -> None:
"""Test streaming cabin overheat protection features come from metadata config."""
metadata = deepcopy(METADATA)
metadata["vehicles"]["LRW3F7EK4NC700000"]["config"] = config
mock_metadata.return_value = metadata
await setup_platform(hass, [Platform.CLIMATE])
state = hass.states.get("climate.test_cabin_overheat_protection")
assert state.attributes[ATTR_SUPPORTED_FEATURES] == supported_features
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_cabin_overheat_protection_streaming_set_temperature(
hass: HomeAssistant,
mock_metadata: AsyncMock,
) -> None:
"""Test setting the streaming cabin overheat protection temperature."""
metadata = deepcopy(METADATA)
metadata["vehicles"]["LRW3F7EK4NC700000"]["config"] = {
"cop_user_set_temp_supported": True
}
mock_metadata.return_value = metadata
await setup_platform(hass, [Platform.CLIMATE])
entity_id = "climate.test_cabin_overheat_protection"
with patch(
"tesla_fleet_api.teslemetry.Vehicle.set_cop_temp",
return_value=COMMAND_OK,
) as mock_set_cop_temp:
await hass.services.async_call(
CLIMATE_DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: [entity_id], ATTR_TEMPERATURE: 35},
blocking=True,
)
mock_set_cop_temp.assert_called_once_with(CabinOverheatProtectionTemp.MEDIUM)
assert hass.states.get(entity_id).attributes[ATTR_TEMPERATURE] == 35