diff --git a/custom_components/irrigation_unlimited/binary_sensor.py b/custom_components/irrigation_unlimited/binary_sensor.py index 3d46f08..3bc73ed 100644 --- a/custom_components/irrigation_unlimited/binary_sensor.py +++ b/custom_components/irrigation_unlimited/binary_sensor.py @@ -4,6 +4,7 @@ import homeassistant.util.dt as dt from datetime import datetime, timedelta from homeassistant.components import history +import json from homeassistant.const import ( STATE_ON, @@ -153,7 +154,6 @@ def device_state_attributes(self): attr["next_duration"] = str(next.duration) else: attr["next_schedule"] = RES_NONE - return attr @@ -235,5 +235,7 @@ def device_state_attributes(self): attr["today_total"] = round( today_on_duration(self.hass, self.entity_id).total_seconds() / 60, 1 ) - + if self._zone.show_config: + attr["configuration"] = json.dumps(self._zone.as_dict(), default=str) + attr["timeline"] = json.dumps(self._zone.runs.as_list(), default=str) return attr diff --git a/custom_components/irrigation_unlimited/irrigation_unlimited.py b/custom_components/irrigation_unlimited/irrigation_unlimited.py index 24bbef9..df4af71 100644 --- a/custom_components/irrigation_unlimited/irrigation_unlimited.py +++ b/custom_components/irrigation_unlimited/irrigation_unlimited.py @@ -32,6 +32,7 @@ CONF_INCREASE, CONF_PERCENTAGE, CONF_RESET, + CONF_SHOW_CONFIG, DEFAULT_GRANULATITY, DEFAULT_TEST_SPEED, CONF_DURATION, @@ -293,6 +294,24 @@ def load(self, config: OrderedDict): return self + def as_dict(self) -> OrderedDict: + dict = OrderedDict() + + dict[CONF_TIME] = self._time + dict[CONF_DURATION] = self._duration + dict[CONF_NAME] = self._name + if self._weekdays is not None: + dict[CONF_WEEKDAY] = [] + for item in self._weekdays: + dict[CONF_WEEKDAY].append(WEEKDAYS[item]) + if self._months is not None: + dict[CONF_MONTH] = [] + for item in self._months: + dict[CONF_MONTH].append(MONTHS[item - 1]) + if self._days is not None: + dict[CONF_DAY] = self._days + return dict + def get_next_run(self, atime: datetime) -> datetime: """ Determine the next start time. Date processing in this routine @@ -456,6 +475,12 @@ def update_time_remaining(self, time: datetime) -> bool: else: return False + def as_dict(self) -> OrderedDict: + dict = OrderedDict() + dict["start"] = self._start_time + dict["end"] = self._end_time + return dict + class IURunQueue(list): MAX_DEPTH: int = 6 @@ -611,6 +636,12 @@ def update_sensor(self, time) -> bool: else: return False + def as_list(self) -> list: + l = [] + for run in self: + l.append(run.as_dict()) + return l + class IUScheduleQueue(IURunQueue): """Class to hold the upcoming schedules to run""" @@ -708,6 +739,7 @@ def __init__( self._is_enabled: bool = True self._name: str = None self._switch_entity_id: str = None + self._show_config: bool = False # Private variables self._initialised: bool = False self._schedules: list(IUSchedule) = [] @@ -742,7 +774,10 @@ def adjustment(self) -> IUAdjustment: @property def name(self) -> str: - return self._name + if self._name is not None: + return self._name + else: + return f"Zone {self._zone_index + 1}" @property def is_on(self) -> bool: @@ -779,6 +814,10 @@ def zone_sensor(self, value: Entity): def status(self) -> str: return self._status() + @property + def show_config(self) -> bool: + return self._show_config + def _is_setup(self) -> bool: """Check if this object is setup""" if not self._initialised: @@ -846,12 +885,25 @@ def load(self, config: OrderedDict): self.clear() self._is_enabled = config.get(CONF_ENABLED, True) - self._name = config.get(CONF_NAME, f"Zone {self.zone_index + 1}") + self._name = config.get(CONF_NAME, None) self._switch_entity_id = config.get(CONF_ENTITY_ID) self._adjustment.load(config) + self._show_config = config.get(CONF_SHOW_CONFIG, False) self._dirty = True return self + def as_dict(self) -> OrderedDict: + dict = OrderedDict() + dict[CONF_ENABLED] = self._is_enabled + if self._name is not None: + dict[CONF_NAME] = self._name + if self._switch_entity_id is not None: + dict[CONF_ENTITY_ID] = self._switch_entity_id + dict[CONF_SCHEDULES] = [] + for schedule in self._schedules: + dict[CONF_SCHEDULES].append(schedule.as_dict()) + return dict + def muster(self, time: datetime, force: bool) -> int: """Calculate run times for this zone""" status: int = 0