Add kitchen_sink integration (#85592)
This commit is contained in:
parent
3d02b5af21
commit
7621c450c7
10 changed files with 518 additions and 466 deletions
|
@ -605,6 +605,8 @@ build.json @home-assistant/supervisor
|
||||||
/homeassistant/components/keyboard_remote/ @bendavid @lanrat
|
/homeassistant/components/keyboard_remote/ @bendavid @lanrat
|
||||||
/homeassistant/components/keymitt_ble/ @spycle
|
/homeassistant/components/keymitt_ble/ @spycle
|
||||||
/tests/components/keymitt_ble/ @spycle
|
/tests/components/keymitt_ble/ @spycle
|
||||||
|
/homeassistant/components/kitchen_sink/ @home-assistant/core
|
||||||
|
/tests/components/kitchen_sink/ @home-assistant/core
|
||||||
/homeassistant/components/kmtronic/ @dgomes
|
/homeassistant/components/kmtronic/ @dgomes
|
||||||
/tests/components/kmtronic/ @dgomes
|
/tests/components/kmtronic/ @dgomes
|
||||||
/homeassistant/components/knx/ @Julius2342 @farmio @marvin-w
|
/homeassistant/components/knx/ @Julius2342 @farmio @marvin-w
|
||||||
|
|
|
@ -2,33 +2,20 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
|
||||||
from random import random
|
|
||||||
|
|
||||||
from homeassistant import config_entries, setup
|
from homeassistant import config_entries, setup
|
||||||
from homeassistant.components import persistent_notification
|
from homeassistant.components import persistent_notification
|
||||||
from homeassistant.components.recorder import get_instance
|
|
||||||
from homeassistant.components.recorder.models import StatisticData, StatisticMetaData
|
|
||||||
from homeassistant.components.recorder.statistics import (
|
|
||||||
async_add_external_statistics,
|
|
||||||
get_last_statistics,
|
|
||||||
)
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
EVENT_HOMEASSISTANT_START,
|
EVENT_HOMEASSISTANT_START,
|
||||||
Platform,
|
Platform,
|
||||||
UnitOfEnergy,
|
|
||||||
UnitOfSoundPressure,
|
UnitOfSoundPressure,
|
||||||
UnitOfTemperature,
|
|
||||||
UnitOfVolume,
|
|
||||||
)
|
)
|
||||||
import homeassistant.core as ha
|
import homeassistant.core as ha
|
||||||
from homeassistant.core import Event, HomeAssistant
|
from homeassistant.core import Event, HomeAssistant
|
||||||
from homeassistant.helpers.discovery import async_load_platform
|
from homeassistant.helpers.discovery import async_load_platform
|
||||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
import homeassistant.util.dt as dt_util
|
|
||||||
|
|
||||||
DOMAIN = "demo"
|
DOMAIN = "demo"
|
||||||
|
|
||||||
|
@ -186,192 +173,15 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
|
|
||||||
hass.bus.async_listen(EVENT_HOMEASSISTANT_START, demo_start_listener)
|
hass.bus.async_listen(EVENT_HOMEASSISTANT_START, demo_start_listener)
|
||||||
|
|
||||||
# Create issues
|
|
||||||
async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"transmogrifier_deprecated",
|
|
||||||
breaks_in_ha_version="2023.1.1",
|
|
||||||
is_fixable=False,
|
|
||||||
learn_more_url="https://en.wiktionary.org/wiki/transmogrifier",
|
|
||||||
severity=IssueSeverity.WARNING,
|
|
||||||
translation_key="transmogrifier_deprecated",
|
|
||||||
)
|
|
||||||
|
|
||||||
async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"out_of_blinker_fluid",
|
|
||||||
breaks_in_ha_version="2023.1.1",
|
|
||||||
is_fixable=True,
|
|
||||||
learn_more_url="https://www.youtube.com/watch?v=b9rntRxLlbU",
|
|
||||||
severity=IssueSeverity.CRITICAL,
|
|
||||||
translation_key="out_of_blinker_fluid",
|
|
||||||
)
|
|
||||||
|
|
||||||
async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"unfixable_problem",
|
|
||||||
is_fixable=False,
|
|
||||||
learn_more_url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
||||||
severity=IssueSeverity.WARNING,
|
|
||||||
translation_key="unfixable_problem",
|
|
||||||
)
|
|
||||||
|
|
||||||
async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"bad_psu",
|
|
||||||
is_fixable=True,
|
|
||||||
learn_more_url="https://www.youtube.com/watch?v=b9rntRxLlbU",
|
|
||||||
severity=IssueSeverity.CRITICAL,
|
|
||||||
translation_key="bad_psu",
|
|
||||||
)
|
|
||||||
|
|
||||||
async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"cold_tea",
|
|
||||||
is_fixable=True,
|
|
||||||
severity=IssueSeverity.WARNING,
|
|
||||||
translation_key="cold_tea",
|
|
||||||
)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _generate_mean_statistics(
|
|
||||||
start: datetime.datetime, end: datetime.datetime, init_value: float, max_diff: float
|
|
||||||
) -> list[StatisticData]:
|
|
||||||
statistics: list[StatisticData] = []
|
|
||||||
mean = init_value
|
|
||||||
now = start
|
|
||||||
while now < end:
|
|
||||||
mean = mean + random() * max_diff - max_diff / 2
|
|
||||||
statistics.append(
|
|
||||||
{
|
|
||||||
"start": now,
|
|
||||||
"mean": mean,
|
|
||||||
"min": mean - random() * max_diff,
|
|
||||||
"max": mean + random() * max_diff,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
now = now + datetime.timedelta(hours=1)
|
|
||||||
|
|
||||||
return statistics
|
|
||||||
|
|
||||||
|
|
||||||
async def _insert_sum_statistics(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
metadata: StatisticMetaData,
|
|
||||||
start: datetime.datetime,
|
|
||||||
end: datetime.datetime,
|
|
||||||
max_diff: float,
|
|
||||||
) -> None:
|
|
||||||
statistics: list[StatisticData] = []
|
|
||||||
now = start
|
|
||||||
sum_ = 0.0
|
|
||||||
statistic_id = metadata["statistic_id"]
|
|
||||||
|
|
||||||
last_stats = await get_instance(hass).async_add_executor_job(
|
|
||||||
get_last_statistics, hass, 1, statistic_id, False, {"sum"}
|
|
||||||
)
|
|
||||||
if statistic_id in last_stats:
|
|
||||||
sum_ = last_stats[statistic_id][0]["sum"] or 0
|
|
||||||
while now < end:
|
|
||||||
sum_ = sum_ + random() * max_diff
|
|
||||||
statistics.append(
|
|
||||||
{
|
|
||||||
"start": now,
|
|
||||||
"sum": sum_,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
now = now + datetime.timedelta(hours=1)
|
|
||||||
|
|
||||||
async_add_external_statistics(hass, metadata, statistics)
|
|
||||||
|
|
||||||
|
|
||||||
async def _insert_statistics(hass: HomeAssistant) -> None:
|
|
||||||
"""Insert some fake statistics."""
|
|
||||||
now = dt_util.now()
|
|
||||||
yesterday = now - datetime.timedelta(days=1)
|
|
||||||
yesterday_midnight = yesterday.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
||||||
today_midnight = yesterday_midnight + datetime.timedelta(days=1)
|
|
||||||
|
|
||||||
# Fake yesterday's temperatures
|
|
||||||
metadata: StatisticMetaData = {
|
|
||||||
"source": DOMAIN,
|
|
||||||
"name": "Outdoor temperature",
|
|
||||||
"statistic_id": f"{DOMAIN}:temperature_outdoor",
|
|
||||||
"unit_of_measurement": UnitOfTemperature.CELSIUS,
|
|
||||||
"has_mean": True,
|
|
||||||
"has_sum": False,
|
|
||||||
}
|
|
||||||
statistics = _generate_mean_statistics(yesterday_midnight, today_midnight, 15, 1)
|
|
||||||
async_add_external_statistics(hass, metadata, statistics)
|
|
||||||
|
|
||||||
# Add external energy consumption in kWh, ~ 12 kWh / day
|
|
||||||
# This should be possible to pick for the energy dashboard
|
|
||||||
metadata = {
|
|
||||||
"source": DOMAIN,
|
|
||||||
"name": "Energy consumption 1",
|
|
||||||
"statistic_id": f"{DOMAIN}:energy_consumption_kwh",
|
|
||||||
"unit_of_measurement": UnitOfEnergy.KILO_WATT_HOUR,
|
|
||||||
"has_mean": False,
|
|
||||||
"has_sum": True,
|
|
||||||
}
|
|
||||||
await _insert_sum_statistics(hass, metadata, yesterday_midnight, today_midnight, 1)
|
|
||||||
|
|
||||||
# Add external energy consumption in MWh, ~ 12 kWh / day
|
|
||||||
# This should not be possible to pick for the energy dashboard
|
|
||||||
metadata = {
|
|
||||||
"source": DOMAIN,
|
|
||||||
"name": "Energy consumption 2",
|
|
||||||
"statistic_id": f"{DOMAIN}:energy_consumption_mwh",
|
|
||||||
"unit_of_measurement": UnitOfEnergy.MEGA_WATT_HOUR,
|
|
||||||
"has_mean": False,
|
|
||||||
"has_sum": True,
|
|
||||||
}
|
|
||||||
await _insert_sum_statistics(
|
|
||||||
hass, metadata, yesterday_midnight, today_midnight, 0.001
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add external gas consumption in m³, ~6 m3/day
|
|
||||||
# This should be possible to pick for the energy dashboard
|
|
||||||
metadata = {
|
|
||||||
"source": DOMAIN,
|
|
||||||
"name": "Gas consumption 1",
|
|
||||||
"statistic_id": f"{DOMAIN}:gas_consumption_m3",
|
|
||||||
"unit_of_measurement": UnitOfVolume.CUBIC_METERS,
|
|
||||||
"has_mean": False,
|
|
||||||
"has_sum": True,
|
|
||||||
}
|
|
||||||
await _insert_sum_statistics(
|
|
||||||
hass, metadata, yesterday_midnight, today_midnight, 0.5
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add external gas consumption in ft³, ~180 ft3/day
|
|
||||||
# This should not be possible to pick for the energy dashboard
|
|
||||||
metadata = {
|
|
||||||
"source": DOMAIN,
|
|
||||||
"name": "Gas consumption 2",
|
|
||||||
"statistic_id": f"{DOMAIN}:gas_consumption_ft3",
|
|
||||||
"unit_of_measurement": UnitOfVolume.CUBIC_FEET,
|
|
||||||
"has_mean": False,
|
|
||||||
"has_sum": True,
|
|
||||||
}
|
|
||||||
await _insert_sum_statistics(hass, metadata, yesterday_midnight, today_midnight, 15)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
"""Set the config entry up."""
|
"""Set the config entry up."""
|
||||||
# Set up demo platforms with config entry
|
# Set up demo platforms with config entry
|
||||||
await hass.config_entries.async_forward_entry_setups(
|
await hass.config_entries.async_forward_entry_setups(
|
||||||
config_entry, COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM
|
config_entry, COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM
|
||||||
)
|
)
|
||||||
if "recorder" in hass.config.components:
|
|
||||||
await _insert_statistics(hass)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
"domain": "demo",
|
"domain": "demo",
|
||||||
"name": "Demo",
|
"name": "Demo",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/demo",
|
"documentation": "https://www.home-assistant.io/integrations/demo",
|
||||||
"after_dependencies": ["recorder"],
|
|
||||||
"dependencies": ["conversation", "group", "zone"],
|
"dependencies": ["conversation", "group", "zone"],
|
||||||
"codeowners": ["@home-assistant/core"],
|
"codeowners": ["@home-assistant/core"],
|
||||||
"quality_scale": "internal",
|
"quality_scale": "internal",
|
||||||
|
|
212
homeassistant/components/kitchen_sink/__init__.py
Normal file
212
homeassistant/components/kitchen_sink/__init__.py
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
"""The Kitchen Sink integration contains demonstrations of various odds and ends.
|
||||||
|
|
||||||
|
This sets up a demo environment of features which are obscure or which represent
|
||||||
|
incorrect behavior, and are thus not wanted in the demo integration.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from random import random
|
||||||
|
|
||||||
|
from homeassistant.components.recorder import get_instance
|
||||||
|
from homeassistant.components.recorder.models import StatisticData, StatisticMetaData
|
||||||
|
from homeassistant.components.recorder.statistics import (
|
||||||
|
async_add_external_statistics,
|
||||||
|
get_last_statistics,
|
||||||
|
)
|
||||||
|
from homeassistant.const import UnitOfEnergy, UnitOfTemperature, UnitOfVolume
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||||
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
DOMAIN = "kitchen_sink"
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
|
"""Set up the demo environment."""
|
||||||
|
# Create issues
|
||||||
|
_create_issues(hass)
|
||||||
|
|
||||||
|
# Insert some external statistics
|
||||||
|
if "recorder" in hass.config.components:
|
||||||
|
await _insert_statistics(hass)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _create_issues(hass):
|
||||||
|
"""Create some issue registry issues."""
|
||||||
|
async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"transmogrifier_deprecated",
|
||||||
|
breaks_in_ha_version="2023.1.1",
|
||||||
|
is_fixable=False,
|
||||||
|
learn_more_url="https://en.wiktionary.org/wiki/transmogrifier",
|
||||||
|
severity=IssueSeverity.WARNING,
|
||||||
|
translation_key="transmogrifier_deprecated",
|
||||||
|
)
|
||||||
|
|
||||||
|
async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"out_of_blinker_fluid",
|
||||||
|
breaks_in_ha_version="2023.1.1",
|
||||||
|
is_fixable=True,
|
||||||
|
learn_more_url="https://www.youtube.com/watch?v=b9rntRxLlbU",
|
||||||
|
severity=IssueSeverity.CRITICAL,
|
||||||
|
translation_key="out_of_blinker_fluid",
|
||||||
|
)
|
||||||
|
|
||||||
|
async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"unfixable_problem",
|
||||||
|
is_fixable=False,
|
||||||
|
learn_more_url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||||
|
severity=IssueSeverity.WARNING,
|
||||||
|
translation_key="unfixable_problem",
|
||||||
|
)
|
||||||
|
|
||||||
|
async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"bad_psu",
|
||||||
|
is_fixable=True,
|
||||||
|
learn_more_url="https://www.youtube.com/watch?v=b9rntRxLlbU",
|
||||||
|
severity=IssueSeverity.CRITICAL,
|
||||||
|
translation_key="bad_psu",
|
||||||
|
)
|
||||||
|
|
||||||
|
async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"cold_tea",
|
||||||
|
is_fixable=True,
|
||||||
|
severity=IssueSeverity.WARNING,
|
||||||
|
translation_key="cold_tea",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_mean_statistics(
|
||||||
|
start: datetime.datetime, end: datetime.datetime, init_value: float, max_diff: float
|
||||||
|
) -> list[StatisticData]:
|
||||||
|
statistics: list[StatisticData] = []
|
||||||
|
mean = init_value
|
||||||
|
now = start
|
||||||
|
while now < end:
|
||||||
|
mean = mean + random() * max_diff - max_diff / 2
|
||||||
|
statistics.append(
|
||||||
|
{
|
||||||
|
"start": now,
|
||||||
|
"mean": mean,
|
||||||
|
"min": mean - random() * max_diff,
|
||||||
|
"max": mean + random() * max_diff,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
now = now + datetime.timedelta(hours=1)
|
||||||
|
|
||||||
|
return statistics
|
||||||
|
|
||||||
|
|
||||||
|
async def _insert_sum_statistics(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
metadata: StatisticMetaData,
|
||||||
|
start: datetime.datetime,
|
||||||
|
end: datetime.datetime,
|
||||||
|
max_diff: float,
|
||||||
|
) -> None:
|
||||||
|
statistics: list[StatisticData] = []
|
||||||
|
now = start
|
||||||
|
sum_ = 0.0
|
||||||
|
statistic_id = metadata["statistic_id"]
|
||||||
|
|
||||||
|
last_stats = await get_instance(hass).async_add_executor_job(
|
||||||
|
get_last_statistics, hass, 1, statistic_id, False, {"sum"}
|
||||||
|
)
|
||||||
|
if statistic_id in last_stats:
|
||||||
|
sum_ = last_stats[statistic_id][0]["sum"] or 0
|
||||||
|
while now < end:
|
||||||
|
sum_ = sum_ + random() * max_diff
|
||||||
|
statistics.append(
|
||||||
|
{
|
||||||
|
"start": now,
|
||||||
|
"sum": sum_,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
now = now + datetime.timedelta(hours=1)
|
||||||
|
|
||||||
|
async_add_external_statistics(hass, metadata, statistics)
|
||||||
|
|
||||||
|
|
||||||
|
async def _insert_statistics(hass: HomeAssistant) -> None:
|
||||||
|
"""Insert some fake statistics."""
|
||||||
|
now = dt_util.now()
|
||||||
|
yesterday = now - datetime.timedelta(days=1)
|
||||||
|
yesterday_midnight = yesterday.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
today_midnight = yesterday_midnight + datetime.timedelta(days=1)
|
||||||
|
|
||||||
|
# Fake yesterday's temperatures
|
||||||
|
metadata: StatisticMetaData = {
|
||||||
|
"source": DOMAIN,
|
||||||
|
"name": "Outdoor temperature",
|
||||||
|
"statistic_id": f"{DOMAIN}:temperature_outdoor",
|
||||||
|
"unit_of_measurement": UnitOfTemperature.CELSIUS,
|
||||||
|
"has_mean": True,
|
||||||
|
"has_sum": False,
|
||||||
|
}
|
||||||
|
statistics = _generate_mean_statistics(yesterday_midnight, today_midnight, 15, 1)
|
||||||
|
async_add_external_statistics(hass, metadata, statistics)
|
||||||
|
|
||||||
|
# Add external energy consumption in kWh, ~ 12 kWh / day
|
||||||
|
# This should be possible to pick for the energy dashboard
|
||||||
|
metadata = {
|
||||||
|
"source": DOMAIN,
|
||||||
|
"name": "Energy consumption 1",
|
||||||
|
"statistic_id": f"{DOMAIN}:energy_consumption_kwh",
|
||||||
|
"unit_of_measurement": UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
}
|
||||||
|
await _insert_sum_statistics(hass, metadata, yesterday_midnight, today_midnight, 1)
|
||||||
|
|
||||||
|
# Add external energy consumption in MWh, ~ 12 kWh / day
|
||||||
|
# This should not be possible to pick for the energy dashboard
|
||||||
|
metadata = {
|
||||||
|
"source": DOMAIN,
|
||||||
|
"name": "Energy consumption 2",
|
||||||
|
"statistic_id": f"{DOMAIN}:energy_consumption_mwh",
|
||||||
|
"unit_of_measurement": UnitOfEnergy.MEGA_WATT_HOUR,
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
}
|
||||||
|
await _insert_sum_statistics(
|
||||||
|
hass, metadata, yesterday_midnight, today_midnight, 0.001
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add external gas consumption in m³, ~6 m3/day
|
||||||
|
# This should be possible to pick for the energy dashboard
|
||||||
|
metadata = {
|
||||||
|
"source": DOMAIN,
|
||||||
|
"name": "Gas consumption 1",
|
||||||
|
"statistic_id": f"{DOMAIN}:gas_consumption_m3",
|
||||||
|
"unit_of_measurement": UnitOfVolume.CUBIC_METERS,
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
}
|
||||||
|
await _insert_sum_statistics(
|
||||||
|
hass, metadata, yesterday_midnight, today_midnight, 0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add external gas consumption in ft³, ~180 ft3/day
|
||||||
|
# This should not be possible to pick for the energy dashboard
|
||||||
|
metadata = {
|
||||||
|
"source": DOMAIN,
|
||||||
|
"name": "Gas consumption 2",
|
||||||
|
"statistic_id": f"{DOMAIN}:gas_consumption_ft3",
|
||||||
|
"unit_of_measurement": UnitOfVolume.CUBIC_FEET,
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
}
|
||||||
|
await _insert_sum_statistics(hass, metadata, yesterday_midnight, today_midnight, 15)
|
9
homeassistant/components/kitchen_sink/manifest.json
Normal file
9
homeassistant/components/kitchen_sink/manifest.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"after_dependencies": ["recorder"],
|
||||||
|
"codeowners": ["@home-assistant/core"],
|
||||||
|
"documentation": "https://www.home-assistant.io/integrations/kitchen_sink",
|
||||||
|
"domain": "kitchen_sink",
|
||||||
|
"iot_class": "calculated",
|
||||||
|
"name": "Everything but the Kitchen Sink",
|
||||||
|
"quality_scale": "internal"
|
||||||
|
}
|
|
@ -2673,6 +2673,12 @@
|
||||||
"config_flow": false,
|
"config_flow": false,
|
||||||
"iot_class": "local_push"
|
"iot_class": "local_push"
|
||||||
},
|
},
|
||||||
|
"kitchen_sink": {
|
||||||
|
"name": "Everything but the Kitchen Sink",
|
||||||
|
"integration_type": "hub",
|
||||||
|
"config_flow": false,
|
||||||
|
"iot_class": "calculated"
|
||||||
|
},
|
||||||
"kiwi": {
|
"kiwi": {
|
||||||
"name": "KIWI",
|
"name": "KIWI",
|
||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
|
|
|
@ -1,25 +1,12 @@
|
||||||
"""The tests for the Demo component."""
|
"""The tests for the Demo component."""
|
||||||
import datetime
|
|
||||||
from http import HTTPStatus
|
|
||||||
import json
|
import json
|
||||||
from unittest.mock import ANY, patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.demo import DOMAIN
|
from homeassistant.components.demo import DOMAIN
|
||||||
from homeassistant.components.recorder import get_instance
|
|
||||||
from homeassistant.components.recorder.statistics import (
|
|
||||||
async_add_external_statistics,
|
|
||||||
get_last_statistics,
|
|
||||||
list_statistic_ids,
|
|
||||||
)
|
|
||||||
from homeassistant.components.repairs import DOMAIN as REPAIRS_DOMAIN
|
|
||||||
from homeassistant.helpers.json import JSONEncoder
|
from homeassistant.helpers.json import JSONEncoder
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
|
||||||
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
|
||||||
|
|
||||||
from tests.components.recorder.common import async_wait_recording_done
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -50,264 +37,3 @@ async def test_setting_up_demo(mock_history, hass):
|
||||||
"Unable to convert all demo entities to JSON. "
|
"Unable to convert all demo entities to JSON. "
|
||||||
"Wrong data in state machine!"
|
"Wrong data in state machine!"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_demo_statistics(recorder_mock, mock_history, hass):
|
|
||||||
"""Test that the demo components makes some statistics available."""
|
|
||||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
await hass.async_start()
|
|
||||||
await async_wait_recording_done(hass)
|
|
||||||
|
|
||||||
statistic_ids = await get_instance(hass).async_add_executor_job(
|
|
||||||
list_statistic_ids, hass
|
|
||||||
)
|
|
||||||
assert {
|
|
||||||
"display_unit_of_measurement": "°C",
|
|
||||||
"has_mean": True,
|
|
||||||
"has_sum": False,
|
|
||||||
"name": "Outdoor temperature",
|
|
||||||
"source": "demo",
|
|
||||||
"statistic_id": "demo:temperature_outdoor",
|
|
||||||
"statistics_unit_of_measurement": "°C",
|
|
||||||
"unit_class": "temperature",
|
|
||||||
} in statistic_ids
|
|
||||||
assert {
|
|
||||||
"display_unit_of_measurement": "kWh",
|
|
||||||
"has_mean": False,
|
|
||||||
"has_sum": True,
|
|
||||||
"name": "Energy consumption 1",
|
|
||||||
"source": "demo",
|
|
||||||
"statistic_id": "demo:energy_consumption_kwh",
|
|
||||||
"statistics_unit_of_measurement": "kWh",
|
|
||||||
"unit_class": "energy",
|
|
||||||
} in statistic_ids
|
|
||||||
|
|
||||||
|
|
||||||
async def test_demo_statistics_growth(recorder_mock, mock_history, hass):
|
|
||||||
"""Test that the demo sum statistics adds to the previous state."""
|
|
||||||
hass.config.units = US_CUSTOMARY_SYSTEM
|
|
||||||
|
|
||||||
now = dt_util.now()
|
|
||||||
last_week = now - datetime.timedelta(days=7)
|
|
||||||
last_week_midnight = last_week.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
||||||
|
|
||||||
statistic_id = f"{DOMAIN}:energy_consumption_kwh"
|
|
||||||
metadata = {
|
|
||||||
"source": DOMAIN,
|
|
||||||
"name": "Energy consumption 1",
|
|
||||||
"statistic_id": statistic_id,
|
|
||||||
"unit_of_measurement": "m³",
|
|
||||||
"has_mean": False,
|
|
||||||
"has_sum": True,
|
|
||||||
}
|
|
||||||
statistics = [
|
|
||||||
{
|
|
||||||
"start": last_week_midnight,
|
|
||||||
"sum": 2**20,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
async_add_external_statistics(hass, metadata, statistics)
|
|
||||||
await async_wait_recording_done(hass)
|
|
||||||
|
|
||||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
await hass.async_start()
|
|
||||||
await async_wait_recording_done(hass)
|
|
||||||
|
|
||||||
statistics = await get_instance(hass).async_add_executor_job(
|
|
||||||
get_last_statistics, hass, 1, statistic_id, False, {"sum"}
|
|
||||||
)
|
|
||||||
assert statistics[statistic_id][0]["sum"] > 2**20
|
|
||||||
assert statistics[statistic_id][0]["sum"] <= (2**20 + 24)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_issues_created(mock_history, hass, hass_client, hass_ws_client):
|
|
||||||
"""Test issues are created and can be fixed."""
|
|
||||||
assert await async_setup_component(hass, REPAIRS_DOMAIN, {REPAIRS_DOMAIN: {}})
|
|
||||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
await hass.async_start()
|
|
||||||
|
|
||||||
ws_client = await hass_ws_client(hass)
|
|
||||||
client = await hass_client()
|
|
||||||
|
|
||||||
await ws_client.send_json({"id": 1, "type": "repairs/list_issues"})
|
|
||||||
msg = await ws_client.receive_json()
|
|
||||||
|
|
||||||
assert msg["success"]
|
|
||||||
assert msg["result"] == {
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": "2023.1.1",
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": False,
|
|
||||||
"issue_id": "transmogrifier_deprecated",
|
|
||||||
"issue_domain": None,
|
|
||||||
"learn_more_url": "https://en.wiktionary.org/wiki/transmogrifier",
|
|
||||||
"severity": "warning",
|
|
||||||
"translation_key": "transmogrifier_deprecated",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": "2023.1.1",
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": True,
|
|
||||||
"issue_id": "out_of_blinker_fluid",
|
|
||||||
"issue_domain": None,
|
|
||||||
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
|
|
||||||
"severity": "critical",
|
|
||||||
"translation_key": "out_of_blinker_fluid",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": None,
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": False,
|
|
||||||
"issue_id": "unfixable_problem",
|
|
||||||
"issue_domain": None,
|
|
||||||
"learn_more_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
||||||
"severity": "warning",
|
|
||||||
"translation_key": "unfixable_problem",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": None,
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": True,
|
|
||||||
"issue_domain": None,
|
|
||||||
"issue_id": "bad_psu",
|
|
||||||
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
|
|
||||||
"severity": "critical",
|
|
||||||
"translation_key": "bad_psu",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": None,
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"is_fixable": True,
|
|
||||||
"issue_domain": None,
|
|
||||||
"issue_id": "cold_tea",
|
|
||||||
"learn_more_url": None,
|
|
||||||
"severity": "warning",
|
|
||||||
"translation_key": "cold_tea",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
"ignored": False,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
url = "/api/repairs/issues/fix"
|
|
||||||
resp = await client.post(
|
|
||||||
url, json={"handler": "demo", "issue_id": "out_of_blinker_fluid"}
|
|
||||||
)
|
|
||||||
|
|
||||||
assert resp.status == HTTPStatus.OK
|
|
||||||
data = await resp.json()
|
|
||||||
|
|
||||||
flow_id = data["flow_id"]
|
|
||||||
assert data == {
|
|
||||||
"data_schema": [],
|
|
||||||
"description_placeholders": None,
|
|
||||||
"errors": None,
|
|
||||||
"flow_id": ANY,
|
|
||||||
"handler": "demo",
|
|
||||||
"last_step": None,
|
|
||||||
"step_id": "confirm",
|
|
||||||
"type": "form",
|
|
||||||
}
|
|
||||||
|
|
||||||
url = f"/api/repairs/issues/fix/{flow_id}"
|
|
||||||
resp = await client.post(url)
|
|
||||||
|
|
||||||
assert resp.status == HTTPStatus.OK
|
|
||||||
data = await resp.json()
|
|
||||||
|
|
||||||
flow_id = data["flow_id"]
|
|
||||||
assert data == {
|
|
||||||
"description": None,
|
|
||||||
"description_placeholders": None,
|
|
||||||
"flow_id": flow_id,
|
|
||||||
"handler": "demo",
|
|
||||||
"type": "create_entry",
|
|
||||||
"version": 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
await ws_client.send_json({"id": 4, "type": "repairs/list_issues"})
|
|
||||||
msg = await ws_client.receive_json()
|
|
||||||
|
|
||||||
assert msg["success"]
|
|
||||||
assert msg["result"] == {
|
|
||||||
"issues": [
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": "2023.1.1",
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": False,
|
|
||||||
"issue_id": "transmogrifier_deprecated",
|
|
||||||
"issue_domain": None,
|
|
||||||
"learn_more_url": "https://en.wiktionary.org/wiki/transmogrifier",
|
|
||||||
"severity": "warning",
|
|
||||||
"translation_key": "transmogrifier_deprecated",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": None,
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": False,
|
|
||||||
"issue_id": "unfixable_problem",
|
|
||||||
"issue_domain": None,
|
|
||||||
"learn_more_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
||||||
"severity": "warning",
|
|
||||||
"translation_key": "unfixable_problem",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": None,
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"ignored": False,
|
|
||||||
"is_fixable": True,
|
|
||||||
"issue_domain": None,
|
|
||||||
"issue_id": "bad_psu",
|
|
||||||
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
|
|
||||||
"severity": "critical",
|
|
||||||
"translation_key": "bad_psu",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"breaks_in_ha_version": None,
|
|
||||||
"created": ANY,
|
|
||||||
"dismissed_version": None,
|
|
||||||
"domain": "demo",
|
|
||||||
"is_fixable": True,
|
|
||||||
"issue_domain": None,
|
|
||||||
"issue_id": "cold_tea",
|
|
||||||
"learn_more_url": None,
|
|
||||||
"severity": "warning",
|
|
||||||
"translation_key": "cold_tea",
|
|
||||||
"translation_placeholders": None,
|
|
||||||
"ignored": False,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
1
tests/components/kitchen_sink/__init__.py
Normal file
1
tests/components/kitchen_sink/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Tests for the Everything but the Kitchen Sink integration."""
|
287
tests/components/kitchen_sink/test_init.py
Normal file
287
tests/components/kitchen_sink/test_init.py
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
"""The tests for the Everything but the Kitchen Sink integration."""
|
||||||
|
import datetime
|
||||||
|
from http import HTTPStatus
|
||||||
|
from unittest.mock import ANY
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.kitchen_sink import DOMAIN
|
||||||
|
from homeassistant.components.recorder import get_instance
|
||||||
|
from homeassistant.components.recorder.statistics import (
|
||||||
|
async_add_external_statistics,
|
||||||
|
get_last_statistics,
|
||||||
|
list_statistic_ids,
|
||||||
|
)
|
||||||
|
from homeassistant.components.repairs import DOMAIN as REPAIRS_DOMAIN
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
||||||
|
|
||||||
|
from tests.components.recorder.common import async_wait_recording_done
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_history(hass):
|
||||||
|
"""Mock history component loaded."""
|
||||||
|
hass.config.components.add("history")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_demo_statistics(recorder_mock, mock_history, hass):
|
||||||
|
"""Test that the kitchen sink component makes some statistics available."""
|
||||||
|
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.async_start()
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
|
statistic_ids = await get_instance(hass).async_add_executor_job(
|
||||||
|
list_statistic_ids, hass
|
||||||
|
)
|
||||||
|
assert {
|
||||||
|
"display_unit_of_measurement": "°C",
|
||||||
|
"has_mean": True,
|
||||||
|
"has_sum": False,
|
||||||
|
"name": "Outdoor temperature",
|
||||||
|
"source": DOMAIN,
|
||||||
|
"statistic_id": f"{DOMAIN}:temperature_outdoor",
|
||||||
|
"statistics_unit_of_measurement": "°C",
|
||||||
|
"unit_class": "temperature",
|
||||||
|
} in statistic_ids
|
||||||
|
assert {
|
||||||
|
"display_unit_of_measurement": "kWh",
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
"name": "Energy consumption 1",
|
||||||
|
"source": DOMAIN,
|
||||||
|
"statistic_id": f"{DOMAIN}:energy_consumption_kwh",
|
||||||
|
"statistics_unit_of_measurement": "kWh",
|
||||||
|
"unit_class": "energy",
|
||||||
|
} in statistic_ids
|
||||||
|
|
||||||
|
|
||||||
|
async def test_demo_statistics_growth(recorder_mock, mock_history, hass):
|
||||||
|
"""Test that the kitchen sink sum statistics adds to the previous state."""
|
||||||
|
hass.config.units = US_CUSTOMARY_SYSTEM
|
||||||
|
|
||||||
|
now = dt_util.now()
|
||||||
|
last_week = now - datetime.timedelta(days=7)
|
||||||
|
last_week_midnight = last_week.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
|
|
||||||
|
statistic_id = f"{DOMAIN}:energy_consumption_kwh"
|
||||||
|
metadata = {
|
||||||
|
"source": DOMAIN,
|
||||||
|
"name": "Energy consumption 1",
|
||||||
|
"statistic_id": statistic_id,
|
||||||
|
"unit_of_measurement": "m³",
|
||||||
|
"has_mean": False,
|
||||||
|
"has_sum": True,
|
||||||
|
}
|
||||||
|
statistics = [
|
||||||
|
{
|
||||||
|
"start": last_week_midnight,
|
||||||
|
"sum": 2**20,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
async_add_external_statistics(hass, metadata, statistics)
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
|
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.async_start()
|
||||||
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
|
statistics = await get_instance(hass).async_add_executor_job(
|
||||||
|
get_last_statistics, hass, 1, statistic_id, False, {"sum"}
|
||||||
|
)
|
||||||
|
assert statistics[statistic_id][0]["sum"] > 2**20
|
||||||
|
assert statistics[statistic_id][0]["sum"] <= (2**20 + 24)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_issues_created(mock_history, hass, hass_client, hass_ws_client):
|
||||||
|
"""Test issues are created and can be fixed."""
|
||||||
|
assert await async_setup_component(hass, REPAIRS_DOMAIN, {REPAIRS_DOMAIN: {}})
|
||||||
|
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.async_start()
|
||||||
|
|
||||||
|
ws_client = await hass_ws_client(hass)
|
||||||
|
client = await hass_client()
|
||||||
|
|
||||||
|
await ws_client.send_json({"id": 1, "type": "repairs/list_issues"})
|
||||||
|
msg = await ws_client.receive_json()
|
||||||
|
|
||||||
|
assert msg["success"]
|
||||||
|
assert msg["result"] == {
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": "2023.1.1",
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": False,
|
||||||
|
"issue_id": "transmogrifier_deprecated",
|
||||||
|
"issue_domain": None,
|
||||||
|
"learn_more_url": "https://en.wiktionary.org/wiki/transmogrifier",
|
||||||
|
"severity": "warning",
|
||||||
|
"translation_key": "transmogrifier_deprecated",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": "2023.1.1",
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": True,
|
||||||
|
"issue_id": "out_of_blinker_fluid",
|
||||||
|
"issue_domain": None,
|
||||||
|
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
|
||||||
|
"severity": "critical",
|
||||||
|
"translation_key": "out_of_blinker_fluid",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": None,
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": False,
|
||||||
|
"issue_id": "unfixable_problem",
|
||||||
|
"issue_domain": None,
|
||||||
|
"learn_more_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||||
|
"severity": "warning",
|
||||||
|
"translation_key": "unfixable_problem",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": None,
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": True,
|
||||||
|
"issue_domain": None,
|
||||||
|
"issue_id": "bad_psu",
|
||||||
|
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
|
||||||
|
"severity": "critical",
|
||||||
|
"translation_key": "bad_psu",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": None,
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"is_fixable": True,
|
||||||
|
"issue_domain": None,
|
||||||
|
"issue_id": "cold_tea",
|
||||||
|
"learn_more_url": None,
|
||||||
|
"severity": "warning",
|
||||||
|
"translation_key": "cold_tea",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
"ignored": False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
url = "/api/repairs/issues/fix"
|
||||||
|
resp = await client.post(
|
||||||
|
url, json={"handler": DOMAIN, "issue_id": "out_of_blinker_fluid"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
data = await resp.json()
|
||||||
|
|
||||||
|
flow_id = data["flow_id"]
|
||||||
|
assert data == {
|
||||||
|
"data_schema": [],
|
||||||
|
"description_placeholders": None,
|
||||||
|
"errors": None,
|
||||||
|
"flow_id": ANY,
|
||||||
|
"handler": DOMAIN,
|
||||||
|
"last_step": None,
|
||||||
|
"step_id": "confirm",
|
||||||
|
"type": "form",
|
||||||
|
}
|
||||||
|
|
||||||
|
url = f"/api/repairs/issues/fix/{flow_id}"
|
||||||
|
resp = await client.post(url)
|
||||||
|
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
data = await resp.json()
|
||||||
|
|
||||||
|
flow_id = data["flow_id"]
|
||||||
|
assert data == {
|
||||||
|
"description": None,
|
||||||
|
"description_placeholders": None,
|
||||||
|
"flow_id": flow_id,
|
||||||
|
"handler": DOMAIN,
|
||||||
|
"type": "create_entry",
|
||||||
|
"version": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
await ws_client.send_json({"id": 4, "type": "repairs/list_issues"})
|
||||||
|
msg = await ws_client.receive_json()
|
||||||
|
|
||||||
|
assert msg["success"]
|
||||||
|
assert msg["result"] == {
|
||||||
|
"issues": [
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": "2023.1.1",
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": False,
|
||||||
|
"issue_id": "transmogrifier_deprecated",
|
||||||
|
"issue_domain": None,
|
||||||
|
"learn_more_url": "https://en.wiktionary.org/wiki/transmogrifier",
|
||||||
|
"severity": "warning",
|
||||||
|
"translation_key": "transmogrifier_deprecated",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": None,
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": False,
|
||||||
|
"issue_id": "unfixable_problem",
|
||||||
|
"issue_domain": None,
|
||||||
|
"learn_more_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||||
|
"severity": "warning",
|
||||||
|
"translation_key": "unfixable_problem",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": None,
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"ignored": False,
|
||||||
|
"is_fixable": True,
|
||||||
|
"issue_domain": None,
|
||||||
|
"issue_id": "bad_psu",
|
||||||
|
"learn_more_url": "https://www.youtube.com/watch?v=b9rntRxLlbU",
|
||||||
|
"severity": "critical",
|
||||||
|
"translation_key": "bad_psu",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"breaks_in_ha_version": None,
|
||||||
|
"created": ANY,
|
||||||
|
"dismissed_version": None,
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"is_fixable": True,
|
||||||
|
"issue_domain": None,
|
||||||
|
"issue_id": "cold_tea",
|
||||||
|
"learn_more_url": None,
|
||||||
|
"severity": "warning",
|
||||||
|
"translation_key": "cold_tea",
|
||||||
|
"translation_placeholders": None,
|
||||||
|
"ignored": False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue