I built an ESPHome keypad for Alarmo, using a nodeMCU and a TM1638 display, both from Amazon at a cost of about $10. Here is a pic:
Buttons 1 and 2 arm the system; button 3 calls for a PIN to be entered to disarm. The code uses the api to communicate with Alarmo, and could be modified to use other modes. I don’t use arm/disarm codes on my system, so the PIN (here 1234) is used only on the keypad. It could be sent to Alarmo in the data template if you use codes. Here is the code:
esphome:
name: alarmokeypad
platform: ESP8266
board: nodemcuv2
name_add_mac_suffix: false
on_boot:
then:
- lambda: id(pin_entry).publish_state(false);
- lambda: id(pin).publish_state("");
logger:
api:
id: api_server
ota:
improv_serial:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
captive_portal:
web_server:
display:
platform: tm1638
id: tm1638_display
stb_pin: D7
clk_pin: D5
dio_pin: D2
intensity: 4
update_interval: 100ms
lambda: |-
it.print (" ");
it.print (id(print_status).state.c_str());
text_sensor:
- platform: homeassistant
entity_id: "alarm_control_panel.alarmo"
id: alarm_status
- platform: template
id: pin
update_interval: 100ms
on_value:
- if:
condition:
- lambda: "return id(pin).state.length() > 7;"
then:
- if:
condition: # correct PIN is entered
- lambda: |-
return id(pin).state.substr(4,4) == "1234";
then:
- homeassistant.service:
service: alarm_control_panel.alarm_disarm
data_template:
entity_id: alarm_control_panel.alarmo
- lambda: |-
id(pin_entry).publish_state(false);
id(pin).publish_state("");
else:
- lambda: |-
id(pin).publish_state("PIN?");
- platform: template
id: print_status
lambda: |-
if (id(pin_entry).state == true) {
return id(print_status).state = id(pin).state;
}
else if (id(alarm_status).state == "disarmed") {
return id(print_status).state = "DISARMED";
}
else if (id(alarm_status).state == "armed_home") {
return id(print_status).state = "ARM HOME";
}
else if (id(alarm_status).state == "armed_away") {
return id(print_status).state = "ARM AWAY";
}
else if (id(alarm_status).state == "arming") {
return id(print_status).state = "ARMING";
}
else if (id(alarm_status).state == "pending") {
return id(print_status).state = "PENDING";
}
else if (id(alarm_status).state == "triggered") {
return id(print_status).state = "TRIGGER";
}
else return id(print_status).state = "";
update_interval: 100ms
binary_sensor:
- platform: template
id: pin_entry
- platform: tm1638
# button will arm home or add 1 to pin
name: "TM1638 Button 1"
id: TM1638Button1
key: 0
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led1
- lambda: |-
id(pin).publish_state(id(pin).state + "1");
else:
- switch.turn_on: TM1638Led1
- homeassistant.service:
service: alarm_control_panel.alarm_arm_home
data_template:
entity_id: alarm_control_panel.alarmo
on_release:
then:
- switch.turn_off: TM1638Led1
- platform: tm1638
#button will arm away or add 2 to pin
name: "TM1638 Button 2"
id: TM1638Button2
key: 1
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led2
- lambda: |-
id(pin).publish_state(id(pin).state + "2");
else:
- switch.turn_on: TM1638Led2
- homeassistant.service:
service: alarm_control_panel.alarm_arm_away
data_template:
entity_id: alarm_control_panel.alarmo
on_release:
then:
- switch.turn_off: TM1638Led2
- platform: tm1638
# button will change to pin entry or add 3 to pin
name: "TM1638 Button 3"
id: TM1638Button3
key: 2
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led3
- lambda: |-
id(pin).publish_state(id(pin).state + "3");
else:
- switch.turn_on: TM1638Led3
- if:
condition:
- lambda: |-
return id(alarm_status).state == "disarmed";
then:
else:
- lambda: |-
id(pin_entry).publish_state(true);
id(pin).publish_state("PIN?");
on_release:
then:
- switch.turn_off: TM1638Led3
- platform: tm1638
name: "TM1638 Button 4"
id: TM1638Button4
key: 3
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led4
- lambda: |-
id(pin).publish_state(id(pin).state + "4");
else:
- switch.turn_on: TM1638Led4
on_release:
then:
- switch.turn_off: TM1638Led4
- platform: tm1638
name: "TM1638 Button 5"
id: TM1638Button5
key: 4
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led5
- lambda: |-
id(pin).publish_state(id(pin).state + "5");
else:
- switch.turn_on: TM1638Led5
on_release:
then:
- switch.turn_off: TM1638Led5
- platform: tm1638
name: "TM1638 Button 6"
id: TM1638Button6
key: 5
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led6
- lambda: |-
id(pin).publish_state(id(pin).state + "6");
else:
- switch.turn_on: TM1638Led6
on_release:
then:
- switch.turn_off: TM1638Led6
- platform: tm1638
name: "TM1638 Button 7"
id: TM1638Button7
key: 6
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led7
- lambda: |-
id(pin).publish_state(id(pin).state + "7");
else:
- switch.turn_on: TM1638Led7
on_release:
then:
- switch.turn_off: TM1638Led7
- platform: tm1638
name: "TM1638 Button 8"
id: TM1638Button8
key: 7
filters:
- delayed_on: 10ms
on_press:
- if:
condition:
- lambda: "return id(pin_entry).state == true;"
then:
- switch.turn_on: TM1638Led8
- lambda: |-
id(pin).publish_state(id(pin).state + "8");
else:
- switch.turn_on: TM1638Led8
on_release:
then:
- switch.turn_off: TM1638Led8
switch:
- platform: tm1638
id: TM1638Led1
led: 0
- platform: tm1638
id: TM1638Led2
led: 1
- platform: tm1638
id: TM1638Led3
led: 2
- platform: tm1638
id: TM1638Led4
led: 3
- platform: tm1638
id: TM1638Led5
led: 4
- platform: tm1638
id: TM1638Led6
led: 5
- platform: tm1638
id: TM1638Led7
led: 6
- platform: tm1638
id: TM1638Led8
led: 7