Skip to content

Commit

Permalink
Add set_profile service for Vallox integration
Browse files Browse the repository at this point in the history
  • Loading branch information
treetip committed Jun 23, 2024
1 parent f0d5640 commit 34cbb9d
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 1 deletion.
28 changes: 28 additions & 0 deletions homeassistant/components/vallox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class ServiceMethodDetails(NamedTuple):
SERVICE_SET_PROFILE_FAN_SPEED_HOME = "set_profile_fan_speed_home"
SERVICE_SET_PROFILE_FAN_SPEED_AWAY = "set_profile_fan_speed_away"
SERVICE_SET_PROFILE_FAN_SPEED_BOOST = "set_profile_fan_speed_boost"
SERVICE_SET_PROFILE = "set_profile"

SERVICE_TO_METHOD = {
SERVICE_SET_PROFILE_FAN_SPEED_HOME: ServiceMethodDetails(
Expand All @@ -86,6 +87,19 @@ class ServiceMethodDetails(NamedTuple):
method="async_set_profile_fan_speed_boost",
schema=SERVICE_SCHEMA_SET_PROFILE_FAN_SPEED,
),
SERVICE_SET_PROFILE: ServiceMethodDetails(
method="async_set_profile",
schema=vol.Schema(
{
vol.Required("profile"): vol.All(
vol.Coerce(int), vol.Clamp(min=1, max=5)
),
vol.Optional("duration"): vol.All(
vol.Coerce(int), vol.Clamp(min=1, max=65535)
),
}
),
),
}


Expand Down Expand Up @@ -183,6 +197,20 @@ async def async_set_profile_fan_speed_boost(
return False
return True

async def async_set_profile(
self, profile: int, duration: int | None = None
) -> bool:
"""Activate profile for given duration."""
_LOGGER.debug("Activating profile %s for %d min", profile, duration)
try:
await self._client.set_profile(Profile(profile), duration)
except ValloxApiException as err:
_LOGGER.error(
"Error setting profile %d for duration %d: %s", profile, duration, err
)
return False
return True

async def async_handle(self, call: ServiceCall) -> None:
"""Dispatch a service call."""
service_details = SERVICE_TO_METHOD.get(call.service)
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/vallox/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"services": {
"set_profile_fan_speed_home": "mdi:home",
"set_profile_fan_speed_away": "mdi:walk",
"set_profile_fan_speed_boost": "mdi:speedometer"
"set_profile_fan_speed_boost": "mdi:speedometer",
"set_profile": "mdi:fan"
}
}
33 changes: 33 additions & 0 deletions homeassistant/components/vallox/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from dataclasses import dataclass
from datetime import datetime, time

from vallox_websocket_api import Profile

from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
Expand All @@ -18,6 +20,7 @@
REVOLUTIONS_PER_MINUTE,
EntityCategory,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
Expand Down Expand Up @@ -127,6 +130,27 @@ def native_value(self) -> StateType:
return VALLOX_CELL_STATE_TO_STR.get(super_native_value)


class ValloxProfileDurationSensor(ValloxSensorEntity):
"""Child class for profile duration reporting."""

@property
def native_value(self) -> StateType:
"""Return the value reported by the sensor."""
minutes_left: int | float | None = 0

if Profile.EXTRA is self.coordinator.data.profile:
minutes_left = self.coordinator.data.get("A_CYC_EXTRA_TIMER", 0)
elif Profile.FIREPLACE is self.coordinator.data.profile:
minutes_left = self.coordinator.data.get("A_CYC_FIREPLACE_TIMER", 0)
elif Profile.BOOST is self.coordinator.data.profile:
minutes_left = self.coordinator.data.get("A_CYC_BOOST_TIMER", 0)

if not isinstance(minutes_left, int):
return 0

return minutes_left


@dataclass(frozen=True)
class ValloxSensorEntityDescription(SensorEntityDescription):
"""Describes Vallox sensor entity."""
Expand Down Expand Up @@ -253,6 +277,15 @@ class ValloxSensorEntityDescription(SensorEntityDescription):
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
entity_registry_enabled_default=False,
),
ValloxSensorEntityDescription(
key="profile_duration",
translation_key="profile_duration",
device_class=SensorDeviceClass.DURATION,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
entity_type=ValloxProfileDurationSensor,
entity_registry_enabled_default=False,
),
)


Expand Down
25 changes: 25 additions & 0 deletions homeassistant/components/vallox/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,28 @@ set_profile_fan_speed_boost:
min: 0
max: 100
unit_of_measurement: "%"

set_profile:
fields:
profile:
required: true
selector:
select:
options:
- label: "Home"
value: "1"
- label: "Away"
value: "2"
- label: "Boost"
value: "3"
- label: "Fireplace"
value: "4"
- label: "Extra"
value: "5"
duration:
required: false
selector:
number:
min: 1
max: 65535
unit_of_measurement: "min"
17 changes: 17 additions & 0 deletions homeassistant/components/vallox/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
},
"efficiency": {
"name": "Efficiency"
},
"profile_duration": {
"name": "Profile duration"
}
},
"switch": {
Expand Down Expand Up @@ -130,6 +133,20 @@
"description": "[%key:component::vallox::services::set_profile_fan_speed_home::fields::fan_speed::description%]"
}
}
},
"set_profile": {
"name": "Activate profile for duration",
"description": "Activate a profile and optionally set duration.",
"fields": {
"profile": {
"name": "Profile",
"description": "Profile to activate"
},
"duration": {
"name": "Duration",
"description": "Activation duration, if omitted device uses stored duration. Duration of 65535 activates profile without timeout. Duration only applies to Boost, Fireplace and Extra profiles."
}
}
}
}
}

0 comments on commit 34cbb9d

Please sign in to comment.