Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
4 changes: 2 additions & 2 deletions custom_components/plugwise/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def __init__(
self._notification: dict[str, str] = {} # pw-beta

@property
def is_on(self) -> bool:
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
# pw-beta: show Plugwise notifications as HA persistent notifications
if self._notification:
Expand All @@ -174,7 +174,7 @@ def is_on(self) -> bool:
self.hass, message, "Plugwise Notification:", f"{DOMAIN}.{notify_id}"
)

return self.device[BINARY_SENSORS][self.entity_description.key]
return self.device.get(BINARY_SENSORS, {}).get(self.entity_description.key)

@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
Expand Down
36 changes: 16 additions & 20 deletions custom_components/plugwise/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .const import (
Expand Down Expand Up @@ -127,11 +126,11 @@ def __init__(
if (location := self.device.get(LOCATION)) is not None:
self._location = location

self._attr_max_temp = min(self.device[THERMOSTAT][UPPER_BOUND], 35.0)
self._attr_min_temp = self.device[THERMOSTAT][LOWER_BOUND]
self._attr_max_temp = min(self.device.get(THERMOSTAT, {}).get(UPPER_BOUND, 35.0), 35.0)
self._attr_min_temp = self.device.get(THERMOSTAT, {}).get(LOWER_BOUND, 0.0)
# Ensure we don't drop below 0.1
self._attr_target_temperature_step = max(
self.device[THERMOSTAT][RESOLUTION], 0.1
self.device.get(THERMOSTAT, {}).get(RESOLUTION, 0.5), 0.1
)
self._attr_unique_id = f"{device_id}-climate"

Expand All @@ -148,7 +147,7 @@ def __init__(
self._attr_supported_features |= (
ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
)
if presets := self.device["preset_modes"]: # can be NONE
if presets := self.device.get("preset_modes", None): # can be NONE
self._attr_supported_features |= ClimateEntityFeature.PRESET_MODE
self._attr_preset_modes = presets

Expand All @@ -167,40 +166,40 @@ def _previous_action_mode(self, coordinator: PlugwiseDataUpdateCoordinator) -> N
self._previous_mode = mode

@property
def current_temperature(self) -> float:
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self.device[SENSORS][ATTR_TEMPERATURE]
return self.device.get(SENSORS, {}).get(ATTR_TEMPERATURE)

@property
def target_temperature(self) -> float:
def target_temperature(self) -> float | None:
"""Return the temperature we try to reach.

Connected to the HVACMode combination of AUTO-HEAT.
"""

return self.device[THERMOSTAT][TARGET_TEMP]
return self.device.get(THERMOSTAT, {}).get(TARGET_TEMP)

@property
def target_temperature_high(self) -> float:
def target_temperature_high(self) -> float | None:
"""Return the temperature we try to reach in case of cooling.

Connected to the HVACMode combination of AUTO-HEAT_COOL.
"""
return self.device[THERMOSTAT][TARGET_TEMP_HIGH]
return self.device.get(THERMOSTAT, {}).get(TARGET_TEMP_HIGH)

@property
def target_temperature_low(self) -> float:
def target_temperature_low(self) -> float | None:
"""Return the heating temperature we try to reach in case of heating.

Connected to the HVACMode combination AUTO-HEAT_COOL.
"""
return self.device[THERMOSTAT][TARGET_TEMP_LOW]
return self.device.get(THERMOSTAT, {}).get(TARGET_TEMP_LOW)

@property
def hvac_mode(self) -> HVACMode:
"""Return HVAC operation ie. auto, cool, heat, heat_cool, or off mode."""
if (
mode := self.device[CLIMATE_MODE]
mode := self.device.get(CLIMATE_MODE)
) is None or mode not in self.hvac_modes: # pw-beta add to Core
return HVACMode.HEAT # pragma: no cover
# pw-beta homekit emulation
Expand All @@ -219,7 +218,7 @@ def hvac_modes(self) -> list[HVACMode]:
):
hvac_modes.append(HVACMode.OFF)

if self.device.get(AVAILABLE_SCHEDULES):
if self.device.get(AVAILABLE_SCHEDULES, []):
hvac_modes.append(HVACMode.AUTO)

if self.coordinator.api.cooling_present:
Expand Down Expand Up @@ -249,7 +248,7 @@ def hvac_action(self) -> HVACAction: # pw-beta add to Core
@property
def preset_mode(self) -> str | None:
"""Return the current preset mode."""
return self.device[ACTIVE_PRESET]
return self.device.get(ACTIVE_PRESET)

@plugwise_command
async def async_set_temperature(self, **kwargs: Any) -> None:
Expand All @@ -272,9 +271,6 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
@plugwise_command
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the hvac mode."""
if hvac_mode not in self.hvac_modes:
raise HomeAssistantError("Unsupported hvac_mode")

if hvac_mode == self.hvac_mode:
return

Expand All @@ -297,7 +293,7 @@ async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
await self.async_set_preset_mode(PRESET_AWAY) # pragma: no cover
if (
self._homekit_mode in [HVACMode.HEAT, HVACMode.HEAT_COOL]
and self.device[ACTIVE_PRESET] == PRESET_AWAY
and self.device.get(ACTIVE_PRESET) == PRESET_AWAY
): # pragma: no cover
await self.async_set_preset_mode(PRESET_HOME) # pragma: no cover

Expand Down
2 changes: 1 addition & 1 deletion custom_components/plugwise/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def available(self) -> bool:
# Upstream: Do not change the AVAILABLE line below: some Plugwise devices and zones
# Upstream: do not provide their availability-status!
self._dev_id in self.coordinator.data
and (AVAILABLE not in self.device or self.device[AVAILABLE] is True)
and (AVAILABLE not in self.device or self.device.get(AVAILABLE) is True)
and super().available
)

Expand Down
12 changes: 6 additions & 6 deletions custom_components/plugwise/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,23 @@ def __init__(
) -> None:
"""Initiate Plugwise Number."""
super().__init__(coordinator, device_id)
self.actuator = self.device[description.key] # Upstream
self.actuator = self.device.get(description.key) # Upstream
self.device_id = device_id
self.entity_description = description
self._attr_unique_id = f"{device_id}-{description.key}"
self._attr_mode = NumberMode.BOX
self._attr_native_max_value = self.device[description.key][UPPER_BOUND] # Upstream const
self._attr_native_min_value = self.device[description.key][LOWER_BOUND] # Upstream const
self._attr_native_max_value = self.device.get(description.key, {}).get(UPPER_BOUND, 100.0) # Upstream const
self._attr_native_min_value = self.device.get(description.key, {}).get(LOWER_BOUND, 0.0) # Upstream const

native_step = self.device[description.key][RESOLUTION] # Upstream const
native_step = self.device.get(description.key, {}).get(RESOLUTION, 0.5) # Upstream const
if description.key != TEMPERATURE_OFFSET: # Upstream const
native_step = max(native_step, 0.5)
self._attr_native_step = native_step

@property
def native_value(self) -> float:
def native_value(self) -> float | None:
"""Return the present setpoint value."""
return self.device[self.entity_description.key]["setpoint"]
return self.device.get(self.entity_description.key, {}).get("setpoint")

@plugwise_command
async def async_set_native_value(self, value: float) -> None:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/plugwise/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ def __init__(
@property
def current_option(self) -> str| None:
"""Return the selected entity option to represent the entity state."""
return self.device[self.entity_description.key]
return self.device.get(self.entity_description.key)

@property
def options(self) -> list[str]:
"""Return the available select-options."""
return self.device[self.entity_description.options_key]
return self.device.get(self.entity_description.options_key, [])

@plugwise_command
async def async_select_option(self, option: str) -> None:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/plugwise/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,6 @@ def __init__(
self._attr_unique_id = f"{device_id}-{description.key}"

@property
def native_value(self) -> int | float:
def native_value(self) -> int | float | None:
"""Return the value reported by the sensor."""
return self.device[SENSORS][self.entity_description.key] # Upstream consts
return self.device.get(SENSORS, {}).get(self.entity_description.key) # Upstream consts
4 changes: 2 additions & 2 deletions custom_components/plugwise/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ def __init__(
self._attr_unique_id = f"{device_id}-{description.key}"

@property
def is_on(self) -> bool:
def is_on(self) -> bool | None:
"""Return True if entity is on."""
return self.device[SWITCHES][self.entity_description.key] # Upstream const
return self.device.get(SWITCHES, {}).get(self.entity_description.key) # Upstream const

@plugwise_command
async def async_turn_on(self, **kwargs: Any) -> None:
Expand Down
Loading