Skip to content

Commit c553130

Browse files
author
Vaclav
committed
blank frequency, blueprints
1 parent 3d70c8f commit c553130

File tree

6 files changed

+145
-12
lines changed

6 files changed

+145
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ action:
357357
sequence:
358358
- condition: template
359359
value_template: >-
360-
{%- set collection_date = as_datetime(trigger.event.data.collection_dates[repeat.index]) %}
360+
{%- set collection_date = as_datetime(trigger.event.data.collection_dates[repeat.index-1]) %}
361361
{%- set ns = namespace(found=false) %}
362362
{%- for i in range(collection_date.weekday()+1) %}
363363
{%- set d = ( collection_date + timedelta( days=-i) ) | as_timestamp | timestamp_custom("%Y-%m-%d") %}

blueprints/holiday_in_week.yaml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
blueprint:
2+
name: Holiday in week
3+
description: Loop through all calculated dates, move the collection to the next day
4+
if public holiday was in the week before/on the calculated collection date.
5+
source_url: https://github.com/bruxy70
6+
domain: automation
7+
input:
8+
garbage_collection_entity:
9+
name: Garbage Collection Entity
10+
description: Triggered by the event for this entity.
11+
selector:
12+
entity:
13+
integration: garbage_collection
14+
holiday_entity:
15+
name: Holidays (a garbage collection integration entity)
16+
description: Entity containing the holidays. If you use the same
17+
entity for the calendar and the collection schedule, make sure to configure
18+
the collection schedule integration offset to 0, otherwise it will be moved twice.
19+
selector:
20+
entity:
21+
integration: garbage_collection
22+
mode: parallel
23+
trigger:
24+
- platform: event
25+
event_type: garbage_collection_loaded
26+
event_data:
27+
entity_id: !input garbage_collection_entity
28+
action:
29+
- variables:
30+
holiday_entity: !input holiday_entity
31+
- repeat:
32+
count: '{{ trigger.event.data.collection_dates | count }}'
33+
sequence:
34+
- condition: template
35+
value_template: >-
36+
{%- set collection_date = as_datetime(trigger.event.data.collection_dates[repeat.index-1]) %}
37+
{%- set ns = namespace(found=false) %}
38+
{%- for i in range(collection_date.weekday()+1) %}
39+
{%- set d = ( collection_date + timedelta( days=-i) ) | as_timestamp | timestamp_custom("%Y-%m-%d") %}
40+
{%- if d in state_attr(holiday_entity,'holidays') %}
41+
{%- set ns.found = true %}
42+
{%- endif %}
43+
{%- endfor %}
44+
{{ ns.found }}
45+
- service: garbage_collection.offset_date
46+
data:
47+
entity_id: "{{ trigger.event.data.entity_id }}"
48+
date: '{{ trigger.event.data.collection_dates[repeat.index] }}'
49+
offset: >-
50+
{%- set collection_date = as_datetime(trigger.event.data.collection_dates[repeat.index-1]) %}
51+
{%- set ns = namespace(offset=1, found=false) %}
52+
{%- for _ in range(7) if not ns.found %}
53+
{%- set d = ( collection_date + timedelta( days=ns.offset) ) | as_timestamp | timestamp_custom("%Y-%m-%d") %}
54+
{%- if d in state_attr(holiday_entity,'holidays') %}
55+
{%- set ns.offset = ns.offset + 1 %}
56+
{% else %}
57+
{%- set ns.found = true %}
58+
{%- endif %}
59+
{% endfor %}
60+
{{ ns.offset }}
61+
- service: garbage_collection.update_state
62+
data:
63+
entity_id: "{{ trigger.event.data.entity_id }}"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
blueprint:
2+
name: Holiday in week (simple)
3+
description: Loop through all calculated dates, move the collection to the next day
4+
if public holiday was in the week before/on the calculated collection date.
5+
It will always move the collection by 1 day, even if the new day was also a public holiday.
6+
source_url: https://github.com/bruxy70
7+
domain: automation
8+
input:
9+
garbage_collection_entity:
10+
name: Garbage Collection Entity
11+
description: Triggered by the event for this entity.
12+
selector:
13+
entity:
14+
integration: garbage_collection
15+
holiday_entity:
16+
name: Holidays (a garbage collection integration entity)
17+
description: Entity containing the holidays. If you use the same
18+
entity for the calendar and the collection schedule, make sure to configure
19+
the collection schedule integration offset to 0, otherwise it will be moved twice.
20+
selector:
21+
entity:
22+
integration: garbage_collection
23+
mode: parallel
24+
trigger:
25+
- platform: event
26+
event_type: garbage_collection_loaded
27+
event_data:
28+
entity_id: !input garbage_collection_entity
29+
action:
30+
- variables:
31+
holiday_entity: !input holiday_entity
32+
- repeat:
33+
count: '{{ trigger.event.data.collection_dates | count }}'
34+
sequence:
35+
- condition: template
36+
value_template: >-
37+
{%- set collection_date = as_datetime(trigger.event.data.collection_dates[repeat.index-1]) %}
38+
{%- set ns = namespace(found=false) %}
39+
{%- for i in range(collection_date.weekday()+1) %}
40+
{%- set d = ( collection_date + timedelta( days=-i) ) | as_timestamp | timestamp_custom("%Y-%m-%d") %}
41+
{%- if d in state_attr(holiday_entity,'holidays') %}
42+
{%- set ns.found = true %}
43+
{%- endif %}
44+
{%- endfor %}
45+
{{ ns.found }}
46+
- service: garbage_collection.offset_date
47+
data:
48+
entity_id: "{{ trigger.event.data.entity_id }}"
49+
date: '{{ trigger.event.data.collection_dates[repeat.index] }}'
50+
offset: 1
51+
- service: garbage_collection.update_state
52+
data:
53+
entity_id: "{{ trigger.event.data.entity_id }}"

custom_components/garbage_collection/config_flow.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
CONF_INCLUDE_DATES,
2828
CONF_WEEK_ORDER_NUMBER,
2929
CONF_WEEKDAY_ORDER_NUMBER,
30-
DAILY_FREQUENCY,
30+
DAILY_BLANK_FREQUENCY,
3131
DOMAIN,
3232
GROUP_FREQUENCY,
3333
MONTHLY_FREQUENCY,
@@ -113,7 +113,6 @@ def step1_user_init(self, user_input: Dict, defaults=None):
113113
# Do not show name for Options_Flow. The name cannot be changed here
114114
if defaults is not None and CONF_NAME in self.data_schema:
115115
del self.data_schema[CONF_NAME]
116-
117116
return False
118117

119118
def step2_annual_group(self, user_input: Dict, defaults=None):
@@ -286,7 +285,7 @@ async def async_step_user(
286285
if next_step:
287286
if self.shared_class.frequency in ANNUAL_GROUP_FREQUENCY:
288287
return await self.async_step_annual_group()
289-
elif self.shared_class.frequency in DAILY_FREQUENCY:
288+
elif self.shared_class.frequency in DAILY_BLANK_FREQUENCY:
290289
return await self.async_step_final()
291290
else:
292291
return await self.async_step_detail()
@@ -389,7 +388,7 @@ async def async_step_init(self, user_input=None):
389388
if next_step:
390389
if self.shared_class.frequency in ANNUAL_GROUP_FREQUENCY:
391390
return await self.async_step_annual_group()
392-
elif self.shared_class.frequency in DAILY_FREQUENCY:
391+
elif self.shared_class.frequency in DAILY_BLANK_FREQUENCY:
393392
return await self.async_step_final()
394393
else:
395394
return await self.async_step_detail()

custom_components/garbage_collection/const.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"every-n-days",
9292
"monthly",
9393
"annual",
94+
"blank",
9495
"group",
9596
]
9697

@@ -102,14 +103,25 @@
102103
"every-n-weeks",
103104
"every-n-days",
104105
"monthly",
106+
"blank",
107+
]
108+
EXCEPT_ANNUAL_GROUP_BLANK = [
109+
"weekly",
110+
"even-weeks",
111+
"odd-weeks",
112+
"every-n-weeks",
113+
"every-n-days",
114+
"monthly",
105115
]
106116
WEEKLY_DAILY_MONTHLY = ["every-n-weeks", "every-n-days", "monthly"]
107117
WEEKLY_FREQUENCY_X = ["every-n-weeks"]
108118
DAILY_FREQUENCY = ["every-n-days"]
119+
DAILY_BLANK_FREQUENCY = ["blank", "every-n-days"]
109120
MONTHLY_FREQUENCY = ["monthly"]
110121
ANNUAL_GROUP_FREQUENCY = ["annual", "group"]
111122
ANNUAL_FREQUENCY = ["annual"]
112123
GROUP_FREQUENCY = ["group"]
124+
BLANK_FREQUENCY = ["blank"]
113125

114126
MONTH_OPTIONS = [
115127
"jan",
@@ -332,7 +344,7 @@ class configuration(config_singularity):
332344
},
333345
CONF_COLLECTION_DAYS: {
334346
"step": 3,
335-
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP,
347+
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP_BLANK,
336348
"method": vol.Optional,
337349
"type": [str],
338350
"validator": vol.All(cv.ensure_list, [vol.In(WEEKDAYS)]),
@@ -357,14 +369,14 @@ class configuration(config_singularity):
357369
},
358370
CONF_FIRST_MONTH: {
359371
"step": 4,
360-
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP,
372+
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP_BLANK,
361373
"method": vol.Optional,
362374
"default": DEFAULT_FIRST_MONTH,
363375
"type": vol.In(MONTH_OPTIONS),
364376
},
365377
CONF_LAST_MONTH: {
366378
"step": 4,
367-
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP,
379+
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP_BLANK,
368380
"method": vol.Optional,
369381
"default": DEFAULT_LAST_MONTH,
370382
"type": vol.In(MONTH_OPTIONS),
@@ -400,7 +412,7 @@ class configuration(config_singularity):
400412
},
401413
CONF_HOLIDAY_MOVE_OFFSET: {
402414
"step": 4,
403-
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP,
415+
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP_BLANK,
404416
"default": 1,
405417
"method": vol.Optional,
406418
"type": int,
@@ -415,7 +427,7 @@ class configuration(config_singularity):
415427
},
416428
CONF_HOLIDAY_IN_WEEK_MOVE: {
417429
"step": 4,
418-
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP,
430+
"valid_for": lambda f: f in EXCEPT_ANNUAL_GROUP_BLANK,
419431
"method": vol.Optional,
420432
"default": DEFAULT_HOLIDAY_IN_WEEK_MOVE,
421433
"type": bool,

custom_components/garbage_collection/sensor.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,13 @@ async def _async_monthly_candidate(self, day1: date) -> date:
408408
WEEKDAYS.index(self._collection_days[0]),
409409
)
410410

411-
async def _async_find_candidate_date(self, day1: date) -> date:
411+
async def _async_find_candidate_date(self, day1: date) -> Optional[date]:
412412
"""Find the next possible date starting from day1.
413413
414414
Only based on calendar, not looking at include/exclude days.
415415
"""
416+
if self._frequency == "blank":
417+
return None
416418
week = day1.isocalendar()[1]
417419
weekday = day1.weekday()
418420
year = day1.year
@@ -626,6 +628,8 @@ def move_to_range(self, day: date) -> date:
626628
async def _async_find_next_date(self, first_date: date) -> Optional[date]:
627629
"""Get date within configured date range."""
628630
# Today's collection can be triggered by past collection with offset
631+
if self._frequency == "blank":
632+
return None
629633
if self._holiday_in_week_move:
630634
look_back = max(
631635
self._offset, self._holiday_move_offset, first_date.weekday()
@@ -665,6 +669,8 @@ async def _async_find_next_date(self, first_date: date) -> Optional[date]:
665669

666670
async def _async_load_collection_dates(self) -> None:
667671
"""Fill the collection dates list."""
672+
if self._frequency == "blank":
673+
return
668674
today = dt_util.now().date()
669675
start_date = end_date = date(today.year - 1, 1, 1)
670676
end_date = date(today.year + 1, 12, 31)
@@ -732,7 +738,7 @@ async def async_update(self) -> None:
732738
"collection_dates": dates_to_texts(self._collection_dates),
733739
}
734740
self.hass.bus.async_fire("garbage_collection_loaded", event_data)
735-
if not self._manual:
741+
if not self._manual and self._frequency != "blank":
736742
await self.async_update_state()
737743

738744
async def async_update_state(self) -> None:

0 commit comments

Comments
 (0)