Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ repos:
- id: check-merge-conflict
- id: check-xml
- id: check-yaml
exclude: ^blueprints/
- id: debug-statements
- id: end-of-file-fixer
- id: requirements-txt-fixer
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ Features:
- `input_boolean` - code is active when the input boolean is `on`
- Optionally define a maximum number of uses for a code before the code is disabled

## Blueprints

LCM provides blueprints for common automation patterns:

| Blueprint | Description | Import |
| --------- | ----------- | ------ |
| Slot Usage Limiter | Limit PIN uses with a counter, auto-disable at 0 | [![Import](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Framan325%2Flock_code_manager%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Flock_code_manager%2Fslot_usage_limiter.yaml) |
| Calendar Condition | Binary sensor for advanced calendar-based access control | [![Import](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Framan325%2Flock_code_manager%2Fblob%2Fmain%2Fblueprints%2Ftemplate%2Flock_code_manager%2Fcalendar_condition.yaml) |
| Calendar PIN Setter | Set PINs from calendar event data | [![Import](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Framan325%2Flock_code_manager%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Flock_code_manager%2Fcalendar_pin_setter.yaml) |

See the [Blueprints wiki page](https://github.com/raman325/lock_code_manager/wiki/Blueprints) for setup details.

Locks from the following integrations are currently supported:

- Z-Wave
Expand Down
147 changes: 147 additions & 0 deletions blueprints/automation/lock_code_manager/calendar_pin_setter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
blueprint:
name: "Lock Code Manager: Calendar PIN Setter"
description: >
Extracts a PIN from calendar event attributes using a user-provided template
and sets it on a Lock Code Manager code slot. Optionally clears the PIN when
the calendar event ends.


**Available template variables**

Your PIN and slot number templates can use these variables:

- `message` — calendar event summary/title

- `description` — calendar event description

- `location` — calendar event location

- `start_time` — event start time

- `end_time` — event end time

- `all_day` — whether the event is an all-day event


**Example PIN templates**

- Extract a 4-digit PIN from description:
`{{ description | regex_findall('\\b\\d{4}\\b') | first | default('') }}`

- Use the first 4 characters of the event title:
`{{ message[:4] if message | length >= 4 else '' }}`


**Template debugging**

To test your PIN template, go to Developer Tools → Template and paste:

```

{% set description = state_attr('calendar.YOUR_CALENDAR', 'description') | default('') %}

{{ description | regex_findall('\\b\\d{4}\\b') | first | default('') }}

```
domain: automation
# yamllint disable-line rule:line-length
source_url: https://github.com/raman325/lock_code_manager/blob/main/blueprints/automation/lock_code_manager/calendar_pin_setter.yaml
input:
config_entry:
name: Lock Code Manager config entry
description: The Lock Code Manager config entry that manages your lock(s).
selector:
config_entry:
integration: lock_code_manager
slot_number:
name: Slot number
description: >
The code slot number. Can be a static number (e.g. `3`) or a Jinja2
template that resolves to a number using calendar event attributes
(e.g. `{{ description | regex_findall('slot (\d+)') | first }}`).
selector:
template:
calendar_entity:
name: Calendar entity
description: The calendar entity whose events provide PIN codes.
selector:
entity:
domain: calendar
pin_template:
name: PIN template
description: >
A Jinja2 template that extracts a PIN from calendar event attributes.
Must evaluate to a non-empty string to set the PIN, or empty string to
skip setting.
selector:
template:
clear_on_end:
name: Clear PIN when event ends
description: >
When enabled, the PIN is cleared (set to empty) when the calendar
event ends.
default: true
selector:
boolean:

mode: single

variables:
config_entry: !input config_entry
calendar_entity: !input calendar_entity
clear_on_end: !input clear_on_end
config_entry_title: >
{{ config_entry_attr(config_entry, 'title') }}
_all_entities: >
{{ integration_entities(config_entry_title) }}

triggers:
- trigger: state
entity_id: !input calendar_entity

actions:
- variables:
message: >
{{ state_attr(calendar_entity, 'message') | default('', true) }}
description: >
{{ state_attr(calendar_entity, 'description') | default('', true) }}
location: >
{{ state_attr(calendar_entity, 'location') | default('', true) }}
start_time: >
{{ state_attr(calendar_entity, 'start_time') | default('', true) }}
end_time: >
{{ state_attr(calendar_entity, 'end_time') | default('', true) }}
all_day: >
{{ state_attr(calendar_entity, 'all_day') | default(false, true) }}
slot_number: !input slot_number
pin_entity: >
{{ _all_entities
| select('match', 'text\\..*_code_slot_' ~ slot_number ~ '_pin')
| first | default('') }}
pin_value: !input pin_template
- choose:
- conditions:
- condition: template
value_template: >
{{ trigger.to_state.state == 'on'
and pin_entity != ''
and pin_value != '' }}
sequence:
- action: text.set_value
target:
entity_id: "{{ pin_entity }}"
data:
value: "{{ pin_value }}"
- conditions:
- condition: template
value_template: >
{{ trigger.to_state.state == 'off'
and clear_on_end
and pin_entity != '' }}
sequence:
- action: text.set_value
target:
entity_id: "{{ pin_entity }}"
data:
value: ""
145 changes: 145 additions & 0 deletions blueprints/automation/lock_code_manager/slot_usage_limiter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
blueprint:
name: "Lock Code Manager: Slot Usage Limiter"
description: >
Decrements an `input_number` helper each time a code slot PIN is used.
When the counter reaches 0 the slot is automatically disabled.
Optionally resets the counter when the slot is re-enabled.


**Requirements**

This blueprint requires at least one lock that supports code slot events
(i.e. produces `*_code_slot_*_pin_used` events). If none of your locks
support this, the counter will never decrement.


**Setup**

1. Create an `input_number` helper (Settings → Devices & Services → Helpers)
with min=0, max=your desired limit, and step=1.

2. Import this blueprint and configure it with your Lock Code Manager config
entry, slot number, and the helper you just created.


**Template debugging**

To test entity resolution, go to Developer Tools → Template and paste:

```

{% set title = config_entry_attr('YOUR_CONFIG_ENTRY_ID', 'title') %}

{% set all = integration_entities(title) %}

{{ all | select('match', 'event\\..*_code_slot_1_pin_used') | list }}

```

Replace YOUR_CONFIG_ENTRY_ID with your LCM config entry ID and 1 with your
slot number.
domain: automation
# yamllint disable-line rule:line-length
source_url: https://github.com/raman325/lock_code_manager/blob/main/blueprints/automation/lock_code_manager/slot_usage_limiter.yaml
input:
config_entry:
name: Lock Code Manager config entry
description: The Lock Code Manager config entry that manages your lock(s).
selector:
config_entry:
integration: lock_code_manager
slot_number:
name: Code slot number
description: The code slot number to monitor.
selector:
number:
min: 1
max: 999
mode: box
uses_counter:
name: Uses counter
description: >
An `input_number` helper that tracks remaining uses.
Create one via Settings → Devices & Services → Helpers.
selector:
entity:
domain: input_number
initial_uses:
name: Initial uses on re-enable
description: >
When greater than 0, the counter is automatically reset to this value
each time the slot is re-enabled. Set to 0 to disable auto-reset.
default: 0
selector:
number:
min: 0
max: 999
mode: box

mode: queued
max: 10

trigger_variables:
_config_entry: !input config_entry
_slot: !input slot_number
_title: >
{{ config_entry_attr(_config_entry, 'title') }}
_all_entities: >
{{ integration_entities(_title) }}
pin_used_entity: >
{{ _all_entities
| select('match', 'event\\..*_code_slot_' ~ _slot ~ '_pin_used')
| first | default('') }}
enabled_switch: >
{{ _all_entities
| select('match', 'switch\\..*_code_slot_' ~ _slot ~ '_enabled')
| first | default('') }}

triggers:
- trigger: state
entity_id: "{{ pin_used_entity }}"
id: pin_used
- trigger: state
entity_id: "{{ enabled_switch }}"
id: slot_enabled
to: "on"

variables:
initial_uses: !input initial_uses
uses_counter: !input uses_counter

actions:
- choose:
- conditions:
- condition: trigger
id: pin_used
sequence:
- variables:
current: >
{{ states(uses_counter) | int(0) }}
new_count: >
{{ [current - 1, 0] | max }}
- action: input_number.set_value
target:
entity_id: !input uses_counter
data:
value: "{{ new_count }}"
- if:
- condition: template
value_template: "{{ new_count == 0 }}"
then:
- action: switch.turn_off
target:
entity_id: "{{ enabled_switch }}"
- conditions:
- condition: trigger
id: slot_enabled
- condition: template
value_template: "{{ initial_uses | int(0) > 0 }}"
sequence:
- action: input_number.set_value
target:
entity_id: !input uses_counter
data:
value: !input initial_uses
Loading
Loading