I'm looking to create a switch Helper that will be mainly updated from the UI, but I want to lock its ability to be changed (at least in one direction) with a passcode.
What's the best way to set that up?
I don't want it to be a lock template on a helper switch because then theoretically someone can toggle the switch without the code.
#Switch Helper That Locks
1 messages · Page 1 of 1 (latest)
This sounds like a card
Entity cards can have codes, I think
Might just be a confirmation
I think you should look for a dashboard card that supports this. Other solutions will be very complicated
I don't want the entity to be editable by any automation by mistake
Is there no way to secure the entity itself?
There is no way
Ok thank you, I guess a switch Helper with a lock template is the best bet
Maybe I can block via automation the switch entity from getting toggled and that would effectively be what I'm looking for
template:
- lock:
- name: Lock
optimistic: true
state: "{{ is_state('input_boolean.switch', 'on') }}"
code_format: "{{ '\\d{4}' if is_state('input_boolean.switch', 'on') else None }}"
lock:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.switch
unlock:
- variables:
pin: !secret code
- condition: "{{ code == pin }}"
- action: input_boolean.turn_off
target:
entity_id: input_boolean.switch
why isn't this working?
when unlocking it doesn't set the input_boolean and it requires a code for both locking and unlocking
@wise wedge I see you made the change from template lock, it seems to be a bug where the unlock action isn't working correctly
Issue/bug created https://github.com/home-assistant/core/issues/153792
your example works fine for me:
2025-10-05 20:58:05.145 INFO (MainThread) [homeassistant.helpers.script.test_lock_lock] Test Lock lock: Running template script
2025-10-05 20:58:05.145 INFO (MainThread) [homeassistant.helpers.script.test_lock_lock] Test Lock lock: Executing step call service
2025-10-05 20:58:05.145 ERROR (MainThread) [homeassistant.components.system_log.external] Locked
2025-10-05 20:58:10.406 INFO (MainThread) [homeassistant.helpers.script.test_lock_unlock] Test Lock unlock: Running template script
2025-10-05 20:58:10.407 INFO (MainThread) [homeassistant.helpers.script.test_lock_unlock] Test Lock unlock: Executing step call service
2025-10-05 20:58:10.407 ERROR (MainThread) [homeassistant.components.system_log.external] Unlocked
- lock:
- name: Test Lock
optimistic: true
lock:
- action: system_log.write
data:
level: error
message: Locked
unlock:
- action: system_log.write
data:
level: error
message: Unlocked
I reduced the indentation of the block starting with name: by 2 spaces to match the rest of my file, but I just put it back the way you had it and it still works fine
Uh, this isn’t possible. There are test cases that cover this and work as intended. There is something wrong with whatever you are doing.
It’s likely related to your pin being numerical in your condition
I tried narrowing down the cause by removing all pins and had the same issue, what is the best way to share my logs to post on the GitHub issue?
Well, to be honest, it's not a bug
you're doing something wrong
but, to share logs, just run the actions that log out
Here's your exact configuration from the bug report posting directly to the logs
as you can see, you can see the locked and unlocked messages
looking at it via the ui...
@willow copper does your actual configuration still contain the condition?
@wise wedge I stripped it all out
Your right it is working, it was grouping it under one row, so that got me confused
Now I gotta work back and see where the issue starts
the issue is likely related to that condition and the way you're comparing the pin to the code
if your pin is all numbers, you need to ensure both the pin and the code are the same object type
i.e. 1234 is not the same as "1234"
thus making that condition always fail.
it would be nice if constructs like this could be integrated into the trace mechanism
Yup, without the condition it works fine (with any 4 digit pin) with it it's messing up
what do you mean by the same object type?
a number 1234 is not the same as a set of characters that are numbers "1234"
Right, how would I confirm that?
the first one would be an int, the second is a string
by looking at the trace
well, you can't do that can you
easiest is just to convert both to int with |int
make the unlock into a script and it will generate a trace
shhhhhh
it's likely coming at some point
I just need core on board with the config entry changes
ok it's working!
- lock:
- name: Test Lock
optimistic: true
code_format: "{{ '\\d{4}' if is_state('switch.test_switch', 'on') else None }}"
lock:
- action: system_log.write
data:
level: error
message: Locked
- action: switch.turn_on
target:
entity_id: switch.test_switch
unlock:
- variables:
pin: !secret shabbos_mode_code
- condition: "{{ code|int == pin|int }}"
- action: system_log.write
data:
level: error
message: Unlocked
- action: switch.turn_off
target:
entity_id: switch.test_switch
the key change
{{ code|int == pin|int }}
Perhaps the docs can be updated?
Thank you for all the detailed help!
I guess you could use is_number before converting to int
well now the code_format is making sure its 4 digits
I theoretically don't even need the 2nd dummy switch if I would be able to template against the current state of the lock
code_format: "{{ '\\d{4}' if is_state('lock.test_lock', 'locked') else None }}"
That doesn't seem to work though
Oops just noticed that any 4 digits is working, why isn't it checking against my code?
you can use your system_log.write calls or persistent_notification.create to debug
I mean, first it wasn't accepting anything, so it's clearly checking
it shows it's not a match 🙂
What's happening is that it's getting unlocked but the switch isn't changing
Oh maybe becuase I took out the state:
added the state in, but it's still getting unlocked when the code is wrong, it just doesn't update the switch
"optimistic" assumes that it will succeed
so make it false?
Ok now it's all working, awesome!