mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 09:23:17 -04:00
Suppress the placeholder water temperature on Flo valves without the sensor (#182004)
This commit is contained in:
@@ -10,3 +10,8 @@ FLO_HOME = "home"
|
||||
FLO_AWAY = "away"
|
||||
FLO_SLEEP = "sleep"
|
||||
FLO_MODES = [FLO_HOME, FLO_AWAY, FLO_SLEEP]
|
||||
|
||||
# Valves without a water-temperature sensor report a fixed placeholder instead of
|
||||
# omitting tempF. No domestic supply reaches boiling, so a reading at or above
|
||||
# this is a sentinel rather than a measurement.
|
||||
IMPLAUSIBLE_WATER_TEMP_F = 212.0
|
||||
|
||||
@@ -14,7 +14,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import DOMAIN, LOGGER
|
||||
from .const import DOMAIN, IMPLAUSIBLE_WATER_TEMP_F, LOGGER
|
||||
|
||||
type FloConfigEntry = ConfigEntry[FloRuntimeData]
|
||||
|
||||
@@ -144,9 +144,12 @@ class FloDeviceDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
return self._device_information["telemetry"]["current"]["psi"]
|
||||
|
||||
@property
|
||||
def temperature(self) -> float:
|
||||
"""Return the current temperature in degrees F."""
|
||||
return self._device_information["telemetry"]["current"]["tempF"]
|
||||
def temperature(self) -> float | None:
|
||||
"""Return the current temperature in degrees F, or None if not measured."""
|
||||
temperature = self._device_information["telemetry"]["current"]["tempF"]
|
||||
if temperature is None or temperature >= IMPLAUSIBLE_WATER_TEMP_F:
|
||||
return None
|
||||
return temperature
|
||||
|
||||
@property
|
||||
def humidity(self) -> float:
|
||||
|
||||
@@ -11,7 +11,7 @@ from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, CONTENT_TYPE_JSON
|
||||
|
||||
from .common import TEST_EMAIL_ADDRESS, TEST_PASSWORD, TEST_TOKEN, TEST_USER_ID
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
from tests.common import MockConfigEntry, load_fixture, load_json_object_fixture
|
||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
|
||||
|
||||
@@ -26,7 +26,18 @@ def config_entry() -> MockConfigEntry:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def aioclient_mock_fixture(aioclient_mock: AiohttpClientMocker) -> None:
|
||||
def device_info_response(request: pytest.FixtureRequest) -> str:
|
||||
"""Shutoff valve device info, with tempF overridden when parametrized."""
|
||||
device_info = load_json_object_fixture("flo/device_info_response.json")
|
||||
if hasattr(request, "param"):
|
||||
device_info["telemetry"]["current"]["tempF"] = request.param
|
||||
return json.dumps(device_info)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def aioclient_mock_fixture(
|
||||
aioclient_mock: AiohttpClientMocker, device_info_response: str
|
||||
) -> None:
|
||||
"""Fixture to provide a aioclient mocker."""
|
||||
now = round(time.time())
|
||||
# Mocks the login response for flo.
|
||||
@@ -56,7 +67,7 @@ def aioclient_mock_fixture(aioclient_mock: AiohttpClientMocker) -> None:
|
||||
# Mocks the devices for flo.
|
||||
aioclient_mock.get(
|
||||
"https://api-gw.meetflo.com/api/v2/devices/98765",
|
||||
text=load_fixture("flo/device_info_response.json"),
|
||||
text=device_info_response,
|
||||
status=HTTPStatus.OK,
|
||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Test Flo by Moen sensor entities."""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.homeassistant import (
|
||||
@@ -7,7 +9,7 @@ from homeassistant.components.homeassistant import (
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
)
|
||||
from homeassistant.components.sensor import ATTR_STATE_CLASS, SensorStateClass
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
||||
@@ -105,3 +107,40 @@ async def test_manual_update_entity(
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.call_count == call_count + 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_info_response", [225, 212, 220], indirect=True)
|
||||
@pytest.mark.usefixtures("aioclient_mock_fixture")
|
||||
async def test_water_temperature_placeholder_is_not_published(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""A valve with no temperature sensor reports a placeholder, not a reading."""
|
||||
hass.config.units = US_CUSTOMARY_SYSTEM
|
||||
config_entry.add_to_hass(hass)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (
|
||||
hass.states.get("sensor.smart_water_shutoff_water_temperature").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
|
||||
# The detector measures ambient air and is unaffected.
|
||||
assert hass.states.get("sensor.kitchen_sink_temperature").state == "61"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_info_response", [211.9, 70], indirect=True)
|
||||
@pytest.mark.usefixtures("aioclient_mock_fixture")
|
||||
async def test_water_temperature_below_threshold_is_published(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry, device_info_response: str
|
||||
) -> None:
|
||||
"""Anything below boiling is a real reading and is published."""
|
||||
hass.config.units = US_CUSTOMARY_SYSTEM
|
||||
config_entry.add_to_hass(hass)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
expected = json.loads(device_info_response)["telemetry"]["current"]["tempF"]
|
||||
assert hass.states.get("sensor.smart_water_shutoff_water_temperature").state == str(
|
||||
round(expected, 1)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user