diff --git a/homeassistant/components/kitchen_sink/__init__.py b/homeassistant/components/kitchen_sink/__init__.py index f934a96f4d6..b2d4c4cbcc5 100644 --- a/homeassistant/components/kitchen_sink/__init__.py +++ b/homeassistant/components/kitchen_sink/__init__.py @@ -8,14 +8,16 @@ from __future__ import annotations import datetime from random import random -from homeassistant.components.recorder import get_instance +from homeassistant.components.recorder import DOMAIN as RECORDER_DOMAIN, get_instance from homeassistant.components.recorder.models import StatisticData, StatisticMetaData from homeassistant.components.recorder.statistics import ( async_add_external_statistics, + async_import_statistics, get_last_statistics, ) -from homeassistant.const import UnitOfEnergy, UnitOfTemperature, UnitOfVolume +from homeassistant.const import Platform, UnitOfEnergy, UnitOfTemperature, UnitOfVolume from homeassistant.core import HomeAssistant +from homeassistant.helpers.discovery import async_load_platform from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType import homeassistant.util.dt as dt_util @@ -23,8 +25,17 @@ import homeassistant.util.dt as dt_util DOMAIN = "kitchen_sink" +COMPONENTS_WITH_DEMO_PLATFORM = [ + Platform.SENSOR, +] + + async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the demo environment.""" + # Set up demo platforms + for platform in COMPONENTS_WITH_DEMO_PLATFORM: + hass.async_create_task(async_load_platform(hass, platform, DOMAIN, {}, config)) + # Create issues _create_issues(hass) @@ -210,3 +221,52 @@ async def _insert_statistics(hass: HomeAssistant) -> None: "has_sum": True, } await _insert_sum_statistics(hass, metadata, yesterday_midnight, today_midnight, 15) + + # Add some statistics which will raise an issue + # Used to raise an issue where the unit has changed to a non volume unit + metadata = { + "source": RECORDER_DOMAIN, + "name": None, + "statistic_id": "sensor.statistics_issue_1", + "unit_of_measurement": UnitOfVolume.CUBIC_METERS, + "has_mean": True, + "has_sum": False, + } + statistics = _generate_mean_statistics(yesterday_midnight, today_midnight, 15, 1) + async_import_statistics(hass, metadata, statistics) + + # Used to raise an issue where the unit has changed to a different unit + metadata = { + "source": RECORDER_DOMAIN, + "name": None, + "statistic_id": "sensor.statistics_issue_2", + "unit_of_measurement": "cats", + "has_mean": True, + "has_sum": False, + } + statistics = _generate_mean_statistics(yesterday_midnight, today_midnight, 15, 1) + async_import_statistics(hass, metadata, statistics) + + # Used to raise an issue where state class is not compatible with statistics + metadata = { + "source": RECORDER_DOMAIN, + "name": None, + "statistic_id": "sensor.statistics_issue_3", + "unit_of_measurement": UnitOfVolume.CUBIC_METERS, + "has_mean": True, + "has_sum": False, + } + statistics = _generate_mean_statistics(yesterday_midnight, today_midnight, 15, 1) + async_import_statistics(hass, metadata, statistics) + + # Used to raise an issue where the sensor is not in the state machine + metadata = { + "source": RECORDER_DOMAIN, + "name": None, + "statistic_id": "sensor.statistics_issue_4", + "unit_of_measurement": UnitOfVolume.CUBIC_METERS, + "has_mean": True, + "has_sum": False, + } + statistics = _generate_mean_statistics(yesterday_midnight, today_midnight, 15, 1) + async_import_statistics(hass, metadata, statistics) diff --git a/homeassistant/components/kitchen_sink/sensor.py b/homeassistant/components/kitchen_sink/sensor.py new file mode 100644 index 00000000000..b6806b02115 --- /dev/null +++ b/homeassistant/components/kitchen_sink/sensor.py @@ -0,0 +1,101 @@ +"""Demo platform that has a couple of fake sensors.""" +from __future__ import annotations + +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorStateClass, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ATTR_BATTERY_LEVEL, UnitOfPower +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType + +from . import DOMAIN + + +async def async_setup_platform( + hass: HomeAssistant, + config: ConfigType, + async_add_entities: AddEntitiesCallback, + discovery_info: DiscoveryInfoType | None = None, +) -> None: + """Set up the Demo sensors.""" + async_add_entities( + [ + DemoSensor( + "statistics_issue_1", + "Statistics issue 1", + 100, + None, + SensorStateClass.MEASUREMENT, + UnitOfPower.WATT, # Not a volume unit + None, + ), + DemoSensor( + "statistics_issue_2", + "Statistics issue 2", + 100, + None, + SensorStateClass.MEASUREMENT, + "dogs", # Can't be converted to cats + None, + ), + DemoSensor( + "statistics_issue_3", + "Statistics issue 3", + 100, + None, + None, # Wrong state class + UnitOfPower.WATT, + None, + ), + ] + ) + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the Everything but the Kitchen Sink config entry.""" + await async_setup_platform(hass, {}, async_add_entities) + + +class DemoSensor(SensorEntity): + """Representation of a Demo sensor.""" + + _attr_should_poll = False + + def __init__( + self, + unique_id: str, + name: str, + state: StateType, + device_class: SensorDeviceClass | None, + state_class: SensorStateClass | None, + unit_of_measurement: str | None, + battery: StateType, + options: list[str] | None = None, + translation_key: str | None = None, + ) -> None: + """Initialize the sensor.""" + self._attr_device_class = device_class + self._attr_name = name + self._attr_native_unit_of_measurement = unit_of_measurement + self._attr_native_value = state + self._attr_state_class = state_class + self._attr_unique_id = unique_id + self._attr_options = options + self._attr_translation_key = translation_key + + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, unique_id)}, + name=name, + ) + + if battery: + self._attr_extra_state_attributes = {ATTR_BATTERY_LEVEL: battery}