Skip to content

Commit

Permalink
Implement sequence_id
Browse files Browse the repository at this point in the history
  • Loading branch information
rgc99 committed Sep 9, 2024
1 parent c720a66 commit d60b2f9
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 20 deletions.
51 changes: 41 additions & 10 deletions custom_components/irrigation_unlimited/irrigation_unlimited.py
Original file line number Diff line number Diff line change
Expand Up @@ -3590,6 +3590,7 @@ def __init__(
self._coordinator = coordinator
self._controller = controller
# Config parameters
self._sequence_id: str = None
self._name: str = None
self._delay: timedelta = None
self._duration: timedelta = None
Expand Down Expand Up @@ -3673,6 +3674,11 @@ def zones(self) -> list[IUSequenceZone]:
"""Return the list of sequence zones"""
return self._zones

@property
def sequence_id(self) -> str:
"""Return the id of the sequence"""
return self._sequence_id

@property
def name(self) -> str:
"""Return the friendly name of this sequence"""
Expand Down Expand Up @@ -3968,6 +3974,7 @@ def zone_list(self) -> Iterator[list[IUZone]]:
def load(self, config: OrderedDict) -> "IUSequence":
"""Load sequence data from the configuration"""
self.clear()
self._sequence_id = config.get(CONF_SEQUENCE_ID, str(self.index + 1))
self._name = config.get(CONF_NAME, f"Run {self.index + 1}")
self._delay = wash_td(config.get(CONF_DELAY))
self._duration = wash_td(config.get(CONF_DURATION))
Expand Down Expand Up @@ -4804,17 +4811,22 @@ def check_run(self, stime: datetime) -> bool:

def check_links(self) -> bool:
"""Check inter object links"""

result = True
zone_ids = set()
sequence_ids = set()
for zone in self._zones:
if zone.zone_id in zone_ids:
self._coordinator.logger.log_duplicate_id(self, zone, None)
self._coordinator.logger.log_duplicate_id(self, zone, None, None)
result = False
else:
zone_ids.add(zone.zone_id)

for sequence in self._sequences:
if sequence.sequence_id in sequence_ids:
self._coordinator.logger.log_duplicate_id(self, None, sequence, None)
result = False
else:
sequence_ids.add(sequence.sequence_id)
for sequence_zone in sequence.zones:
for zone_id in sequence_zone.zone_ids:
if zone_id not in zone_ids:
Expand Down Expand Up @@ -5782,12 +5794,14 @@ def log_duplicate_id(
self,
controller: IUController,
zone: IUZone,
sequence: IUSequence,
schedule: IUSchedule,
level=WARNING,
) -> None:
"""Warn a controller/zone/schedule has a duplicate id"""
idl = IUBase.idl([controller, zone, schedule], "0", 1)
if not zone and not schedule:
# pylint: disable=too-many-arguments
idl = IUBase.idl([controller, zone, sequence, schedule], "0", 1)
if not zone and not sequence and not schedule:
self._format(
level,
"DUPLICATE_ID",
Expand Down Expand Up @@ -5817,18 +5831,31 @@ def log_duplicate_id(
f"controller_id: {controller.controller_id}, "
f"zone: {idl[1]}, "
f"zone_id: {zone.zone_id if zone else ''}, "
f"schedule: {idl[2]}, "
f"schedule: {idl[3]}, "
f"schedule_id: {schedule.schedule_id if schedule else ''}",
)
else: # not zone and schedule
elif sequence and not schedule:
self._format(
level,
"DUPLICATE_ID",
None,
f"Duplicate Sequence ID: "
f"controller: {idl[0]}, "
f"controller_id: {controller.controller_id}, "
f"sequence: {idl[2]}, "
f"sequence_id: {sequence.sequence_id if sequence else ''}",
)
elif sequence and schedule:
self._format(
level,
"DUPLICATE_ID",
None,
f"Duplicate Schedule ID (sequence): "
f"controller: {idl[0]}, "
f"controller_id: {controller.controller_id}, "
f"schedule: {idl[2]}, "
f"sequence: {idl[2]}, "
f"sequence_id: {sequence.sequence_id if sequence else ''}, "
f"schedule: {idl[3]}, "
f"schedule_id: {schedule.schedule_id if schedule else ''}",
)

Expand Down Expand Up @@ -6291,7 +6318,7 @@ def check_links(self) -> bool:
controller_ids = set()
for controller in self._controllers:
if controller.controller_id in controller_ids:
self._logger.log_duplicate_id(controller, None, None)
self._logger.log_duplicate_id(controller, None, None, None)
result = False
else:
controller_ids.add(controller.controller_id)
Expand All @@ -6304,15 +6331,19 @@ def check_links(self) -> bool:
for schedule in zone.schedules:
if schedule.schedule_id is not None:
if schedule.schedule_id in schedule_ids:
self._logger.log_duplicate_id(controller, zone, schedule)
self._logger.log_duplicate_id(
controller, zone, None, schedule
)
result = False
else:
schedule_ids.add(schedule.schedule_id)
for sequence in controller.sequences:
for schedule in sequence.schedules:
if schedule.schedule_id is not None:
if schedule.schedule_id in schedule_ids:
self._logger.log_duplicate_id(controller, None, schedule)
self._logger.log_duplicate_id(
controller, None, sequence, schedule
)
result = False
else:
schedule_ids.add(schedule.schedule_id)
Expand Down
1 change: 1 addition & 0 deletions custom_components/irrigation_unlimited/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ def _parse_dd_mmm(value: str) -> date | None:
cv.ensure_list, [SEQUENCE_SCHEDULE_SCHEMA]
),
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_SEQUENCE_ID): cv.matches_regex(IU_ID),
vol.Optional(CONF_DELAY): cv.time_period,
vol.Optional(CONF_DURATION): cv.positive_time_period,
vol.Optional(CONF_REPEAT): cv.positive_int,
Expand Down
5 changes: 5 additions & 0 deletions tests/configs/test_ids.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ irrigation_unlimited:
zone_id: "zone_3" # Conflicts with Zone 3
sequences:
- name: "Sequence 1"
sequence_id: "sequence_1"
schedules:
- name: Never
schedule_id: "schedule_2" # Conflicts with Zone 2, Schedule 1
Expand All @@ -43,6 +44,10 @@ irrigation_unlimited:
zones:
- zone_id: 1
- zone_id: [1, "no_zone"] # Orphaned
- name: "Sequence 2"
sequence_id: "sequence_1" # Conflicts with Sequence 1
zones:
- zone_id: 1
- name: Controller 2
controller_id: "1" # Conflicts with controller 1
zones:
Expand Down
15 changes: 5 additions & 10 deletions tests/test_link_ids.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""irrigation_unlimited test for logging"""

# pylint: disable=unused-import
from unittest.mock import patch
import homeassistant.core as ha
Expand All @@ -17,22 +18,16 @@ async def test_link_ids(hass: ha.HomeAssistant, skip_dependencies, skip_history)
with patch.object(IULogger, "log_duplicate_id") as mock_duplicate:
with patch.object(IULogger, "log_orphan_id") as mock_orphan:
async with IUExam(hass, "test_ids.yaml"):
assert mock_duplicate.call_count == 6
assert mock_duplicate.call_count == 7
assert mock_orphan.call_count == 1

with patch.object(IULogger, "_format") as mock:
async with IUExam(hass, "test_ids.yaml"):
assert (
sum(
[
1
for call in mock.call_args_list
if call.args[1] == "DUPLICATE_ID"
]
)
== 6
sum(1 for call in mock.call_args_list if call.args[1] == "DUPLICATE_ID")
== 7
)
assert (
sum([1 for call in mock.call_args_list if call.args[1] == "ORPHAN_ID"])
sum(1 for call in mock.call_args_list if call.args[1] == "ORPHAN_ID")
== 1
)

0 comments on commit d60b2f9

Please sign in to comment.