Esphome alarm system

I have been playing with creating a self contained wired alarm system using an esp32 with esphome. All the logic happens on the esp32, which drastically improves the performance and stability of the system compared to having the logic in HA.

The new template alarm_control_panel in v0.105 makes this system fully functional.

My home assistant server can read the state of all the entities like motion detectors and door sensors. Home assistant can arm and disarm the system by providing a code to the device.

With this setup, one can also take advantage of a lot of the great possibilities of interegrating into HA like sending notifications, gathering pictures from cameras, etc.

I want to see if I can get a keypad integrated on device using this custom esphome library, although I’m quickly running out of GPIO pins to use. Separate codes could be used for separate users on the esp32 alarm. One could also imagine programming a dynamic code that expires for guests.

I need to test the robustness of the system to the brief wifi disconnections and sometimes device reboots that aren’t uncommon. So this is still very experimental. I would love to know if anyone has tips on this.

I did not use any of the end of line resistors to measure different states like circuit shorts, but is possible to integrate into this logic. Here is a great example DIY Replacement Alarm Panel.

The template alarm_control_panel doesn’t support some common states like pending yet, so it currently throws an error in HA when the alarm is pending. But since all the logic is local on the esp32, this does not affect the functionality.

Code here


Interesting, thanks for sharing.
When I looked at the template_alarm_panel on 0.105 release I really wanted to see how to use it. Will have a look at it.
You said it’s a wired system and you’re running out of GPIOs - have you ever thought about using wireless sensors/converting multiple separate signals into MQTT messages and then send them to your ESP (I know it won’t be a self-contained anymore but still…)

1 Like

You can see my code example for how to use it. It works well, although the way it is implemented is a little cumbersome. For example, the only way to use the provided code is inside the actions. There is no code_template that provides code checking automatically.

My goal is to have everything wired on device, which makes everything more robust IMO. Plus, I already have the wired sensors. I think I still have some GPIOs to use, although I might have to start using pins without internal pull-up resistors. The esp32 has so many pins available compared to the esp8266.

Always possible to use an i2c IO expander or even just a bunch of shift registers to expand gpio.

Also, if you’re going to all the trouble to make everything wired to be more robust, I’d highly suggest using wired Ethernet with your esp32.


how do we do that?

Needs additional hardware (magjack) but is supported in esphome. Should be lots of docs on setting it up. Will likely need many gpio though.

I am curious what kind of performance and stability issues occur when using ha for logic?

I currently use the ha alarm panel card for a GUI, and nodered to handle the logic… lots of esphome and zwave devices for input. I haven’t seen any latency issues or high loads on the pi3b+ from this (but I admit I’m noob enough to not know if I may be… nothing obvious happening anyways). I do like to offload HA when I can using logic in esp’s for certain things (like running average polling, or sending commands that would otherwise be repetitive… like beeping 3 times I send a single “3” instead of 6 on/off commands with delays between). However I don’t think there’s anything my alarm does like that… each arm/disarm/pending is a single state change so not a big load on top of everything else.

edit: On a side note, I agree the addition of an i2c expander is a perfect solution to the lack of gpio here. Also, when running ethernet, if you happen to have poe available, I think you can even buy a poe hat to power the esp from as well.

These are good suggestions about the io expanders. They look very useful when I run out of pin space. I wish I had started with them.

I need to look into the Ethernet again. The last time I had looked there wasn’t that much good information on using it.

On stability and lag, 90% of the issue is having a self contained alarm system to continue working when home assistant is down (like during a version update and I forget to read the novel of breaking changes) or the power is out. I have a battery backup for the esp which draws less power than the pi. I also currently have a very custom way to arm and disarm the system that I wanted to keep secret so didn’t include in the shared code. I noticed a small but noticeable lag with the alarm logic in home assistant when using it to arm and disarm, but absolutely no lag with only the esp32. It didn’t inspire my confidence when the warning chirp didn’t respond immediately.

Thank you for sharing that. I’m in the process of testing that and so far I’m not able to get the “Alarm” status to go from “unknown” to " Disarmed or Armed". I’m basically using your config.

I need more info to try and help you debug it, have you looked at the esphome logs to see if it helps. Have you provided the codes as strings to esphome?

thank you for your reply.

  password: "xxxxxxxx"
    - service: arm_home
         code: string
        - if:
              lambda: "return code == \"xxxx\";"
              - script.execute: alarm_arm
    - service: diasarm
         code: string
        - if:
              lambda: "return code == \"xxxx\";"
              - script.execute: alarm_disarm

I realized that it might be important to have the same name for the node. I think home assistant esphome integration uses it for the service call name.

I updated the gist.

Also check your logs in home assistant, you likely have an error in one log or another.

Ok i’ll check it out and thank you for the help

So far, the log for esphome shows no errors and HA shows this error


HA Config

  - platform: template
        value_template: "{{ states('sensor.alarm_condition') }}"
          - condition: template
            value_template: "{{ code == 'xxxx' }}"
          - service: esphome.esp32_alarm_arm_home
              code: xxxx
          - condition: template
            value_template: "{{ code == 'xxxx' }}"
          - service: esphome.esp32_alarm_diasarm
              code: xxxx

Have you tried arming or disarming your alarm? What do you see? Also it looks like you have a typo in your disarm action for the service name.

EDIT: Also, do you have an entity called sensor.alarm_condition that shows up?

I cannot disarm or arm since the alarm is in “unknown” status; those options are grayed out. Also the sensor.alarm_condition showed, but it is unknown.

Ok, this narrows your current issue to be on the home assistant side. You should be able to execute the arm and disarm service regardless of the state. I think mine also showed unknown until the first arm action. You can pressure test this by making your value_template always return “disarmed”. If you do this, does it work?

value_template: "{{ 'disarmed' }}"

I’ll give it a try and thank you

Thanks for this.
I’m in the process of setting up the same myself. I’d however just used the esp as a sensor platform, much nicer to offload the logic, so it’s less dependant on ha being available.
How does it handle power cycles?