How I Secured My Home Using Home Assistant - Part Two

How I Secured My Home Using Home Assistant - Part Two
Photo by George Becker on Pexels.com

As I mentioned in Part One of this series, I prioritized my Home Assistant based security system around letting us know when there was an intrusion. It was important that the system let any intruders know their presence was known, and to make sure that we could respond whether we were remote or in another part of the house.

Home Assistant is the perfect solution automating your lights and for monitoring your house. So with that, let me show you how the system responds after the security system has been armed.

Intruder Alert!

My Home Assistant monitors all my doors via Zwave and Zigbee. sensors. These are actually connected via an old security system that used wried sensors to the doors and windows. Instead of putting the ZWave door sensors on the door itself they are actually in the security box. I just disconnected the wiring from the old logic board and wired them directly into the sensors. These Zwave sensors are the ones I used.

There are better solutions out there, but I do not have easy access to power in this box (its a long story and a horrible design) so for now the battery sensors work fine. I have not had to replace these batteries yet and they have been in place for over a year.

So now if a door is opened while the system is armed the automation security_breach_door is triggered.

- id: security_breach_door
    alias: Security Breach Doors
    trigger:
    - platform: state
      entity_id:
      - binary_sensor.front_door
      - binary_sensor.laundry_room_door
      - binary_sensor.back_door
      - binary_sensor.side_door
      - binary_sensor.garage_door
      from: 'off'
    condition:
    - condition: state
      entity_id: input_boolean.sentry_mode
      state: 'on'
    - condition: state
      entity_id: input_boolean.dog_mode
      state: 'off'
    action:
    - service: script.jarvis_alert
      data_template:
        message: "My security protocols are being overidden,, The {{ trigger.to_state.attributes.friendly_name }} has been opened."
    - service: script.text_alert
      data_template:
        title: "Security Alert!!"
        message: "{{ trigger.to_state.attributes.friendly_name }} has been opened."
    - service: input_boolean.turn_on
      entity_id: input_boolean.security_issue
    initial_state: true

As long as the sentry mode is on, and dog mode is off (I’ll be talking about that in the next security post) then the system announces the intrusion as if Agent Coulson was calling us urgently while we needed to gloat in our success. And it turns on input_boolean.security_issue.

Once security issue is on more automation takes over.

- id: security_response_on
    alias: Security Response On
    initial_state: true
    trigger:
    - platform: state
      entity_id: input_boolean.security_issue
      from: 'off'
      to: 'on'
    action:
    - service: script.turn_on
      entity_id: script.security_response
    - service: scene.turn_on
      entity_id: scene.lr_red

That automation turns the lights in the living room…can’t have a security issue without “Red alert”, and turns on the script.security_response which lets people in the house know their unwanted presence has been noticed.

  security_response:
    sequence:
    - service: script.inside_all_on
    - delay:
        seconds: 15
    - service: script.jarvis_alert
      data_template:
        message: >
          {{ [
          ",Unauthorized Access detected.",
          ",Meat Popsicle detected. Attempting to verify."
          ] | random }}
          You now have 60 seconds to abandon Anchorage House.
    - delay:
        seconds: 15
    - service: script.jarvis_alert
      data_template:
        message: >
          {{ [
          ",Just, what do you think you're doing, Dave?",
          ",This is highly unusual."
          ] | random }}
          You have 45 seconds.
    - delay:
        seconds: 15
    - service: script.jarvis_alert
      data_template:
        message: >
          {{ [
          ",I can't lie to you about your chances, but, you have my sympathies.",
          ",I wouldn't do that if I was you."
          ] | random }}
          You have 30 seconds.
    - delay:
        seconds: 15
    - service: script.jarvis_alert
      data_template:
        message: >
          {{ [
          "Danger. The emergency destruct system is now activated.",
          "Danger. Counter Measures are now armed."
          ] | random }}
          You have 15 seconds.
    - delay:
        seconds: 15
    - service: media_player.turn_on
      entity_id: media_player.ha_speaker
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.ha_speaker
        volume_level: .9
    - service: media_player.play_media
      entity_id: media_player.ha_speaker
      data:
        media_content_id: http://192.168.7.40/audio/security_siren.mp3
        media_content_type: "music"

There is a lot happening here. But the first thing it does is turn all the inside lights on. Then it starts its warning period which is a series of randomized comments and a count down. This is frankly just to give us time to disarm. Or run. You do not want to be inside with the alarm goes off.

If the alarm isn’t disarmed the volume is cranked (it’s loud enough that you can hear it on the street if all the doors are closed thanks to the stand-alone home theater AV receiver powering the audible notifications), and the most annoying siren is blared throughout the house for quite a while.

It also has already notified us via our phones, so we can respond as well. But thankfully that rarely happens with us in the house, because we know how to disarm.

Deactivating Barn door Protocol

Keeping with My Three Laws of Home Automation disarm happens without any user input….usually. And it can happen in several different ways.

Family is Home

The most obvious is just like Armed – Away is presence initiated, disarming is as well. Once people arrive back at home, and at least once of the presence sensors changes to ‘home’ the script.standby if executed.

The main purpose of this script is to turn off sentry mode, but since the alarm may have already started going off there are scripts that are meant to shut off any alarms or switches that were turned on:

standby:
    sequence:
    - condition: state
      entity_id: input_boolean.vacation_mode
      state: 'off'
    - service: input_boolean.turn_off
      entity_id: input_boolean.sentry_mode
    - service: input_boolean.turn_off
      entity_id: input_boolean.security_issue
    - service: input_boolean.turn_off
      entity_id: input_boolean.lockdown_issue
    - service: input_boolean.turn_off
      entity_id: input_boolean.security_alarm

It has on condition check to see if Vacation mode is off (it actually gets turned off before this script is fired if it is one) then it turns off input_boolean.sentry_mode. This is to ensure that if vacation mode is not off then it doesn’t disarm. This is another safety check to ensure it doesn’t get turned off when we are away because of a glitch.

But just in case something happened and the security alarm activated because a door opened before Home Assistant saw the presence of family, then it turns off all the various issues and the alarm itself.

It is not in this script, but anytime sentry mode is enabled or disabled, it lets us know. This prevents us not knowing when it goes into standby. This again is part of the series of checks and balances all done in the effort to prevent the wrong people or situation from disabling or enabling the security system.

Morning Standby

Every morning, after we are up, the system automatically disarms the system.

- id: morning_standby
    alias: Morning Standby
    initial_state: true
    trigger:
    - platform: time
      at: 05:30:00
    condition:
      condition: or
      conditions:
      - condition: state
        entity_id: sensor.family_status
        state: Home
      - condition: state
        entity_id: input_boolean.guest_mode
        state: 'on'
    action:
    - service: script.standby

This one simply makes sure we are home or guest mode is one, then executes script.standby. The condition checks mean if we are not home the system doesn’t disarm until we come back home. This is an imperfect solution, but for now it works because someone is always up by the time this disarms.

Voice Commands

And of course we have voice commands that can disable the security system. For security reasons I am not going to cover the exact commands because they are the closest thing this system has to an alarm code. But they are setup via the Alexa routines when used execute:

deactivate_barn_door_protocol:
    sequence:
    - service: script.ah_report
      data:
        call_confirmation: 1
    - delay:
        seconds: 2
    - service: input_boolean.turn_off
      entity_id: input_boolean.sentry_mode

This simply turns off the system, and the automation watching sentry mode status notifies us when it has been turned off.

Disarming Automatically

Unfortunately this system still operates with what I consider to be major flaw. If we are home and the system is armed there is nothing to remind us right before we open a door that the security system is armed and setting off the alarm. This “flaw” isn’t exclusive to this system either. Back when I had a monitored system I would be up working late and forget to disarm the security prior to opening a door which would sound the security alarm. And in previous system the Armed Home had no countdown before alarm went off. It just blared.

Future enhancements to this system will centered around making all disarming fit My First Law of Home Automation. My goal is to have a series of sensors to enable the system to know that someone on the inside is about to open the door and prevent the alarm from going off when it is someone on the inside taking out the trash or simply going to get something from the garage. Since this is security we are talking about it will need to be multiple inputs to reduce the chances it is disarmed from the outside and to ensure that it reads the intent correctly.

The rough sketch for this is a series of sensors tells Home Assistant that someone on the inside might be about to open a door which starts a timer. If a door is opened while the timer is active then the system disarms temporarily, only to re-armed when someone comes back in.

Other Security Features

Now there are some other things this system does.

Door Checks

The driveway lights come on at sunset if the garage door is open. This is both for security and because if the garage is open we are probably outside.

 - id: garage_open_sunset
    alias: Garage Open At Sunset
    initial_state: true
    trigger:
    - platform: sun
      event: sunset
    condition:
    - condition: state
      entity_id: binary_sensor.garage_door
      state: "on"
    action:
    - service: script.driveway_on

These lights then go off when the doors are closed if the sun has set. We also get a notification if the garage is still open after 9pm when we are likely back inside. This one needs to get refactored to be based on sunset since as the days get longer we are probably still outside at 9pm.

There is also an automation that plays a chime when doors are opened during the day. And then an announcement when a door has been standing open for more than a minute:

- id: door_opened_long
    alias: Door Opened Too Long
    trigger:
    - platform: state
      entity_id:
      - binary_sensor.front_door
      - binary_sensor.laundry_room_door
      - binary_sensor.attic_door
      - binary_sensor.back_door
      from: 'off'
      to: 'on'
      for: '00:01:00'
    condition:
    - condition: state
      entity_id: input_boolean.audible_notifications
      state: 'on'
    action:
    - service: script.ah_report
      data_template:
        speech_message: " the {{ trigger.to_state.attributes.friendly_name }} has been standing open for more than a minute."
        call_interuption: 1
        call_snark_door_open: 1
    initial_state: true

The for option on the trigger is an awesome way to handle this kind of automation.

Guest Mode

There is a guest mode that allows us to disable the security responses when we have guest over. I didn’t go into detail on it, but it is set either through voice commands or by recognizing devices on the network or via presence. This is a benefit of having the extended family also using Life360.

Fire!

We also have some ZWave Smoke / CO Alarms. I’m not going to put every one of these automations because frankly I need to refactor these to all be in one automation, but they all follow this pattern:

- id: Kitchen_Alarm_Smoke
    alias: Kitchen Alarm Smoke
    initial_state: true
    trigger:
    - platform: state
      entity_id: sensor.kitchen_alarm_type
      to: '1'
    action:
    - service: input_boolean.turn_on
      entity_id: input_boolean.fire_alarm
    - service: script.text_alert
      data_template:
        title: Security Alert - Smoke
        message: Smoke Detected in Kitchen!!
    - service: script.jarvis_alert
      data_template:
        message: Smoke Detected in Kitchen!
    - delay:
        seconds: 5
    - service: script.fire_alarm
    - delay:
        seconds: 15
    - service: notify.alexa_media_everywhere
      data:
        message: Smoke Detected in Kitchen
        data:
          type: announce

The idea is when smoke is detected, turn on input_boolean.fire_alarm that is used to reduce false alarms and to allow us to test. Let me just mention it’s important to test these responses, and having an input boolean kicking off the process makes it easy.

The system starts announcing via the house audio there is a fire and gives the location, then broadcasts on all the echos the same thing. The script.fire_alarm takes over and blares the fire alarm mp3.

Vacation Mode

And perhaps lastly there is a vacation mode. This one is just an input boolean and is simply meant to put the house in Vacation mode which change some of the automations, and prevents the security system from being disarmed until we are home. This one gets set based automatically based on how far we are from home. So there is nothing for anyone to do here. We go on vacation and we don’t need to tell the house. The house just knows.

- id: enable_vacation_mode
    alias: Enable Vacation Mode
    initial_state: true
    trigger:
    - platform: numeric_state
      entity_id: sensor.jeff_ett_home
      above: 180
    - platform: numeric_state
      entity_id: sensor.kat_ett_home
      above: 180
    condition:
    - condition: numeric_state
      entity_id: sensor.jeff_ett_home
      above: 180
    - condition: numeric_state
      entity_id: sensor.kat_ett_home
      above: 180
    action:
    - service: input_boolean.turn_on
      entity_id: input_boolean.vacation_mode

And Finally…

If you have stuck around to this point thank you! It’s not perfect, but I don’t think Home automation ever will. I am constantly tweaking. As I typed this up I was still making changes. Hopefully but the time you are reading this I would have push those changes to the GitHub repo.

If you see something that could be improved do not hesitate to send my repo a pull request, or just shoot me a comment. You can find me on twitter or leave a comment on this article.

Until Next time…Go Automate Something!

Mastodon