Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions homeassistant/components/geo_location/trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import voluptuous as vol

from homeassistant.components.zone import condition as zone_condition
from homeassistant.const import CONF_EVENT, CONF_PLATFORM, CONF_SOURCE, CONF_ZONE
from homeassistant.core import (
CALLBACK_TYPE,
Expand All @@ -17,7 +18,7 @@
State,
callback,
)
from homeassistant.helpers import condition, config_validation as cv
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.config_validation import entity_domain
from homeassistant.helpers.event import TrackStates, async_track_state_change_filtered
from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
Expand Down Expand Up @@ -79,9 +80,11 @@ def state_change_listener(event: Event[EventStateChangedData]) -> None:
return

from_match = (
condition.zone(hass, zone_state, from_state) if from_state else False
zone_condition.zone(hass, zone_state, from_state) if from_state else False
)
to_match = (
zone_condition.zone(hass, zone_state, to_state) if to_state else False
)
to_match = condition.zone(hass, zone_state, to_state) if to_state else False

if (trigger_event == EVENT_ENTER and not from_match and to_match) or (
trigger_event == EVENT_LEAVE and from_match and not to_match
Expand Down
16 changes: 14 additions & 2 deletions homeassistant/components/goodwe/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""The Goodwe inverter component."""

from goodwe import InverterError, connect
from goodwe.const import GOODWE_TCP_PORT, GOODWE_UDP_PORT

from homeassistant.const import CONF_HOST
from homeassistant.core import HomeAssistant
Expand All @@ -20,11 +21,22 @@ async def async_setup_entry(hass: HomeAssistant, entry: GoodweConfigEntry) -> bo
try:
inverter = await connect(
host=host,
port=GOODWE_UDP_PORT,
family=model_family,
retries=10,
)
except InverterError as err:
raise ConfigEntryNotReady from err
except InverterError as err_udp:
# First try with UDP failed, trying with the TCP port
try:
inverter = await connect(
host=host,
port=GOODWE_TCP_PORT,
family=model_family,
retries=10,
)
except InverterError:
# Both ports are unavailable
raise ConfigEntryNotReady from err_udp

device_info = DeviceInfo(
configuration_url="https://www.semsportal.com",
Expand Down
36 changes: 23 additions & 13 deletions homeassistant/components/goodwe/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import Any

from goodwe import InverterError, connect
from goodwe.const import GOODWE_TCP_PORT, GOODWE_UDP_PORT
import voluptuous as vol

from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
Expand All @@ -27,29 +28,38 @@ class GoodweFlowHandler(ConfigFlow, domain=DOMAIN):

VERSION = 1

async def _handle_successful_connection(self, inverter, host):
await self.async_set_unique_id(inverter.serial_number)
self._abort_if_unique_id_configured()

return self.async_create_entry(
title=DEFAULT_NAME,
data={
CONF_HOST: host,
CONF_MODEL_FAMILY: type(inverter).__name__,
},
)

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a flow initialized by the user."""
errors = {}
if user_input is not None:
host = user_input[CONF_HOST]

try:
inverter = await connect(host=host, retries=10)
inverter = await connect(host=host, port=GOODWE_UDP_PORT, retries=10)
except InverterError:
errors[CONF_HOST] = "connection_error"
try:
inverter = await connect(
host=host, port=GOODWE_TCP_PORT, retries=10
)
except InverterError:
errors[CONF_HOST] = "connection_error"
else:
return await self._handle_successful_connection(inverter, host)
else:
await self.async_set_unique_id(inverter.serial_number)
self._abort_if_unique_id_configured()

return self.async_create_entry(
title=DEFAULT_NAME,
data={
CONF_HOST: host,
CONF_MODEL_FAMILY: type(inverter).__name__,
},
)
return await self._handle_successful_connection(inverter, host)

return self.async_show_form(
step_id="user", data_schema=CONFIG_SCHEMA, errors=errors
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/goodwe/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/goodwe",
"iot_class": "local_polling",
"loggers": ["goodwe"],
"requirements": ["goodwe==0.3.6"]
"requirements": ["goodwe==0.4.8"]
}
29 changes: 18 additions & 11 deletions homeassistant/components/goodwe/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,24 @@ async def async_setup_entry(
# Inverter model does not support this setting
_LOGGER.debug("Could not read inverter operation mode")
else:
async_add_entities(
[
InverterOperationModeEntity(
device_info,
OPERATION_MODE,
inverter,
[v for k, v in _MODE_TO_OPTION.items() if k in supported_modes],
_MODE_TO_OPTION[active_mode],
)
]
)
active_mode_option = _MODE_TO_OPTION.get(active_mode)
if active_mode_option is not None:
async_add_entities(
[
InverterOperationModeEntity(
device_info,
OPERATION_MODE,
inverter,
[v for k, v in _MODE_TO_OPTION.items() if k in supported_modes],
active_mode_option,
)
]
)
else:
_LOGGER.warning(
"Active mode %s not found in Goodwe Inverter Operation Mode Entity. Skipping entity creation",
active_mode,
)


class InverterOperationModeEntity(SelectEntity):
Expand Down
40 changes: 38 additions & 2 deletions homeassistant/components/nibe_heatpump/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@

from nibe.coil import Coil, CoilData
from nibe.connection import Connection
from nibe.exceptions import CoilNotFoundException, ReadException
from nibe.exceptions import (
CoilNotFoundException,
ReadException,
WriteDeniedException,
WriteException,
WriteTimeoutException,
)
from nibe.heatpump import HeatPump, Series
from propcache.api import cached_property

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

Expand Down Expand Up @@ -134,7 +141,36 @@ def get_coil_float(self, coil: Coil) -> float | None:
async def async_write_coil(self, coil: Coil, value: float | str) -> None:
"""Write coil and update state."""
data = CoilData(coil, value)
await self.connection.write_coil(data)
try:
await self.connection.write_coil(data)
except WriteDeniedException as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="write_denied",
translation_placeholders={
"address": str(coil.address),
"value": str(value),
},
) from e
except WriteTimeoutException as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="write_timeout",
translation_placeholders={
"address": str(coil.address),
},
) from e
except WriteException as e:
LOGGER.debug("Failed to write", exc_info=True)
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="write_failed",
translation_placeholders={
"address": str(coil.address),
"value": str(value),
"error": str(e),
},
) from e

self.data[coil.address] = data

Expand Down
11 changes: 11 additions & 0 deletions homeassistant/components/nibe_heatpump/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,16 @@
"unknown": "[%key:common::config_flow::error::unknown%]",
"url": "The specified URL is not well formed nor supported"
}
},
"exceptions": {
"write_denied": {
"message": "Writing of coil {address} with value `{value}` was denied"
},
"write_timeout": {
"message": "Timeout while writing coil {address}"
},
"write_failed": {
"message": "Writing of coil {address} with value `{value}` failed with error `{error}`"
}
}
}
2 changes: 1 addition & 1 deletion homeassistant/components/openai_conversation/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"documentation": "https://www.home-assistant.io/integrations/openai_conversation",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["openai==1.76.2"]
"requirements": ["openai==1.93.0"]
}
Loading
Loading