Skip to content

Managing Guests and Rentals

raman325 edited this page Aug 28, 2026 · 4 revisions

Managing guests and rentals

A short-term rental, a spare room, a cleaner who comes on Tuesdays: somebody other than the household needs a code, but not all the time.

Start by asking what actually changes — because in the most common case, nothing does, and there is no per-visit work at all.


Complete, paste-able automations are in Recipes below.

The short version

Permanent user, recurring condition Rotate a standing user Add and remove
Use when The same person, on a repeating schedule Same number of guests, different people Ad-hoc, and the count varies
Example The cleaner, every Tuesday morning A rental unit's guest A contractor for one week
What changes per visit Nothing Name and PIN The user itself
Entity IDs Never change Never change Change every time
Automations Keep working Keep working Need repointing each time

Work down that table and stop at the first row that fits. Most recurring access — cleaners, dog walkers, a neighbour who feeds the cat — is the first row, and needs no automation whatsoever.


Pattern 0: a permanent user on a recurring schedule

The cleaner comes every Tuesday. The person is not temporary; only the window is. So this is one permanent user with a schedule attached as their condition — and once it is set up, there is nothing to do per visit, ever.

  1. Add a user named for the person: Cleaner, or their actual name.
  2. Create a schedule helper covering when they should get in — Tuesday 08:00–12:00.
  3. Attach it as their condition entity.

Their PIN is written to the locks while the schedule is on and removed when it is off. You do not enable and disable anything; the schedule reverses itself. The code is dead for the other six days without you thinking about it.

Use a calendar instead of a schedule when the pattern is irregular — a cleaner who comes fortnightly, or whose day moves — since a calendar can hold arbitrary dates while a schedule repeats weekly. Everything else is the same.

This is also the right shape for a dog walker, a gardener, a carer, or anyone else who comes back on a rhythm. If the person is not changing, do not rotate or re-create them.


Why renaming is free

Lock Code Manager identifies a user internally by the slot number they hold, not by their name. The name is the label you see; it is not the key.

That means renaming a user changes nothing but the label. Their entity IDs stay put. Their history stays attached. Every automation, script, dashboard card and blueprint that references them keeps working. You can rename Guest 1 to Sarah Chen on Friday and back to Guest 1 on Monday, forever, and nothing downstream notices.

Adding a user is the opposite. A new user gets new entity IDs, named after them — text.all_locks_sarah_chen_pin — so anything you want to automate has to be pointed at the new entities each time. Removing them takes those entities away again.

Neither is wrong. But if you find yourself re-editing the same automation every booking, you have chosen the wrong pattern.


Pattern 1: rotate a standing user (recommended for rentals)

For when the position is stable but the person is not. Set up once, then change two fields per booking.

Setup

  1. Decide how many guests you can have at once — usually one per rental unit.
  2. Add that many users, named for the position rather than the person: Guest 1, Guest 2. Leave them disabled, with no PIN. (Staff who come on a rhythm are not guests — give them their own permanent user per Pattern 0.)
  3. Attach a condition entity to each so the code only works when it should. A calendar is the natural fit for a rental: the PIN is live during the booking and dead outside it, without anything having to remember to turn it off.

Per booking

Change the name to the guest, set a fresh PIN, and let the calendar handle activation:

action: text.set_value
target:
  entity_id: text.all_locks_guest_1_name
data:
  value: Sarah Chen

action: text.set_value
target:
  entity_id: text.all_locks_guest_1_pin
data:
  value: "{{ pin }}"

Generate the PIN rather than picking one — generate_pin draws from a cryptographic source and rejects sequences, repeats and the common-leak list:

action: lock_code_manager.generate_pin
data:
  length: 6
response_variable: generated

action: text.set_value
target:
  entity_id: text.all_locks_guest_1_pin
data:
  value: "{{ generated.pin }}"

Those entity IDs never change, so this automation is written once.

You can also address the person by name with set_credential, which avoids depending on entity IDs at all — though for this pattern you would have to rename first and then set the PIN under the new name, so the entity-driven version above stays simpler here. Where it earns its keep is rotating a code for somebody whose name is not changing:

action: lock_code_manager.set_credential
data:
  config_entry_title: All Locks
  name: Sarah Chen
  credential_type: pin
  value: "{{ generated.pin }}"
  enable_if_disabled: true

enable_if_disabled matters if the code was cleared earlier — clearing disables the person, so without it the new PIN would be set but inert.

Fully automated from a calendar

If your booking platform publishes a calendar, the Calendar PIN Setter blueprint does the whole thing: extracts a PIN from the event, sets it when the booking starts, clears it when it ends. Pair it with the Slot Usage Notifier if you want to know when they first arrive.


Pattern 2: add and remove per guest

Better when the count varies — a contractor for one week, a house-sitter once a year — and you would otherwise be maintaining standing users who are empty most of the time. If they are coming back on a schedule, they are Pattern 0, not this.

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: Sarah Chen
  pin: "{{ generated.pin }}"
  condition: calendar.bookings

and when they leave:

action: lock_code_manager.delete_user
data:
  config_entry_title: All Locks
  name: Sarah Chen

Removing a user clears their PIN from every lock in the entry. That is the point of removing them. If you want the opposite — hand the code over and stop tracking it here — pass clear_credentials: false, but understand that the code keeps working and the slot stays occupied.

You do not choose a slot number. Lock Code Manager reads what the locks hold and allocates a free one, so a slot freed by a departing guest is available to the next.

Both actions accept config_entry_title as well as config_entry_id, which makes hand-written automations readable.



Recipes

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.

If you would rather the code stop working at checkout without removing the user, pass condition: calendar.bookings to add_user and drop the second automation — the condition entity turns the code off when the event ends. The user stays, holding an inactive code, until you remove them.

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.

Keeping guests apart from household codes

You can run two config entries against the same locks — one for permanent codes (you, family, staff) and one for guests — as long as they do not manage the same slot numbers on the same lock.

Worth doing when:

  • You want the guest dashboard separate from the household one.
  • You want to wipe every guest code at once, by clearing that entry.
  • Different people administer them.

Not worth it for two or three codes; one entry is simpler.


Things that bite

Locks have a finite number of slots. Adding users fails once the lock is full. Standing users make the ceiling visible up front rather than at the worst moment.

A code left behind still opens the door. Before 5.0, removing a slot did not clear its PIN. If your locks predate that, the upgrade asks about every code it cannot account for — see [[Upgrading to 5.0#unmanaged-codes|Upgrading-to-5.0#unmanaged-codes]].

Do not reuse a PIN between guests. Generate a new one each time. A returning guest's old code should not still work, and the previous guest should not be able to guess the next one.

A condition entity is not the same as disabling. A disabled user's code is removed from the lock. A user gated by a condition still holds their slot; the code is only written while the condition is on. For a rental you almost always want the condition — it reverses itself.

Check the PIN actually landed. Each user has an in sync sensor per lock. If a lock was asleep or unreachable when you set the code, that sensor tells you before your guest does.

Clone this wiki locally