Skip to content

Managing Guests and Rentals Recipes

raman325 edited this page Oct 27, 2026 · 2 revisions

Managing guests and rentals: recipes

Part of Managing guests and rentals, which explains the patterns these recipes build on: a permanent user on a recurring schedule, rotating a standing user, or adding and removing one per guest.

Complete automations, not fragments — paste one in and change the names. Every one of them generates the PIN rather than choosing it, because generate_pin draws from a cryptographic source and rejects sequences, repeats and the common-leak list.

1. A booking calendar that adds and removes the guest itself

The whole of Pattern 2, driven by the calendar. Two automations: one when a booking starts, one when it ends.

automation:
  - alias: "Guests: add on booking start"
    triggers:
      - trigger: calendar
        entity_id: calendar.bookings
        event: start
    actions:
      - action: lock_code_manager.generate_pin
        data: {length: 6}
        response_variable: generated
      - action: lock_code_manager.add_user
        data:
          config_entry_title: All Locks
          name: "{{ trigger.calendar_event.summary }}"
          pin: "{{ generated.pin }}"
      - action: notify.send_message
        target:
          entity_id: notify.mobile_app_phone
        data:
          message: >-
            {{ trigger.calendar_event.summary }} arrives today.
            Code {{ generated.pin }}.

  - alias: "Guests: remove on booking end"
    triggers:
      - trigger: calendar
        entity_id: calendar.bookings
        event: end
    actions:
      - action: lock_code_manager.delete_user
        data:
          config_entry_title: All Locks
          name: "{{ trigger.calendar_event.summary }}"

The guest's name comes from the event summary, so the two automations agree about who to remove without storing anything.

The summary has to be a usable name and the same one both times. An event titled Sarah Chen — 3 nights adds a user under that whole string, and renaming the event mid-stay means the remove step names somebody who isn't there. If your booking platform writes noisy summaries, either extract the name with a template or use Pattern 1, where the user already exists and only the name and PIN change.

Keep the remove automation: it's what revokes the code. Don't replace it with condition: calendar.bookings on the guest. That calendar is on during every booking, so a guest kept around with it as their condition would get their code back during every later booking.

2. An ad-hoc guest, on demand

For the friend staying this weekend, where there is no calendar. A script with a field, so it takes one tap from a dashboard button.

script:
  add_guest:
    alias: Add a guest code
    fields:
      guest_name:
        name: Guest name
        required: true
        selector:
          text:
    sequence:
      - action: lock_code_manager.generate_pin
        data: {length: 6}
        response_variable: generated
      - action: lock_code_manager.add_user
        data:
          config_entry_title: All Locks
          name: "{{ guest_name }}"
          pin: "{{ generated.pin }}"
      - action: notify.send_message
        target:
          entity_id: notify.mobile_app_phone
        data:
          message: "{{ guest_name }}: {{ generated.pin }}"

Removing them is lock_code_manager.delete_user with the same name — worth a second script if you hand out codes often.

A whole party at once. add_user takes a list, so a booking with several named guests is one call rather than one per person — and one read of your locks rather than several, which matters on battery locks. delete_user takes a list of names the same way. The single-person form used throughout this page is shorthand for a list of one and keeps working. See Services and Actions.

3. A code good for a fixed number of entries

add_user allocates the slot and waits for the entry to finish reacting before it returns, so the next step can address the new user's entities directly rather than guessing at a delay. (It waits on the entry, not on those specific entities, so a second write landing at the same instant can release it early — in practice that means don't fire two of these at once.)

script:
  add_one_use_guest:
    sequence:
      - action: lock_code_manager.generate_pin
        data: {length: 6}
        response_variable: generated
      - action: lock_code_manager.add_user
        data:
          config_entry_title: All Locks
          name: Courier
          pin: "{{ generated.pin }}"
      # The entities now exist, named after the user.
      - action: input_number.set_value
        target:
          entity_id: input_number.courier_uses
        data:
          value: 1

Then point the Slot Usage Limiter blueprint at event.all_locks_courier_credential_used, the enabled switch, and that counter. The code disables itself after one entry.

Entity IDs come from the name. A user called Courier gets event.all_locks_courier_credential_used; Sarah Chen gets ..._sarah_chen_.... That is fine for a fixed role like Courier, which is why this recipe uses one — a blueprint automation cannot repoint itself at a new entity ID per guest. For rotating guests, keep the standing user of Pattern 1 and rename it: the entity IDs never move, so the limiter stays pointed at the same ones.

Things these share

  • enabled defaults to true, and an enabled user must have a PIN. Adding one without a pin fails with 'Name' cannot be enabled without a PIN. Pass enabled: false to park a user with no code.
  • Names are unique by person, not by spelling. Two names that normalize to the same identity are refused with A user named 'X' already exists.
  • You never choose a slot number. Lock Code Manager reads what the locks hold and allocates a free one, so a slot a departing guest freed goes to the next arrival.
  • delete_user clears the PIN from every lock unless you pass clear_credentials: false — which leaves the code working on the lock and the slot occupied.
  • PIN length must satisfy your strictest lock. generate_pin takes 4–12 digits; if a lock takes only 4, ask for 4.

Clone this wiki locally