Skip to content

Instantly share code, notes, and snippets.

@tboby
Last active February 6, 2025 20:31
Show Gist options
  • Save tboby/e28b9252037616bd5d3d31000944ebf0 to your computer and use it in GitHub Desktop.
Save tboby/e28b9252037616bd5d3d31000944ebf0 to your computer and use it in GitHub Desktop.
Alarm panel pro with local keypad
esphome:
name: ${name}
name_add_mac_suffix: false
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ota:
- platform: esphome
password: !secret ota_password
####
##
## Konnected Alarm Panel Pro (ESP32)
## Firmware configuration for ESPHome
##
## filename: alarm-panel-pro-esp32.yaml
## GitHub: https://github.com/konnected-io/konnected-esphome
## Buy Konnected hardware: https://konnected.io
## Help & Support: https://[email protected] (support is provided for purchasers of Konnected hardware)
##
## Copyright© 2023 Konnected Inc.
##
## Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
## files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
## modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
## is furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
## OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
## LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
## IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
##
####
####
# GENERAL SETTINGS
# Customize these variables to your preferences and needs
# more: https://esphome.io/guides/configuration-types.html#substitutions
substitutions:
####
# NAME
# By default, the name of the ESPHome device is "konnected-xxxxxx" where xxxxxx is a unique identifier. The device's
# hostname on your network is also defined by the name, defaulting to "konnected-xxxxxx.local". Edit this variable to
# customize the name and hostname. Note: only lowercase characters, numbers and hyphen(-) are allowed.
name: xxx
friendly_name: xxx
project_name: konnected.alarm-panel-pro-esp32-local-keypad
project_version: "0.2.2-tb"
sensor_debounce_time: 200ms
warning_beep_pulse_time: 100ms
warning_beep_pause_time: 130ms
warning_beep_internal_only: "false"
warning_beep_shared: "false"
blink_on_state: "true"
####
# ALARM CONFIG
alarm_code: !secret alarm_master_code
disarmed_state: '0'
arming_state: '1'
armed_away_state: '2'
armed_home_state: '3'
armed_night_state: '4'
pending_state: '5'
triggered_state: '6'
# yamllint disable-line rule:line-length
state_strings: '{"disarmed", "arming", "armed_away", "armed_home", "armed_night", "pending", "triggered"}'
####
# ZONE MAPPING
# Do not edit this section.
zone1: GPIO4
zone2: GPIO2
zone3: GPIO15
zone4: GPIO13
zone5: GPIO18
zone6: GPIO14
zone7: GPIO33
zone8: GPIO32
zone9: GPIO36
zone10: GPIO39
zone11: GPIO34
zone12: GPIO35
alarm1: GPIO12
alarm2: GPIO5
out1: GPIO23
out2: GPIO5
status_led: GPIO3
####
# CONNECTION MAPPINGS
warning_beep_pin: $out1
####
# PACKAGES
# Each package includes the alarm panel feature
# Remove or comment out any packages that you do not need or want.
# If you're developing/installing locally, replace the github package line with the local package include above it.
packages:
remote_package:
url: https://github.com/konnected-io/konnected-esphome
ref: master
refresh: 5min
files:
####
# CORE
# This package is required and sets up core features.
- packages/core-esp32.yaml
####
# WIFI
# Enables WiFi connectivity and diagnostics. Uncommet below to enable WiFi.
- packages/wifi-esp32.yaml
####
# STATUS LED
# Enables the onboard blue status LED as an activity/error indicator
- packages/status-led.yaml
####
# INPUT ZONES
# - packages/alarm-panel/zone1.yaml
# - packages/alarm-panel/zone2.yaml
- packages/alarm-panel/zone3.yaml
- packages/alarm-panel/zone4.yaml
- packages/alarm-panel/zone5.yaml
- packages/alarm-panel/zone6.yaml
- packages/alarm-panel/zone7.yaml
# - packages/alarm-panel/zone8.yaml
# - packages/alarm-panel/zone9.yaml
# - packages/alarm-panel/zone10.yaml
# - packages/alarm-panel/zone11.yaml
# - packages/alarm-panel/zone12.yaml
####
# OUTPUTS
- packages/alarm-panel/alarm1.yaml
- packages/alarm-panel/alarm2.yaml
####
# WARNING BEEP
# Enables a 'Warning Beep' entity, intended to be used with a piezo buzzer or other pulsing.
# binary output This is implemented using the light component with strobe effect to create a
# repeated beeping sound or pulsing action that can be turned on via the _strobe_ effect.
- packages/warning-beep.yaml
######### Exposed to HA ##########
# sensor.alarm_state
# - disarmed
# - arming
# - armed_away
# - armed_home
# - armed_night
# - pending
# - triggered
# service.esphome_${name}_arm
# service.esphome_${name}_arm_away
# service.esphome_${name}_disarm
# data:
# code: "XXXXXXX"
##################################
switch:
- platform: template
name: ${friendly_name} Trigger Siren
id: trigger_siren
icon: mdi:bullhorn
optimistic: true
entity_category: config
restore_mode: RESTORE_DEFAULT_OFF
binary_sensor:
# Customize the name and device_class of input zones
# to mirror the traditional alarm panel
- id: !extend zone3
name: Front door
on_state:
then:
- script.execute: evaluate_alarm
- id: !extend zone4
name: Games room
on_state:
then:
- script.execute: evaluate_alarm
- id: !extend zone5
name: Kitchen
on_state:
then:
- script.execute: evaluate_alarm
- id: !extend zone6
name: 1st floor
on_state:
then:
- script.execute: evaluate_alarm
- id: !extend zone7
name: 2nd floor
on_state:
then:
- script.execute: evaluate_alarm
####
# STATE MACHINE
# The logic of armed and disarmed states and transitions is defined here
external_components:
source: github://muxa/esphome-state-machine
components:
- state_machine
state_machine:
diagram: mermaid
initial_state: 'disarmed'
states:
- name: 'disarmed'
- name: 'arming'
on_enter:
- light.turn_on:
id: warning_beep_1
effect: strobe
- delay: !lambda return id(arming_timeout).state * 1000;
- state_machine.transition: arm_away
on_leave:
- light.turn_off: warning_beep_1
- name: 'armed_away'
- name: 'armed_home'
- name: 'armed_night'
- name: 'pending'
on_enter:
- light.turn_on:
id: warning_beep_1
effect: strobe
- delay: !lambda return id(pending_timeout).state * 1000;
- state_machine.transition: trigger
on_leave:
- light.turn_off: warning_beep_1
- name: 'triggered'
on_enter:
- if:
condition:
switch.is_on: trigger_siren
then:
- switch.turn_on: alarm1
- light.turn_on:
id: warning_beep_1
effect: strobe
- delay: !lambda return id(trigger_timeout).state * 60 * 1000;
- state_machine.transition: arm_away
on_leave:
- switch.turn_off: alarm1
- light.turn_off: warning_beep_1
inputs:
- name: arm_away
transitions:
- disarmed -> arming
- arming -> armed_away
- triggered -> armed_away
- name: arm_home
transitions:
- disarmed -> armed_home
- name: arm_night
transitions:
- disarmed -> armed_night
- name: disarm
transitions:
- arming -> disarmed
- armed_away -> disarmed
- armed_home -> disarmed
- armed_night -> disarmed
- pending -> disarmed
- triggered -> disarmed
- name: toggle
transitions:
- arming -> disarmed
- armed_away -> disarmed
- armed_home -> disarmed
- armed_night -> disarmed
- pending -> disarmed
- triggered -> disarmed
- disarmed -> arming
- name: trip
transitions:
- armed_away -> pending
- armed_home -> pending
- armed_night -> pending
- name: trigger
transitions:
- armed_away -> triggered
- armed_home -> triggered
- armed_night -> triggered
- pending -> triggered
script:
- id: evaluate_alarm
then:
- if:
condition:
and:
- or:
- state_machine.state: armed_away
- state_machine.state: armed_home
- state_machine.state: armed_night
- or:
# - lambda: return id(zone1).state;
# - lambda: return id(zone2).state;
- lambda: return id(zone3).state;
- lambda: return id(zone4).state;
- lambda: return id(zone5).state;
- lambda: return id(zone6).state;
- lambda: return id(zone7).state;
# - lambda: return id(zone8).state;
then:
- state_machine.transition: trip
globals:
- id: alarm_state_global
type: 'uint8_t'
restore_value: true
initial_value: '0'
- id: incorrect_codes
type: 'uint8_t'
restore_value: true
initial_value: '0'
sensor:
- platform: template
id: alarm_state
update_interval: 1s
lambda: return id(alarm_state_global);
filters:
- delta: 1
on_value:
- text_sensor.template.publish:
id: alarm_state_text
state: !lambda |-
static std::array<std::string, 7> strings = ${state_strings};
int y = (int) x;
return strings[y];
- platform: template
id: incorrect_codes_sensor
name: '${friendly_name} Incorrect Codes'
lambda: return id(incorrect_codes);
update_interval: never
text_sensor:
- platform: state_machine
id: alarm_state_text
name: ${friendly_name} State
- platform: template
id: ready_state
name: ${friendly_name} Ready
disabled_by_default: true
button:
- platform: template
name: Arm Away
on_press:
then:
- state_machine.transition: arm_away
- platform: template
name: Disarm
on_press:
then:
- state_machine.transition: disarm
number:
- platform: template
id: arming_timeout
name: ${friendly_name} Arming Timeout
restore_value: true
initial_value: 60
unit_of_measurement: seconds
min_value: 0
max_value: 300
step: 1
mode: box
optimistic: true
entity_category: config
- platform: template
id: pending_timeout
name: ${friendly_name} Pending Timeout
restore_value: true
initial_value: 60
unit_of_measurement: seconds
min_value: 0
max_value: 300
step: 1
mode: box
optimistic: true
entity_category: config
- platform: template
id: trigger_timeout
name: ${friendly_name} Trigger Timeout
restore_value: true
initial_value: 5
unit_of_measurement: minutes
min_value: 1
max_value: 20
step: 1
mode: box
optimistic: true
entity_category: config
dashboard_import:
package_import_url: github://konnected-io/konnected-esphome/alarm-panel-pro-esp32-wifi.yaml@master
import_full_config: false
####
# WEB SEVER
# Enables the built-in web server for viewing the device state, internals and controls via web browser
# on the same local network as the device.
web_server:
include_internal: true
####
# LOGGER
# more: https://esphome.io/components/logger.html
logger:
wiegand:
- id: mykeypad
d0: $zone1
d1: $zone2
on_key:
- lambda: ESP_LOGI("KEY", "received key %d", x);
on_tag:
- lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
on_raw:
- lambda: ESP_LOGI("RAW", "received raw %d bits, value %llx", bits, value);
key_collector:
- id: pincode_reader
source_id: mykeypad
min_length: 4
max_length: 4
end_keys: "#"
end_key_required: true
clear_keys: "*"
allowed_keys: "0123456789"
timeout: 5s
on_progress:
- logger.log:
format: "input progress: '%s', started by '%c'"
args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
on_result:
- logger.log:
format: "input result: '%s', started by '%c', ended by '%c'"
args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ]
- if:
condition:
lambda: return strcmp(x.c_str(), "${alarm_code}") == 0;
then:
- lambda: id(incorrect_codes) = 0;
- state_machine.transition: toggle
else:
- lambda: id(incorrect_codes) += 1;
- if:
condition:
lambda: return id(incorrect_codes) >= 3;
then:
- state_machine.transition: trigger
on_timeout:
- logger.log:
format: "input timeout: '%s', started by '%c'"
args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
api:
encryption:
key: !secret encryption_key
services:
- service: arm
then:
- state_machine.transition: arm
- service: disarm
variables:
code: string
then:
- if:
condition:
lambda: return code == "${alarm_code}";
then:
- state_machine.transition: disarm
@tboby
Copy link
Author

tboby commented Jan 28, 2025

@tboby
Copy link
Author

tboby commented Jan 30, 2025

Made an important edit: actually triggering the alarm. The konnected sample didn't seem to actually hook up the script to any conditions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment