mirror of
https://github.com/home-assistant/core.git
synced 2025-07-11 15:27:08 +00:00
Address late review of vicare config flow (#63343)
* Review comments from #56691 * Adapt to review suggestions * Update homeassistant/components/vicare/strings.json Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
10195dc700
commit
2969a7ab4f
@ -10,13 +10,7 @@ from PyViCare.PyViCareDevice import Device
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
||||||
CONF_CLIENT_ID,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_PASSWORD,
|
|
||||||
CONF_SCAN_INTERVAL,
|
|
||||||
CONF_USERNAME,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.storage import STORAGE_DIR
|
from homeassistant.helpers.storage import STORAGE_DIR
|
||||||
@ -26,6 +20,7 @@ from .const import (
|
|||||||
CONF_CIRCUIT,
|
CONF_CIRCUIT,
|
||||||
CONF_HEATING_TYPE,
|
CONF_HEATING_TYPE,
|
||||||
DEFAULT_HEATING_TYPE,
|
DEFAULT_HEATING_TYPE,
|
||||||
|
DEFAULT_SCAN_INTERVAL,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
HEATING_TYPE_TO_CREATOR_METHOD,
|
HEATING_TYPE_TO_CREATOR_METHOD,
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
@ -46,21 +41,20 @@ class ViCareRequiredKeysMixin:
|
|||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
|
vol.All(
|
||||||
|
cv.deprecated(DOMAIN),
|
||||||
{
|
{
|
||||||
DOMAIN: vol.All(
|
DOMAIN: vol.All(
|
||||||
cv.deprecated(CONF_CIRCUIT),
|
cv.deprecated(CONF_CIRCUIT),
|
||||||
|
cv.deprecated(DOMAIN),
|
||||||
vol.Schema(
|
vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_USERNAME): cv.string,
|
vol.Required(CONF_USERNAME): cv.string,
|
||||||
vol.Required(CONF_PASSWORD): cv.string,
|
vol.Required(CONF_PASSWORD): cv.string,
|
||||||
vol.Required(CONF_CLIENT_ID): cv.string,
|
vol.Required(CONF_CLIENT_ID): cv.string,
|
||||||
vol.Optional(CONF_SCAN_INTERVAL, default=60): vol.All(
|
|
||||||
cv.time_period, lambda value: value.total_seconds()
|
|
||||||
),
|
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_CIRCUIT
|
CONF_CIRCUIT
|
||||||
): int, # Ignored: All circuits are now supported. Will be removed when switching to Setup via UI.
|
): int, # Ignored: All circuits are now supported. Will be removed when switching to Setup via UI.
|
||||||
vol.Optional(CONF_NAME, default="ViCare"): cv.string,
|
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_HEATING_TYPE, default=DEFAULT_HEATING_TYPE.value
|
CONF_HEATING_TYPE, default=DEFAULT_HEATING_TYPE.value
|
||||||
): vol.In([e.value for e in HeatingType]),
|
): vol.In([e.value for e in HeatingType]),
|
||||||
@ -68,6 +62,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
),
|
||||||
extra=vol.ALLOW_EXTRA,
|
extra=vol.ALLOW_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -106,7 +101,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
def vicare_login(hass, entry_data):
|
def vicare_login(hass, entry_data):
|
||||||
"""Login via PyVicare API."""
|
"""Login via PyVicare API."""
|
||||||
vicare_api = PyViCare()
|
vicare_api = PyViCare()
|
||||||
vicare_api.setCacheDuration(entry_data[CONF_SCAN_INTERVAL])
|
vicare_api.setCacheDuration(DEFAULT_SCAN_INTERVAL)
|
||||||
vicare_api.initWithCredentials(
|
vicare_api.initWithCredentials(
|
||||||
entry_data[CONF_USERNAME],
|
entry_data[CONF_USERNAME],
|
||||||
entry_data[CONF_PASSWORD],
|
entry_data[CONF_PASSWORD],
|
||||||
|
@ -18,12 +18,17 @@ from homeassistant.components.binary_sensor import (
|
|||||||
BinarySensorEntityDescription,
|
BinarySensorEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_NAME
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import ViCareRequiredKeysMixin
|
from . import ViCareRequiredKeysMixin
|
||||||
from .const import DOMAIN, VICARE_API, VICARE_CIRCUITS, VICARE_DEVICE_CONFIG
|
from .const import (
|
||||||
|
DOMAIN,
|
||||||
|
VICARE_API,
|
||||||
|
VICARE_CIRCUITS,
|
||||||
|
VICARE_DEVICE_CONFIG,
|
||||||
|
VICARE_NAME,
|
||||||
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -88,7 +93,7 @@ def _build_entity(name, vicare_api, device_config, sensor):
|
|||||||
|
|
||||||
|
|
||||||
async def _entities_from_descriptions(
|
async def _entities_from_descriptions(
|
||||||
hass, name, all_devices, sensor_descriptions, iterables, config_entry
|
hass, name, entities, sensor_descriptions, iterables, config_entry
|
||||||
):
|
):
|
||||||
"""Create entities from descriptions and list of burners/circuits."""
|
"""Create entities from descriptions and list of burners/circuits."""
|
||||||
for description in sensor_descriptions:
|
for description in sensor_descriptions:
|
||||||
@ -104,19 +109,19 @@ async def _entities_from_descriptions(
|
|||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: ConfigEntry,
|
||||||
async_add_devices: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the ViCare binary sensor devices."""
|
"""Create the ViCare binary sensor devices."""
|
||||||
name = config_entry.data[CONF_NAME]
|
name = VICARE_NAME
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
||||||
|
|
||||||
all_devices = []
|
entities = []
|
||||||
|
|
||||||
for description in CIRCUIT_SENSORS:
|
for description in CIRCUIT_SENSORS:
|
||||||
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
||||||
@ -131,23 +136,23 @@ async def async_setup_entry(
|
|||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await _entities_from_descriptions(
|
await _entities_from_descriptions(
|
||||||
hass, name, all_devices, BURNER_SENSORS, api.burners, config_entry
|
hass, name, entities, BURNER_SENSORS, api.burners, config_entry
|
||||||
)
|
)
|
||||||
except PyViCareNotSupportedFeatureError:
|
except PyViCareNotSupportedFeatureError:
|
||||||
_LOGGER.info("No burners found")
|
_LOGGER.info("No burners found")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await _entities_from_descriptions(
|
await _entities_from_descriptions(
|
||||||
hass, name, all_devices, COMPRESSOR_SENSORS, api.compressors, config_entry
|
hass, name, entities, COMPRESSOR_SENSORS, api.compressors, config_entry
|
||||||
)
|
)
|
||||||
except PyViCareNotSupportedFeatureError:
|
except PyViCareNotSupportedFeatureError:
|
||||||
_LOGGER.info("No compressors found")
|
_LOGGER.info("No compressors found")
|
||||||
|
|
||||||
async_add_devices(all_devices)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class ViCareBinarySensor(BinarySensorEntity):
|
class ViCareBinarySensor(BinarySensorEntity):
|
||||||
|
@ -23,12 +23,7 @@ from homeassistant.components.climate.const import (
|
|||||||
SUPPORT_TARGET_TEMPERATURE,
|
SUPPORT_TARGET_TEMPERATURE,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
|
||||||
ATTR_TEMPERATURE,
|
|
||||||
CONF_NAME,
|
|
||||||
PRECISION_WHOLE,
|
|
||||||
TEMP_CELSIUS,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_platform
|
from homeassistant.helpers import entity_platform
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
@ -40,6 +35,7 @@ from .const import (
|
|||||||
VICARE_API,
|
VICARE_API,
|
||||||
VICARE_CIRCUITS,
|
VICARE_CIRCUITS,
|
||||||
VICARE_DEVICE_CONFIG,
|
VICARE_DEVICE_CONFIG,
|
||||||
|
VICARE_NAME,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -109,12 +105,12 @@ def _build_entity(name, vicare_api, circuit, device_config, heating_type):
|
|||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: ConfigEntry,
|
||||||
async_add_devices: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the ViCare climate platform."""
|
"""Set up the ViCare climate platform."""
|
||||||
name = config_entry.data[CONF_NAME]
|
name = VICARE_NAME
|
||||||
|
|
||||||
all_devices = []
|
entities = []
|
||||||
|
|
||||||
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
||||||
suffix = ""
|
suffix = ""
|
||||||
@ -128,7 +124,7 @@ async def async_setup_entry(
|
|||||||
config_entry.data[CONF_HEATING_TYPE],
|
config_entry.data[CONF_HEATING_TYPE],
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
platform = entity_platform.async_get_current_platform()
|
platform = entity_platform.async_get_current_platform()
|
||||||
|
|
||||||
@ -138,7 +134,7 @@ async def async_setup_entry(
|
|||||||
"set_vicare_mode",
|
"set_vicare_mode",
|
||||||
)
|
)
|
||||||
|
|
||||||
async_add_devices(all_devices)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class ViCareClimate(ClimateEntity):
|
class ViCareClimate(ClimateEntity):
|
||||||
|
@ -9,13 +9,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components import dhcp
|
from homeassistant.components import dhcp
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
||||||
CONF_CLIENT_ID,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_PASSWORD,
|
|
||||||
CONF_SCAN_INTERVAL,
|
|
||||||
CONF_USERNAME,
|
|
||||||
)
|
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.device_registry import format_mac
|
from homeassistant.helpers.device_registry import format_mac
|
||||||
@ -25,8 +19,8 @@ from .const import (
|
|||||||
CONF_CIRCUIT,
|
CONF_CIRCUIT,
|
||||||
CONF_HEATING_TYPE,
|
CONF_HEATING_TYPE,
|
||||||
DEFAULT_HEATING_TYPE,
|
DEFAULT_HEATING_TYPE,
|
||||||
DEFAULT_SCAN_INTERVAL,
|
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
VICARE_NAME,
|
||||||
HeatingType,
|
HeatingType,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -50,10 +44,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
vol.Required(CONF_HEATING_TYPE, default=DEFAULT_HEATING_TYPE.value): vol.In(
|
vol.Required(CONF_HEATING_TYPE, default=DEFAULT_HEATING_TYPE.value): vol.In(
|
||||||
[e.value for e in HeatingType]
|
[e.value for e in HeatingType]
|
||||||
),
|
),
|
||||||
vol.Optional(CONF_NAME, default="ViCare"): cv.string,
|
|
||||||
vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): vol.All(
|
|
||||||
vol.Coerce(int), vol.Range(min=30)
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
errors: dict[str, str] = {}
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
@ -62,12 +52,10 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
await self.hass.async_add_executor_job(
|
await self.hass.async_add_executor_job(
|
||||||
vicare_login, self.hass, user_input
|
vicare_login, self.hass, user_input
|
||||||
)
|
)
|
||||||
return self.async_create_entry(
|
except PyViCareInvalidCredentialsError:
|
||||||
title=user_input[CONF_NAME], data=user_input
|
|
||||||
)
|
|
||||||
except PyViCareInvalidCredentialsError as ex:
|
|
||||||
_LOGGER.debug("Could not log in to ViCare, %s", ex)
|
|
||||||
errors["base"] = "invalid_auth"
|
errors["base"] = "invalid_auth"
|
||||||
|
else:
|
||||||
|
return self.async_create_entry(title=VICARE_NAME, data=user_input)
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="user",
|
step_id="user",
|
||||||
@ -90,22 +78,14 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
async def async_step_import(self, import_info):
|
async def async_step_import(self, import_info):
|
||||||
"""Handle a flow initiated by a YAML config import."""
|
"""Handle a flow initiated by a YAML config import."""
|
||||||
|
|
||||||
await self.async_set_unique_id("Configuration.yaml")
|
|
||||||
self._abort_if_unique_id_configured()
|
|
||||||
|
|
||||||
if self._async_current_entries():
|
if self._async_current_entries():
|
||||||
return self.async_abort(reason="single_instance_allowed")
|
return self.async_abort(reason="single_instance_allowed")
|
||||||
|
|
||||||
# Remove now unsupported config parameters
|
# Remove now unsupported config parameters
|
||||||
if import_info.get(CONF_CIRCUIT):
|
import_info.pop(CONF_CIRCUIT, None)
|
||||||
import_info.pop(CONF_CIRCUIT)
|
|
||||||
|
|
||||||
# Add former optional config if missing
|
# CONF_HEATING_TYPE is now required but was optional in yaml config. Add if missing.
|
||||||
if import_info.get(CONF_HEATING_TYPE) is None:
|
if import_info.get(CONF_HEATING_TYPE) is None:
|
||||||
import_info[CONF_HEATING_TYPE] = DEFAULT_HEATING_TYPE.value
|
import_info[CONF_HEATING_TYPE] = DEFAULT_HEATING_TYPE.value
|
||||||
|
|
||||||
return self.async_create_entry(
|
return await self.async_step_user(import_info)
|
||||||
title="Configuration.yaml",
|
|
||||||
data=import_info,
|
|
||||||
)
|
|
||||||
|
@ -16,6 +16,7 @@ PLATFORMS = [
|
|||||||
VICARE_DEVICE_CONFIG = "device_conf"
|
VICARE_DEVICE_CONFIG = "device_conf"
|
||||||
VICARE_API = "api"
|
VICARE_API = "api"
|
||||||
VICARE_CIRCUITS = "circuits"
|
VICARE_CIRCUITS = "circuits"
|
||||||
|
VICARE_NAME = "ViCare"
|
||||||
|
|
||||||
CONF_CIRCUIT = "circuit"
|
CONF_CIRCUIT = "circuit"
|
||||||
CONF_HEATING_TYPE = "heating_type"
|
CONF_HEATING_TYPE = "heating_type"
|
||||||
|
@ -22,7 +22,6 @@ from homeassistant.components.sensor import (
|
|||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_NAME,
|
|
||||||
ENERGY_KILO_WATT_HOUR,
|
ENERGY_KILO_WATT_HOUR,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
POWER_WATT,
|
POWER_WATT,
|
||||||
@ -39,6 +38,7 @@ from .const import (
|
|||||||
VICARE_API,
|
VICARE_API,
|
||||||
VICARE_CIRCUITS,
|
VICARE_CIRCUITS,
|
||||||
VICARE_DEVICE_CONFIG,
|
VICARE_DEVICE_CONFIG,
|
||||||
|
VICARE_NAME,
|
||||||
VICARE_UNIT_TO_DEVICE_CLASS,
|
VICARE_UNIT_TO_DEVICE_CLASS,
|
||||||
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT,
|
VICARE_UNIT_TO_UNIT_OF_MEASUREMENT,
|
||||||
)
|
)
|
||||||
@ -339,7 +339,7 @@ def _build_entity(name, vicare_api, device_config, sensor):
|
|||||||
|
|
||||||
|
|
||||||
async def _entities_from_descriptions(
|
async def _entities_from_descriptions(
|
||||||
hass, name, all_devices, sensor_descriptions, iterables, config_entry
|
hass, name, entities, sensor_descriptions, iterables, config_entry
|
||||||
):
|
):
|
||||||
"""Create entities from descriptions and list of burners/circuits."""
|
"""Create entities from descriptions and list of burners/circuits."""
|
||||||
for description in sensor_descriptions:
|
for description in sensor_descriptions:
|
||||||
@ -355,19 +355,19 @@ async def _entities_from_descriptions(
|
|||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: ConfigEntry,
|
||||||
async_add_devices: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the ViCare sensor devices."""
|
"""Create the ViCare sensor devices."""
|
||||||
name = config_entry.data[CONF_NAME]
|
name = VICARE_NAME
|
||||||
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
api = hass.data[DOMAIN][config_entry.entry_id][VICARE_API]
|
||||||
|
|
||||||
all_devices = []
|
entities = []
|
||||||
for description in GLOBAL_SENSORS:
|
for description in GLOBAL_SENSORS:
|
||||||
entity = await hass.async_add_executor_job(
|
entity = await hass.async_add_executor_job(
|
||||||
_build_entity,
|
_build_entity,
|
||||||
@ -377,7 +377,7 @@ async def async_setup_entry(
|
|||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
for description in CIRCUIT_SENSORS:
|
for description in CIRCUIT_SENSORS:
|
||||||
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
||||||
@ -392,23 +392,23 @@ async def async_setup_entry(
|
|||||||
description,
|
description,
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await _entities_from_descriptions(
|
await _entities_from_descriptions(
|
||||||
hass, name, all_devices, BURNER_SENSORS, api.burners, config_entry
|
hass, name, entities, BURNER_SENSORS, api.burners, config_entry
|
||||||
)
|
)
|
||||||
except PyViCareNotSupportedFeatureError:
|
except PyViCareNotSupportedFeatureError:
|
||||||
_LOGGER.info("No burners found")
|
_LOGGER.info("No burners found")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await _entities_from_descriptions(
|
await _entities_from_descriptions(
|
||||||
hass, name, all_devices, COMPRESSOR_SENSORS, api.compressors, config_entry
|
hass, name, entities, COMPRESSOR_SENSORS, api.compressors, config_entry
|
||||||
)
|
)
|
||||||
except PyViCareNotSupportedFeatureError:
|
except PyViCareNotSupportedFeatureError:
|
||||||
_LOGGER.info("No compressors found")
|
_LOGGER.info("No compressors found")
|
||||||
|
|
||||||
async_add_devices(all_devices)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class ViCareSensor(SensorEntity):
|
class ViCareSensor(SensorEntity):
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
"title": "{name}",
|
"title": "{name}",
|
||||||
"description": "Set up ViCare integration. To generate API key go to https://developer.viessmann.com",
|
"description": "Set up ViCare integration. To generate API key go to https://developer.viessmann.com",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "[%key:common::config_flow::data::name%]",
|
|
||||||
"scan_interval": "Scan Interval (seconds)",
|
|
||||||
"username": "[%key:common::config_flow::data::email%]",
|
"username": "[%key:common::config_flow::data::email%]",
|
||||||
"password": "[%key:common::config_flow::data::password%]",
|
"password": "[%key:common::config_flow::data::password%]",
|
||||||
"client_id": "[%key:common::config_flow::data::api_key%]",
|
"client_id": "[%key:common::config_flow::data::api_key%]",
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
"heating_type": "Heating type",
|
"heating_type": "Heating type",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"scan_interval": "Scan Interval (seconds)",
|
|
||||||
"username": "Email"
|
"username": "Email"
|
||||||
},
|
},
|
||||||
"description": "Set up ViCare integration. To generate API key go to https://developer.viessmann.com",
|
"description": "Set up ViCare integration. To generate API key go to https://developer.viessmann.com",
|
||||||
|
@ -14,12 +14,7 @@ from homeassistant.components.water_heater import (
|
|||||||
WaterHeaterEntity,
|
WaterHeaterEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
|
||||||
ATTR_TEMPERATURE,
|
|
||||||
CONF_NAME,
|
|
||||||
PRECISION_WHOLE,
|
|
||||||
TEMP_CELSIUS,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
@ -29,6 +24,7 @@ from .const import (
|
|||||||
VICARE_API,
|
VICARE_API,
|
||||||
VICARE_CIRCUITS,
|
VICARE_CIRCUITS,
|
||||||
VICARE_DEVICE_CONFIG,
|
VICARE_DEVICE_CONFIG,
|
||||||
|
VICARE_NAME,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -76,12 +72,12 @@ def _build_entity(name, vicare_api, circuit, device_config, heating_type):
|
|||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: ConfigEntry,
|
||||||
async_add_devices: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the ViCare climate platform."""
|
"""Set up the ViCare climate platform."""
|
||||||
name = config_entry.data[CONF_NAME]
|
name = VICARE_NAME
|
||||||
|
|
||||||
all_devices = []
|
entities = []
|
||||||
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
for circuit in hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]:
|
||||||
suffix = ""
|
suffix = ""
|
||||||
if len(hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]) > 1:
|
if len(hass.data[DOMAIN][config_entry.entry_id][VICARE_CIRCUITS]) > 1:
|
||||||
@ -94,9 +90,9 @@ async def async_setup_entry(
|
|||||||
config_entry.data[CONF_HEATING_TYPE],
|
config_entry.data[CONF_HEATING_TYPE],
|
||||||
)
|
)
|
||||||
if entity is not None:
|
if entity is not None:
|
||||||
all_devices.append(entity)
|
entities.append(entity)
|
||||||
|
|
||||||
async_add_devices(all_devices)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class ViCareWater(WaterHeaterEntity):
|
class ViCareWater(WaterHeaterEntity):
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
"""Test for ViCare."""
|
"""Test for ViCare."""
|
||||||
from homeassistant.components.vicare.const import CONF_HEATING_TYPE
|
from __future__ import annotations
|
||||||
from homeassistant.const import (
|
|
||||||
CONF_CLIENT_ID,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_PASSWORD,
|
|
||||||
CONF_SCAN_INTERVAL,
|
|
||||||
CONF_USERNAME,
|
|
||||||
)
|
|
||||||
|
|
||||||
ENTRY_CONFIG = {
|
from typing import Final
|
||||||
|
|
||||||
|
from homeassistant.components.vicare.const import CONF_HEATING_TYPE
|
||||||
|
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
||||||
|
|
||||||
|
ENTRY_CONFIG: Final[dict[str, str]] = {
|
||||||
CONF_USERNAME: "foo@bar.com",
|
CONF_USERNAME: "foo@bar.com",
|
||||||
CONF_PASSWORD: "1234",
|
CONF_PASSWORD: "1234",
|
||||||
CONF_CLIENT_ID: "5678",
|
CONF_CLIENT_ID: "5678",
|
||||||
CONF_HEATING_TYPE: "auto",
|
CONF_HEATING_TYPE: "auto",
|
||||||
CONF_SCAN_INTERVAL: 60,
|
}
|
||||||
CONF_NAME: "ViCare",
|
|
||||||
|
ENTRY_CONFIG_NO_HEATING_TYPE: Final[dict[str, str]] = {
|
||||||
|
CONF_USERNAME: "foo@bar.com",
|
||||||
|
CONF_PASSWORD: "1234",
|
||||||
|
CONF_CLIENT_ID: "5678",
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_MAC = "B874241B7B9"
|
MOCK_MAC = "B874241B7B9"
|
||||||
|
@ -3,23 +3,18 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
from PyViCare.PyViCareUtils import PyViCareInvalidCredentialsError
|
from PyViCare.PyViCareUtils import PyViCareInvalidCredentialsError
|
||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow, setup
|
from homeassistant import config_entries, data_entry_flow
|
||||||
from homeassistant.components import dhcp
|
from homeassistant.components import dhcp
|
||||||
from homeassistant.components.vicare.const import (
|
from homeassistant.components.vicare.const import CONF_CIRCUIT, DOMAIN, VICARE_NAME
|
||||||
CONF_CIRCUIT,
|
|
||||||
CONF_HEATING_TYPE,
|
|
||||||
DOMAIN,
|
|
||||||
)
|
|
||||||
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
|
||||||
|
|
||||||
from . import ENTRY_CONFIG, MOCK_MAC
|
from . import ENTRY_CONFIG, ENTRY_CONFIG_NO_HEATING_TYPE, MOCK_MAC
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
async def test_form(hass):
|
async def test_form(hass):
|
||||||
"""Test we get the form."""
|
"""Test we get the form."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
)
|
)
|
||||||
@ -54,7 +49,6 @@ async def test_form(hass):
|
|||||||
|
|
||||||
async def test_import(hass):
|
async def test_import(hass):
|
||||||
"""Test that the import works."""
|
"""Test that the import works."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vicare.config_flow.vicare_login",
|
"homeassistant.components.vicare.config_flow.vicare_login",
|
||||||
@ -71,7 +65,7 @@ async def test_import(hass):
|
|||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["title"] == "Configuration.yaml"
|
assert result["title"] == VICARE_NAME
|
||||||
assert result["data"] == ENTRY_CONFIG
|
assert result["data"] == ENTRY_CONFIG
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -81,7 +75,6 @@ async def test_import(hass):
|
|||||||
|
|
||||||
async def test_import_removes_circuit(hass):
|
async def test_import_removes_circuit(hass):
|
||||||
"""Test that the import works."""
|
"""Test that the import works."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vicare.config_flow.vicare_login",
|
"homeassistant.components.vicare.config_flow.vicare_login",
|
||||||
@ -99,7 +92,7 @@ async def test_import_removes_circuit(hass):
|
|||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["title"] == "Configuration.yaml"
|
assert result["title"] == VICARE_NAME
|
||||||
assert result["data"] == ENTRY_CONFIG
|
assert result["data"] == ENTRY_CONFIG
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -109,7 +102,6 @@ async def test_import_removes_circuit(hass):
|
|||||||
|
|
||||||
async def test_import_adds_heating_type(hass):
|
async def test_import_adds_heating_type(hass):
|
||||||
"""Test that the import works."""
|
"""Test that the import works."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.vicare.config_flow.vicare_login",
|
"homeassistant.components.vicare.config_flow.vicare_login",
|
||||||
@ -120,14 +112,13 @@ async def test_import_adds_heating_type(hass):
|
|||||||
"homeassistant.components.vicare.async_setup_entry",
|
"homeassistant.components.vicare.async_setup_entry",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_setup_entry:
|
) as mock_setup_entry:
|
||||||
del ENTRY_CONFIG[CONF_HEATING_TYPE]
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG_NO_HEATING_TYPE,
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["title"] == "Configuration.yaml"
|
assert result["title"] == VICARE_NAME
|
||||||
assert result["data"] == ENTRY_CONFIG
|
assert result["data"] == ENTRY_CONFIG
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -162,7 +153,6 @@ async def test_invalid_login(hass) -> None:
|
|||||||
|
|
||||||
async def test_form_dhcp(hass):
|
async def test_form_dhcp(hass):
|
||||||
"""Test we can setup from dhcp."""
|
"""Test we can setup from dhcp."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -203,29 +193,10 @@ async def test_form_dhcp(hass):
|
|||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_import_already_configured(hass):
|
|
||||||
"""Test that configuring same instance is rejectes."""
|
|
||||||
mock_entry = MockConfigEntry(
|
|
||||||
domain=DOMAIN,
|
|
||||||
unique_id="Configuration.yaml",
|
|
||||||
data=ENTRY_CONFIG,
|
|
||||||
)
|
|
||||||
mock_entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
|
||||||
data=ENTRY_CONFIG,
|
|
||||||
)
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
|
||||||
assert result["reason"] == "already_configured"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import_single_instance_allowed(hass):
|
async def test_import_single_instance_allowed(hass):
|
||||||
"""Test that configuring more than one instance is rejected."""
|
"""Test that configuring more than one instance is rejected."""
|
||||||
mock_entry = MockConfigEntry(
|
mock_entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id="Configuration.yaml",
|
|
||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
)
|
)
|
||||||
mock_entry.add_to_hass(hass)
|
mock_entry.add_to_hass(hass)
|
||||||
@ -236,14 +207,13 @@ async def test_import_single_instance_allowed(hass):
|
|||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "single_instance_allowed"
|
||||||
|
|
||||||
|
|
||||||
async def test_dhcp_single_instance_allowed(hass):
|
async def test_dhcp_single_instance_allowed(hass):
|
||||||
"""Test that configuring more than one instance is rejected."""
|
"""Test that configuring more than one instance is rejected."""
|
||||||
mock_entry = MockConfigEntry(
|
mock_entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id="Configuration.yaml",
|
|
||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
)
|
)
|
||||||
mock_entry.add_to_hass(hass)
|
mock_entry.add_to_hass(hass)
|
||||||
@ -263,7 +233,6 @@ async def test_dhcp_single_instance_allowed(hass):
|
|||||||
|
|
||||||
async def test_user_input_single_instance_allowed(hass):
|
async def test_user_input_single_instance_allowed(hass):
|
||||||
"""Test that configuring more than one instance is rejected."""
|
"""Test that configuring more than one instance is rejected."""
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
mock_entry = MockConfigEntry(
|
mock_entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id="ViCare",
|
unique_id="ViCare",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user