#Switch Helper That Locks

1 messages · Page 1 of 1 (latest)

willow copper
#

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.

pulsar thicket
#

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

willow copper
#

Is there no way to secure the entity itself?

pulsar thicket
#

There is no way

willow copper
#

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

willow copper
#
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

willow copper
#

@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

willow copper
pulsar thicket
#

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
willow copper
#

Hmm

#

Can you share the exact yaml you used?

pulsar thicket
#
- 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

wise wedge
#

It’s likely related to your pin being numerical in your condition

willow copper
wise wedge
#

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?

willow copper
#

@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

wise wedge
#

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.

pulsar thicket
#

it would be nice if constructs like this could be integrated into the trace mechanism

willow copper
#

what do you mean by the same object type?

wise wedge
#

a number 1234 is not the same as a set of characters that are numbers "1234"

willow copper
#

Right, how would I confirm that?

wise wedge
#

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

pulsar thicket
#

easiest is just to convert both to int with |int

wise wedge
#

make the unlock into a script and it will generate a trace

wise wedge
#

it's likely coming at some point

#

I just need core on board with the config entry changes

willow copper
#

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!

wise wedge
#

code can be any type though

#

same with pin

pulsar thicket
#

I guess you could use is_number before converting to int

willow copper
#

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

willow copper
pulsar thicket
#

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

willow copper
#

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

pulsar thicket
#

"optimistic" assumes that it will succeed

willow copper
#

so make it false?

pulsar thicket
#

just remove it

#

optimistic boolean (Optional, default: false)

willow copper
#

Ok now it's all working, awesome!