Skip to content

Commit

Permalink
Added end_time calculation for ambisense time program, added calendar…
Browse files Browse the repository at this point in the history
…, deprecated set_zone_time_program in favor of set_time_program on climate entities
  • Loading branch information
signalkraft committed Mar 25, 2024
1 parent 8362142 commit 344c75e
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 50 deletions.
46 changes: 46 additions & 0 deletions custom_components/mypyllant/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
DHWTimeProgramDay,
DHWTimeProgram,
ZoneTimeProgram,
RoomTimeProgramDay,
RoomTimeProgram,
)
from myPyllant.enums import ZoneTimeProgramType

Expand All @@ -31,6 +33,7 @@
ZoneCoordinatorEntity,
DomesticHotWaterCoordinatorEntity,
EntityList,
AmbisenseCoordinatorEntity,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -63,6 +66,10 @@ async def async_setup_entry(
index, dhw_index, coordinator
)
)
for room in system.ambisense_rooms:
sensors.append(
lambda: AmbisenseCalendar(index, room.room_index, coordinator)
)
async_add_entities(sensors)


Expand Down Expand Up @@ -362,3 +369,42 @@ async def update_time_program(self):
self.domestic_hot_water, self.time_program
)
await self.coordinator.async_request_refresh_delayed()


class AmbisenseCalendar(BaseCalendarEntity, AmbisenseCoordinatorEntity):
_attr_icon = "mdi:thermometer-auto"
_has_setpoint = True

@property
def time_program(self) -> RoomTimeProgram:
return self.room.time_program # type: ignore

@property
def name(self) -> str:
return f"{self.name_prefix} Schedule"

def _get_calendar_id_prefix(self):
return f"room_{self.room.room_index}"

def build_event(
self,
time_program_day: RoomTimeProgramDay,
start: datetime.datetime,
end: datetime.datetime,
):
summary = f"{time_program_day.temperature_setpoint}°C on {self.name}"
return CalendarEvent(
summary=summary,
start=start,
end=end,
description="You can change the start time, end time, weekdays, or the temperature in the Summary.",
uid=self._get_uid(time_program_day, start),
rrule=self._get_rrule(time_program_day),
recurrence_id=self._get_recurrence_id(time_program_day),
)

async def update_time_program(self):
await self.coordinator.api.set_ambisense_room_time_program(
self.room, self.time_program
)
await self.coordinator.async_request_refresh_delayed()
41 changes: 8 additions & 33 deletions custom_components/mypyllant/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
System,
Zone,
ZoneTimeProgram,
AmbisenseRoom,
RoomTimeProgram,
)
from myPyllant.enums import (
Expand All @@ -49,7 +48,11 @@
AmbisenseRoomOperationMode,
)

from custom_components.mypyllant.utils import shorten_zone_name, EntityList
from custom_components.mypyllant.utils import (
shorten_zone_name,
EntityList,
AmbisenseCoordinatorEntity,
)

from . import SystemCoordinator
from .const import (
Expand Down Expand Up @@ -696,7 +699,7 @@ async def async_set_preset_mode(self, preset_mode):
await self.coordinator.async_request_refresh_delayed()


class AmbisenseClimate(CoordinatorEntity, ClimateEntity):
class AmbisenseClimate(AmbisenseCoordinatorEntity, ClimateEntity):
"""Climate for an ambisense room."""

coordinator: SystemCoordinator
Expand All @@ -715,9 +718,7 @@ def __init__(
config: ConfigEntry,
data: dict,
) -> None:
super().__init__(coordinator)
self.system_index = system_index
self.room_index = room_index
super().__init__(system_index, room_index, coordinator)
self.config = config
self.data = data
self.data["last_active_hvac_mode"] = (
Expand Down Expand Up @@ -749,35 +750,9 @@ def default_quick_veto_duration(self):
* 60 # Ambisense rooms expect minutes, but OPTION_DEFAULT_QUICK_VETO_DURATION is in hours
)

@property
def system(self) -> System:
return self.coordinator.data[self.system_index]

@property
def room(self) -> AmbisenseRoom:
return [
r for r in self.system.ambisense_rooms if r.room_index == self.room_index
][0]

@property
def id_infix(self) -> str:
return f"{self.system.id}_room_{self.room_index}"

@property
def device_info(self) -> DeviceInfo:
return DeviceInfo(
identifiers={(DOMAIN, self.id_infix)},
name=self.name,
manufacturer=self.system.brand_name,
)

@property
def unique_id(self) -> str:
return f"{DOMAIN}_{self.id_infix}_climate"

@property
def name(self) -> str:
return f"{self.system.home.home_name or self.system.home.nomenclature} {self.room.name}"
return self.name_prefix

@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
Expand Down
2 changes: 1 addition & 1 deletion custom_components/mypyllant/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/signalkraft/mypyllant-component/issues",
"requirements": [
"myPyllant==0.8.9"
"myPyllant==0.8.10"
],
"version": "v0.7.3"
}
8 changes: 4 additions & 4 deletions custom_components/mypyllant/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ set_time_program:
fields:
program_type:
name: Type
description: Type of the time program (heating, cooling)
description: Type of the time program (heating, cooling). Ambisense rooms ignore this field
example: heating
selector:
select:
Expand All @@ -128,7 +128,7 @@ set_time_program:
- "cooling"
time_program:
name: Time Program
description: A dictionary of days with a list of setpoints, start_time, and end_time (in minutes since midnight)
description: A dictionary of days with a list of setpoints, start_time, and end_time (in minutes since midnight). Ambisense rooms don't support end_time
example: >
monday:
- start_time: 420
Expand Down Expand Up @@ -160,8 +160,8 @@ set_time_program:
setpoint: 20
set_zone_time_program:
name: Set Zone Time Program
description: Updates the time program for a zone
name: Set Zone Time Program (deprecated)
description: Deprecated, use "Set Time Program" instead
target:
entity:
integration: mypyllant
Expand Down
46 changes: 45 additions & 1 deletion custom_components/mypyllant/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

if typing.TYPE_CHECKING:
from custom_components.mypyllant.coordinator import SystemCoordinator
from myPyllant.models import System, DomesticHotWater, Zone
from myPyllant.models import System, DomesticHotWater, Zone, AmbisenseRoom

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -258,3 +258,47 @@ def device_info(self):
@property
def available(self) -> bool | None:
return self.zone.is_active


class AmbisenseCoordinatorEntity(CoordinatorEntity):
coordinator: SystemCoordinator

def __init__(
self,
system_index: int,
room_index: int,
coordinator: SystemCoordinator,
) -> None:
super().__init__(coordinator)
self.system_index = system_index
self.room_index = room_index

@property
def system(self) -> System:
return self.coordinator.data[self.system_index]

@property
def room(self) -> AmbisenseRoom:
return [
r for r in self.system.ambisense_rooms if r.room_index == self.room_index
][0]

@property
def name_prefix(self) -> str:
return f"{self.system.home.home_name or self.system.home.nomenclature} {self.room.name}"

@property
def id_infix(self) -> str:
return f"{self.system.id}_room_{self.room_index}"

@property
def device_info(self):
return DeviceInfo(
identifiers={(DOMAIN, self.id_infix)},
name=self.name_prefix,
manufacturer=self.system.brand_name,
)

@property
def unique_id(self) -> str:
return f"{DOMAIN}_{self.id_infix}_climate"
2 changes: 1 addition & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ types-PyYAML~=6.0.12.12

# Need specific versions
pytest-homeassistant-custom-component==0.13.101
myPyllant==0.8.9
myPyllant==0.8.10

# Versions handled by pytest-homeassistant-custom-component
freezegun
Expand Down
75 changes: 66 additions & 9 deletions docs/docs/2-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ There are custom services for almost every functionality of the myVAILLANT app:
| [Cancel quick veto](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.cancel_quick_veto) | Cancels quick veto temperature and returns to normal schedule / manual setpoint | climate | |
| [Set holiday](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_holiday) | Set holiday / away mode with start / end or duration | climate | Start Date, End Date, Duration, Setpoint |
| [Cancel Holiday](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.cancel_holiday) | Cancel holiday / away mode | climate | |
| [Set Zone Time Program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_zone_time_program) | Updates the time program for a zone | climate | Type, Time Program |
| [Set Time Program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_time_program) | Updates the time program for a zone or room | climate | Type, Time Program |
| [Set Zone Time Program (deprecated)](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_zone_time_program) | Deprecated, use "Set Time Program" instead | climate | Type, Time Program |
| [Set Zone Operating mode](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_zone_operating_mode) | Same as setting HVAC mode, but allows setting heating or cooling | climate | Operating Mode, Operating Type |
| [Set Water Heater Time Program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_dhw_time_program) | Updates the time program for a water heater | water_heater | Time Program |
| [Set Water Heater Circulation Time Program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_dhw_circulation_time_program) | Updates the time program for the circulation pump of a water heater | water_heater | Time Program |
Expand Down Expand Up @@ -46,8 +47,8 @@ interactive UI.

The following services can be used to set time programs:

* [mypyllant.set_zone_time_program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_zone_time_program)
for climate zone temperature schedule (requires an additional `program_type`)
* [mypyllant.set_time_program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_time_program)
for climate temperature schedule (requires an additional `program_type` for zone climate)
* [mypyllant.set_dhw_time_program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_dhw_time_program)
for water heater temperature schedule
* [mypyllant.set_dhw_circulation_time_program](https://my.home-assistant.io/redirect/developer_call_service/?service=mypyllant.set_dhw_circulation_time_program)
Expand All @@ -65,10 +66,10 @@ You can also [use the calendar UI](2-entities.md#calendar-entities) to change ti

You can delete all time windows on a day by sending an empty list, for example `monday: []`.

=== "Climate"
=== "Zone Climate"

```yaml
service: mypyllant.set_zone_time_program
service: mypyllant.set_time_program
data:
program_type: heating
time_program:
Expand Down Expand Up @@ -100,11 +101,69 @@ You can also [use the calendar UI](2-entities.md#calendar-entities) to change ti
- start_time: 420
end_time: 1290
setpoint: 20
type: heating
target:
entity_id: climate.home_zone_1_circuit_0_climate
```

=== "Ambisense Climate"

```yaml
service: mypyllant.set_time_program
data:
time_program:
monday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
tuesday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
wednesday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
thursday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
friday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
saturday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
sunday:
- startTime: 0
temperatureSetpoint: 20
- startTime: 360
temperatureSetpoint: 19
- startTime: 1260
temperatureSetpoint: 20
target:
entity_id: climate.home_room_1_climate
```

=== "Water Heater"

```yaml
Expand Down Expand Up @@ -132,7 +191,6 @@ You can also [use the calendar UI](2-entities.md#calendar-entities) to change ti
sunday:
- start_time: 420
end_time: 1290
type: heating
target:
entity_id: water_heater.home_domestic_hot_water_0
```
Expand Down Expand Up @@ -164,7 +222,6 @@ You can also [use the calendar UI](2-entities.md#calendar-entities) to change ti
sunday:
- start_time: 420
end_time: 1290
type: heating
target:
entity_id: water_heater.home_domestic_hot_water_0
```
```
Loading

0 comments on commit 344c75e

Please sign in to comment.