Skip to content

Commit

Permalink
Add count down timers to sequence entity
Browse files Browse the repository at this point in the history
  • Loading branch information
rgc99 committed Jan 6, 2024
1 parent 976ab70 commit 4179de8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
3 changes: 3 additions & 0 deletions custom_components/irrigation_unlimited/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ def extra_state_attributes(self):
attr[ATTR_CURRENT_ZONE] = None
attr[ATTR_CURRENT_START] = dt.as_local(current.start_time)
attr[ATTR_CURRENT_DURATION] = str(current.total_time)
attr[ATTR_TIME_REMAINING] = str(current.time_remaining)
attr[ATTR_PERCENT_COMPLETE] = current.percent_complete
if current.schedule is not None:
attr[ATTR_CURRENT_SCHEDULE] = current.schedule.id1
attr[ATTR_CURRENT_NAME] = current.schedule.name
Expand All @@ -333,6 +335,7 @@ def extra_state_attributes(self):
else:
attr[ATTR_CURRENT_ZONE] = None
attr[ATTR_CURRENT_SCHEDULE] = None
attr[ATTR_PERCENT_COMPLETE] = 0
if (next_run := self._sequence.runs.next_run) is not None:
attr[ATTR_NEXT_START] = dt.as_local(next_run.start_time)
attr[ATTR_NEXT_DURATION] = str(next_run.total_time)
Expand Down
36 changes: 35 additions & 1 deletion custom_components/irrigation_unlimited/irrigation_unlimited.py
Original file line number Diff line number Diff line change
Expand Up @@ -2597,6 +2597,8 @@ def __init__(
self._last_pause: datetime = None
self._volume_trackers: list[CALLBACK_TYPE] = []
self._volume_stats: dict[IUSequenceZoneRun, dict[IUZone, Decimal]] = {}
self._remaining_time = timedelta(0)
self._percent_complete: int = 0

@property
def sequence(self) -> "IUSequence":
Expand Down Expand Up @@ -2648,6 +2650,16 @@ def runs(self) -> dict[IURun, IUSequenceZoneRun]:
"""Return the runs"""
return self._runs

@property
def time_remaining(self) -> timedelta:
"""Return the amount of time left to run"""
return self._remaining_time

@property
def percent_complete(self) -> float:
"""Return the percentage completed"""
return self._percent_complete

def is_manual(self) -> bool:
"""Check if this is a manual run"""
return self._schedule is None
Expand Down Expand Up @@ -2716,7 +2728,8 @@ def build(self, duration_factor: float) -> timedelta:
duration_max = max(duration_max, zone_run_time - next_run)
next_run += duration_max

return self._end_time - self._start_time
self._remaining_time = self._end_time - self._start_time
return self._remaining_time

def allocate_runs(self, stime: datetime, start_time: datetime) -> None:
"""Allocate runs"""
Expand Down Expand Up @@ -2987,6 +3000,19 @@ def remove_trackers() -> None:

return result

def update_time_remaining(self, stime: datetime) -> bool:
"""Update the count down timers"""
if self.running:
self._remaining_time = self._end_time - stime
total_duration = self._end_time - self._start_time
time_elapsed = stime - self._start_time
if total_duration > timedelta(0):
self._percent_complete = int((time_elapsed / total_duration) * 100)
else:
self._percent_complete = 0
return True
return False

def as_dict(self, include_expired=False) -> dict:
"""Return this sequence run as a dict"""
result = {}
Expand Down Expand Up @@ -3207,6 +3233,13 @@ def update_queue(self) -> IURQStatus:

return status

def update_sensor(self, stime: datetime) -> bool:
"""Update the count down timers"""
result = False
for run in self:
result |= run.update_time_remaining(stime)
return result

def as_list(self) -> list:
"""Return a list of runs"""
return [run.as_dict() for run in self]
Expand Down Expand Up @@ -3710,6 +3743,7 @@ def update_sensor(self, stime: datetime, do_on: bool) -> bool:

if self._sequence_sensor is not None:
if do_on is False:
updated |= self._run_queue.update_sensor(stime)
do_update = not self.is_on and self._sensor_update_required
else:
if self.is_on:
Expand Down
2 changes: 1 addition & 1 deletion tests/configs/test_sequence_entity.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
irrigation_unlimited:
refresh_interval: 2000
refresh_interval: 10
controllers:
- name: "Test controller 1"
zones:
Expand Down
50 changes: 50 additions & 0 deletions tests/test_sequence_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 06:05"),
"next_duration": "0:38:00",
"next_schedule": 1,
Expand All @@ -59,6 +60,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 06:10"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -77,6 +79,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:36:00",
"percent_complete": 5,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -91,6 +95,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"status": "off",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -110,6 +115,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:31:30",
"percent_complete": 17,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -127,6 +134,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:27:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:25:30",
"percent_complete": 5,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -146,6 +155,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:29:00",
"percent_complete": 23,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -163,6 +174,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:27:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:23:00",
"percent_complete": 14,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -182,6 +195,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:23:00",
"percent_complete": 39,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -199,6 +214,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:27:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:17:00",
"percent_complete": 37,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -218,6 +235,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:18:30",
"percent_complete": 51,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -235,6 +254,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:27:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:12:30",
"percent_complete": 53,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -254,6 +275,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:16:00",
"percent_complete": 57,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -271,6 +294,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:27:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:10:00",
"percent_complete": 62,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -290,6 +315,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:03:00",
"percent_complete": 92,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -304,6 +331,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"status": "off",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -320,6 +348,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"status": "off",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -334,6 +363,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"status": "off",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand Down Expand Up @@ -367,6 +397,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 06:05:00"),
"next_duration": "0:38:00",
"next_schedule": 1,
Expand All @@ -388,6 +419,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "%0.0",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_schedule": None,
"icon": "mdi:stop-circle-outline",
"friendly_name": "Seq 2",
Expand Down Expand Up @@ -422,6 +454,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 06:05:00"),
"next_duration": "0:38:00",
"next_schedule": 1,
Expand All @@ -439,6 +472,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_schedule": None,
"icon": "mdi:circle-off-outline",
},
Expand Down Expand Up @@ -475,6 +509,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_start": mk_local("2023-11-16 06:05:00"),
"next_duration": "0:38:00",
"next_schedule": 1,
Expand All @@ -496,6 +531,7 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"adjustment": "",
"current_zone": None,
"current_schedule": None,
"percent_complete": 0,
"next_schedule": None,
"icon": "mdi:timer-outline",
"friendly_name": "Seq 2",
Expand All @@ -522,6 +558,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:29:00",
"percent_complete": 23,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -540,6 +578,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:27:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:23:00",
"percent_complete": 14,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -565,6 +605,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:17:00",
"percent_complete": 55,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -583,6 +625,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:39:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:23:00",
"percent_complete": 41,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand Down Expand Up @@ -611,6 +655,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:38:00",
"current_schedule": 1,
"current_name": "Dawn",
"time_remaining": "0:30:00",
"percent_complete": 21,
"next_start": mk_local("2023-11-16 17:05:00"),
"next_duration": "0:38:00",
"next_schedule": 2,
Expand All @@ -629,6 +675,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:25:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:22:00",
"percent_complete": 12,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand All @@ -648,6 +696,8 @@ async def test_sequence_run(hass: ha.HomeAssistant, skip_dependencies, skip_hist
"current_duration": "0:25:00",
"current_schedule": 1,
"current_name": "Morning",
"time_remaining": "0:21:00",
"percent_complete": 16,
"next_start": mk_local("2023-11-17 06:10:00"),
"next_duration": "0:27:00",
"next_schedule": 1,
Expand Down

0 comments on commit 4179de8

Please sign in to comment.