diff --git a/custom_components/rinnaitouch/binary_sensor.py b/custom_components/rinnaitouch/binary_sensor.py index c0e0bf9..c0d4f74 100644 --- a/custom_components/rinnaitouch/binary_sensor.py +++ b/custom_components/rinnaitouch/binary_sensor.py @@ -36,6 +36,7 @@ async def async_setup_entry( RinnaiPumpOperatingBinarySensorEntity(ip_address, name), RinnaiCoolerBusyBinarySensorEntity(ip_address, name), RinnaiFanOperatingBinarySensorEntity(ip_address, name), + RinnaiTimeSettingSensorEntity(ip_address, name), ] ) if entry.data.get(CONF_ZONE_A): @@ -321,6 +322,38 @@ def available(self): return True +class RinnaiTimeSettingSensorEntity(RinnaiBinarySensorEntity): + """Binary sensor for signaling the system is in time setting mode.""" + + def __init__(self, ip_address, name): + super().__init__(ip_address, name) + self._attr_name = name + " Time Setting Sensor" + self._attr_status_attr = "is_timesetting" + + @property + def icon(self): + """Return the icon to use in the frontend for this device.""" + if self.is_on: + return "mdi:clock-alert-outline" + return "mdi:clock-outline" + + @property + def is_on(self): + """If the sensor is currently on or off.""" + state: RinnaiSystemStatus = self._system.get_stored_status() + if self.available: + return state.is_timesetting + return False + + @property + def available(self): + """If the sensor is currently available.""" + state: RinnaiSystemStatus = self._system.get_stored_status() + if not state.has_fault: + return True + return False + + class RinnaiZoneStateBinarySensorEntity(RinnaiBinarySensorEntity): """Binary sensor for preheating on/off during heater operation.""" diff --git a/custom_components/rinnaitouch/climate.py b/custom_components/rinnaitouch/climate.py index a79daf6..d67e452 100644 --- a/custom_components/rinnaitouch/climate.py +++ b/custom_components/rinnaitouch/climate.py @@ -20,7 +20,7 @@ from __future__ import annotations import asyncio -from datetime import timedelta +from datetime import timedelta, datetime import logging @@ -43,6 +43,8 @@ ) from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.entity_registry import async_entries_for_device +from homeassistant.helpers import config_validation as cv, entity_platform +import voluptuous as vol from .const import ( PRESET_AUTO, @@ -62,6 +64,7 @@ CONF_ZONE_D, CONF_ZONE_COMMON, DEFAULT_NAME, + SET_DATETIME, ) SUPPORT_FLAGS_MAIN = ( @@ -75,6 +78,8 @@ SCAN_INTERVAL = timedelta(seconds=5) +SERVICE_SET_TIME = "rinnai_set_time" + async def async_setup_entry(hass, entry, async_add_entities): """Set up climate entities.""" @@ -109,6 +114,14 @@ async def async_setup_entry(hass, entry, async_add_entities): async_add_entities( [RinnaiTouchZone(hass, ip_address, name, "U", temperature_entity_common)] ) + platform = entity_platform.async_get_current_platform() + platform.async_register_entity_service( + SERVICE_SET_TIME, + { + vol.Optional(SET_DATETIME): cv.datetime, + }, + "set_system_time" + ) return True @@ -429,6 +442,10 @@ def set_swing_mode(self, swing_mode): """Set new target swing operation.""" return False + async def set_system_time(self, set_datetime: datetime = None): + """Set the system time.""" + await self._system.set_system_time(set_datetime) + async def async_set_temperature(self, **kwargs): """Set new target temperature.""" if kwargs.get(ATTR_TEMPERATURE) is not None: diff --git a/custom_components/rinnaitouch/const.py b/custom_components/rinnaitouch/const.py index c492c4f..c9f4da3 100644 --- a/custom_components/rinnaitouch/const.py +++ b/custom_components/rinnaitouch/const.py @@ -23,3 +23,4 @@ CONF_ZONE_C = "Zone C" CONF_ZONE_D = "Zone D" CONF_ZONE_COMMON = "Common Zone" +SET_DATETIME = "set_datetime" diff --git a/custom_components/rinnaitouch/manifest.json b/custom_components/rinnaitouch/manifest.json index c3a3b63..aacc903 100644 --- a/custom_components/rinnaitouch/manifest.json +++ b/custom_components/rinnaitouch/manifest.json @@ -4,8 +4,8 @@ "documentation": "https://github.com/funtastix/rinnaitouch", "issue_tracker": "https://github.com/funtastix/rinnaitouch/issues", "codeowners": [ "@funtastix" ], - "requirements": [ "pyrinnaitouch>=0.12.13" ], + "requirements": [ "pyrinnaitouch>=0.12.14" ], "config_flow": true, - "version": "0.12.13", + "version": "0.12.14", "iot_class": "local_push" } diff --git a/custom_components/rinnaitouch/requirements.txt b/custom_components/rinnaitouch/requirements.txt index b1ba638..829e3e9 100644 --- a/custom_components/rinnaitouch/requirements.txt +++ b/custom_components/rinnaitouch/requirements.txt @@ -1,3 +1,3 @@ async_timeout>=3.0.1 asyncio>=3.4.3 -pyrinnaitouch>=0.12.13 \ No newline at end of file +pyrinnaitouch>=0.12.14 \ No newline at end of file diff --git a/custom_components/rinnaitouch/services.yaml b/custom_components/rinnaitouch/services.yaml new file mode 100644 index 0000000..6a992e2 --- /dev/null +++ b/custom_components/rinnaitouch/services.yaml @@ -0,0 +1,29 @@ +# Service ID +rinnai_set_time: + # If the service accepts entity IDs, target allows the user to specify entities by + # entity, device, or area. If `target` is specified, `entity_id` should not be + # defined in the `fields` map. By default it shows only targets matching entities + # from the same domain as the service, but if further customization is required, + # target supports the entity, device, and area selectors + # (https://www.home-assistant.io/docs/blueprint/selectors/). Entity selector + # parameters will automatically be applied to device and area, and device selector + # parameters will automatically be applied to area. + target: + entity: + domain: climate + integration: rinnaitouch + # Different fields that your service accepts + fields: + # Key of the field + set_datetime: + # Whether or not field is required (default = false) + required: false + # Advanced fields are only shown when the advanced mode is enabled for the user + # (default = false) + advanced: false + # Example value that can be passed for this field + example: "2023-01-01T12:00:00+0000" + # Selector (https://www.home-assistant.io/docs/blueprint/selectors/) to control + # the input UI for this field + selector: + datetime: \ No newline at end of file