Hello,
for those who wants a keycode to arm and disarm alarms like for example Xiaomi Gateways, here is the complete working code.
i have the Arduino IDE version, i have adapt to MQTT to integrate into HA,
and yesterday i have adapt the code for ESPHOME with HA API, here is the complete and functionnal code if someone is interested to work in progress…not perfect…but works : need to push the codelock on the touchscreen until the X symbol is draw on the screen for each digit, basicly 4 digits, you can change with “codenum” variable in globals: section of the file. Enjoy!
2 things to do first :
- 1 is to create a “input_boolean.digicode_arm” in HA to trigger an automation to put alarm on and off
- 2 create an automation that will be triggered with the input_boolean above and will activate the alarm(s) entity(entities).
i use the ILI9341 with xpt2046 touchscreen 3.2" and a ESP32S, dont work with a ESP8266.
Need a photoresistor + resistor of 10KOmhs and a buzzer (piezo) + a 220Ohms resistor + a BC337 or similar transistor.
esphome:
name: digicode
esp32:
board: esp-wrover-kit
framework:
type: arduino
logger:
# level: VERBOSE
wifi:
ssid: "XXXXXXXXXXXXXXXXX"
password: "xXxxxXxxxxXxxxxXXXxxxxx"
manual_ip:
static_ip: 192.168.X.XX
gateway: 192.168.X.X
subnet: 255.255.255.0
dns1: 192.168.X.X
fast_connect: on
power_save_mode: none
# Enable Home Assistant API
api:
services:
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
ota:
password: "XXXXxxxxxXXXX"
spi:
clk_pin: 19
mosi_pin: 23
miso_pin: 25
globals:
- id: counter_key
type: int
restore_value: no
initial_value: '0'
- id: number_new
type: int
restore_value: no
initial_value: '0000'
- id: codenum
type: int
restore_value: no
initial_value: '2581'
- id: value_key
type: int
restore_value: no
initial_value: '0'
- id: variable_a
type: int
restore_value: no
initial_value: '0'
- id: variable_b
type: int
restore_value: no
initial_value: '0'
- id: variable_c
type: int
restore_value: no
initial_value: '0'
- id: variable_d
type: int
restore_value: no
initial_value: '0'
font:
- file: "arial.ttf"
id: arial
size: 10
- file: "arial.ttf"
id: arialB
size: 20
- file: "theboldfont.ttf"
id: bold
size: 10
- file: "theboldfont.ttf"
id: boldf
size: 20
- file: "theboldfont.ttf"
id: boldf2
size: 15
- file: "theboldfont.ttf"
id: boldff
size: 40
- file: "theboldfont.ttf"
id: boldf3
size: 30
time:
- platform: homeassistant
id: time_ha
timezone: UTC-4
binary_sensor:
- platform: status
name: "Status Wifi Digicode ILI9341"
id: etatwdigicodeili9341
- platform: homeassistant
id: somebody_home
entity_id: binary_sensor.somebody_home
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_7
x_min: 0
x_max: 80
y_min: 64
y_max: 128
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 7;
ESP_LOGI("TAG", "touch_7 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_4
x_min: 0
x_max: 80
y_min: 128
y_max: 192
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 4;
ESP_LOGI("TAG", "touch_4 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_1
x_min: 0
x_max: 80
y_min: 192
y_max: 256
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 1;
ESP_LOGI("TAG", "touch_1 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_c
x_min: 0
x_max: 80
y_min: 256
y_max: 320
on_press:
- lambda: |-
ESP_LOGI("TAG", "touch_c touched=%i", (int) id(touchscreen).touched );
id(variable_a) = id(variable_b) = id(variable_c) = id(variable_d) = 0;
id(number_new) = 0;
id(counter_key) = 0;
- rtttl.play: "two short:d=4,o=5,b=100:16e6,16e6"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_8
x_min: 80
x_max: 160
y_min: 64
y_max: 128
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 8;
ESP_LOGI("TAG", "touch_8 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_5
x_min: 80
x_max: 160
y_min: 128
y_max: 192
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 5;
ESP_LOGI("TAG", "touch_5 /Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_2
x_min: 80
x_max: 160
y_min: 192
y_max: 256
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 2;
ESP_LOGI("TAG", "touch_2 / Le compteur est a : %i", id(counter_key));
- rtttl.play: 'beep:d=16,o=5,b=100:b'
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_0
x_min: 80
x_max: 160
y_min: 256
y_max: 320
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 0;
ESP_LOGI("TAG", "touch_0 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_9
x_min: 160
x_max: 240
y_min: 64
y_max: 128
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 9;
ESP_LOGI("TAG", "touch_9 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_6
x_min: 160
x_max: 240
y_min: 128
y_max: 192
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 6;
ESP_LOGI("TAG", "touch_6 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_3
x_min: 160
x_max: 240
y_min: 192
y_max: 256
on_press:
- lambda: |-
id(counter_key) += 1;
id(value_key) = 3;
ESP_LOGI("TAG", "touch_3 / Le compteur est a : %i", id(counter_key));
- rtttl.play: "beep:d=16,o=5,b=100:b"
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_ok
x_min: 160
x_max: 240
y_min: 256
y_max: 320
on_press:
- lambda: |-
ESP_LOGI("TAG", "touch_ok touched=%i", (int) id(touchscreen).touched );
switch:
- platform: restart
name: "Restart Digicode ili9341"
- platform: template
id: rtttl_code_ok
name: RTTTL Two Short Code Ok
turn_on_action:
- rtttl.play: "long:d=10,o=5,b=100:b,g,a"
- platform: template
id: rtttl_code_error
name: RTTTL Two Short Code Error
turn_on_action:
- rtttl.play: "two short:d=4,o=5,b=100:16e6,16e6"
- platform: template
id: display_page2
name: Display page2
internal: true
turn_on_action:
- display.page.show: page2
- platform: template
id: display_page1
name: Display page1
internal: true
turn_on_action:
- display.page.show: page1
color:
- id: my_red
red: 100%
green: 15%
blue: 5%
- id: my_green
red: 0%
green: 100%
blue: 0%
- id: my_blue
red: 0%
green: 0%
blue: 100%
- id: my_white
red: 100%
green: 100%
blue: 100%
sensor:
- platform: wifi_signal
name: "WiFi Signal Digicode ili9341"
update_interval: 60s
id: signalwdigicodeili9341
- platform: adc
pin: 34
name: "Luminosite Digicode Ili9341"
id: illumination_digicode_ili9341
unit_of_measurement: lux
update_interval: 1s
filters:
- lambda: return (( x * 3.3 / 10000.0) * 3000000.0);
on_value:
then:
- light.turn_on:
id: back_light_digicode_ili9341
brightness: !lambda |-
return id(illumination_digicode_ili9341).state / 700.0;
text_sensor:
- platform: homeassistant
id: date_simple
entity_id: sensor.date_simple
internal: true
- platform: homeassistant
id: uptime_ha
entity_id: sensor.uptime_ha
internal: true
- platform: template
id: text_sensor_arm
on_value:
then:
- if:
condition:
lambda: 'return id(text_sensor_arm).state =="on";'
then:
- homeassistant.service:
service: input_boolean.turn_on
data:
entity_id: input_boolean.digicode_arm
else:
- homeassistant.service:
service: input_boolean.turn_off
data:
entity_id: input_boolean.digicode_arm
output:
- platform: ledc
pin: 5
id: gpio_32_backlight_pwm
- platform: ledc
pin: GPIO21
id: rtttl_out
rtttl:
output: rtttl_out
on_finished_playback:
- logger.log: 'Song ended!'
light:
- platform: monochromatic
output: gpio_32_backlight_pwm
name: "Display Backlight Digicode Ili9341"
id: back_light_digicode_ili9341
restore_mode: ALWAYS_ON
xpt2046:
id: touchscreen
cs_pin: 17
irq_pin: 16
update_interval: 50ms
report_interval: 1s
threshold: 600
dimension_x: 240
dimension_y: 320
calibration_x_min: 250
calibration_x_max: 3800
calibration_y_min: 3800
calibration_y_max: 365
swap_x_y: false
display:
- platform: ili9341
model: "TFT_2.4"
cs_pin: 32
dc_pin: 33
led_pin: 5
reset_pin: 26
rotation: 0
id: display_digicode_ili9341
pages:
- id: page1
lambda: |-
if ((id(illumination_digicode_ili9341).state < 100) | (!id(somebody_home).state)) {
auto call = id(back_light_digicode_ili9341).turn_off();
call.perform();
} else {
auto call = id(back_light_digicode_ili9341).turn_on();
call.perform();
it.strftime(20, 12, id(bold), TextAlign::BASELINE_LEFT, "%H : %M", id(time_ha).now());
it.strftime(150, 12, id(bold), TextAlign::BASELINE_LEFT, "%d . %m . %Y", id(time_ha).now());
it.strftime(90, 12, id(bold), TextAlign::BASELINE_LEFT, "%A", id(time_ha).now());
it.printf(10, 14, id(arial), "Wifi : %s", id(etatwdigicodeili9341).state ? "Online" : "Offline");
it.printf(72, 14, id(arial), " %.f", id(signalwdigicodeili9341).state);
it.printf(90, 14, id(arial), "dB");
it.printf(120, 14, id(arial), "Luminosite : %.f lux", id(illumination_digicode_ili9341).state);
it.line(0, 25, 240, 25, id(my_blue));
it.line(0, 26, 240, 26, id(my_blue));
it.line(0, 63, 240, 63, id(my_blue));
it.line(0, 64, 240, 64, id(my_blue));
it.line(0, 128, 240, 128, id(my_blue));
it.line(0, 192, 240, 192, id(my_blue));
it.line(0, 256, 240, 256, id(my_blue));
it.line(80, 64, 80, 320, id(my_blue));
it.line(160, 64, 160, 320, id(my_blue));
it.rectangle(0, 0, 240, 320, id(my_blue));
it.rectangle(1, 1, 238, 318, id(my_blue));
it.printf(30, 110, id(boldff), TextAlign::BASELINE_LEFT, "7");
it.printf(30, 175, id(boldff), TextAlign::BASELINE_LEFT, "4");
it.printf(30, 240, id(boldff), TextAlign::BASELINE_LEFT, "1");
it.printf(30, 305, id(boldff), id(my_red), TextAlign::BASELINE_LEFT, "C");
it.printf(110, 110, id(boldff), TextAlign::BASELINE_LEFT, "8");
it.printf(110, 175, id(boldff), TextAlign::BASELINE_LEFT, "5");
it.printf(110, 240, id(boldff), TextAlign::BASELINE_LEFT, "2");
it.printf(110, 305, id(boldff), TextAlign::BASELINE_LEFT, "0");
it.printf(190, 110, id(boldff), TextAlign::BASELINE_LEFT, "9");
it.printf(190, 175, id(boldff), TextAlign::BASELINE_LEFT, "6");
it.printf(190, 240, id(boldff), TextAlign::BASELINE_LEFT, "3");
it.printf(170, 305, id(boldff), id(my_green), TextAlign::BASELINE_LEFT, "OK");
if (id(touch_ok).state) {
if (id(number_new) == id(codenum)) {
it.filled_rectangle(2, 27, 237, 36, id(my_green));
it.printf(35, 60, id(boldff), id(my_white), TextAlign::BASELINE_LEFT, "CODE OK");
id(rtttl_code_ok).turn_on();
id(display_page2).turn_on();
id(counter_key) = 0;
id(number_new) = 0;
}
else {
it.filled_rectangle(2, 27, 237, 36, id(my_red));
it.printf(20, 55, id(boldf3), id(my_white), TextAlign::BASELINE_LEFT, "!WRONG CODE!");
id(rtttl_code_error).turn_on();
id(counter_key) = 0;
id(variable_a) = id(variable_b) = id(variable_c) = id(variable_d) = 0;
}
}
if ((id(touch_0).state))
{
id(value_key) = 0;
}
else if ((id(touch_1).state))
{
id(value_key) = 1;
}
else if ((id(touch_2).state))
{
id(value_key) = 2;
}
else if ((id(touch_3).state))
{
id(value_key) = 3;
}
else if ((id(touch_4).state))
{
id(value_key) = 4;
}
else if ((id(touch_5).state))
{
id(value_key) = 5;
}
else if ((id(touch_6).state))
{
id(value_key) = 6;
}
else if ((id(touch_7).state))
{
id(value_key) = 7;
}
else if ((id(touch_8).state))
{
id(value_key) = 8;
}
else if ((id(touch_9).state))
{
id(value_key) = 9;
}
if ((id(counter_key) == 1))
{
id(variable_a) = id(value_key) * 1000;
id(number_new) = (id(variable_a) + id(variable_b) + id(variable_c) + id(variable_d));
it.printf(60, 60, id(boldff), TextAlign::BASELINE_LEFT, "%s", "X");
}
else if ((id(counter_key) == 2))
{
id(variable_b) = id(value_key) * 100;
id(number_new) = (id(variable_a) + id(variable_b) + id(variable_c) + id(variable_d));
it.printf(60, 60, id(boldff), TextAlign::BASELINE_LEFT, "%s", "XX");
}
else if ((id(counter_key) == 3))
{
id(variable_c) = id(value_key) * 10;
id(number_new) = (id(variable_a) + id(variable_b) + id(variable_c) + id(variable_d));
it.printf(60, 60, id(boldff), TextAlign::BASELINE_LEFT, "%s", "XXX");
}
else if ((id(counter_key) == 4))
{
id(variable_d) = id(value_key);
id(number_new) = (id(variable_a) + id(variable_b) + id(variable_c) + id(variable_d));
it.printf(60, 60, id(boldff), TextAlign::BASELINE_LEFT, "%s", "XXXX");
}
if (id(touch_c).state) {
it.printf(30, 60, id(boldff), TextAlign::BASELINE_LEFT, " ");
}
}
- id: page2
lambda: |-
if ((id(illumination_digicode_ili9341).state < 100) | (!id(somebody_home).state)) {
auto call = id(back_light_digicode_ili9341).turn_off();
call.perform();
} else {
auto call = id(back_light_digicode_ili9341).turn_on();
call.perform();
it.strftime(20, 12, id(bold), TextAlign::BASELINE_LEFT, "%H : %M", id(time_ha).now());
it.strftime(150, 12, id(bold), TextAlign::BASELINE_LEFT, "%d . %m . %Y", id(time_ha).now());
it.strftime(90, 12, id(bold), TextAlign::BASELINE_LEFT, "%A", id(time_ha).now());
it.printf(10, 14, id(arial), "Wifi : %s", id(etatwdigicodeili9341).state ? "Online" : "Offline");
it.printf(72, 14, id(arial), " %.f", id(signalwdigicodeili9341).state);
it.printf(90, 14, id(arial), "dB");
it.printf(120, 14, id(arial), "Luminosite : %.f lux", id(illumination_digicode_ili9341).state);
it.line(0, 25, 240, 25, id(my_blue));
it.line(0, 26, 240, 26, id(my_blue));
it.rectangle(0, 0, 240, 320, id(my_blue));
it.rectangle(1, 1, 238, 318, id(my_blue));
it.filled_rectangle(4, 63, 235, 60, id(my_red));
it.printf(60, 110, id(boldff), id(my_white), TextAlign::BASELINE_LEFT, "! ARM !");
it.filled_rectangle(4, 125, 235, 60, id(my_green));
it.printf(40, 170, id(boldff), id(my_white), TextAlign::BASELINE_LEFT, "!DISARM!");
it.filled_rectangle(4, 257, 80, 60, id(my_red));
it.printf(25, 295, id(arialB), id(my_white), TextAlign::BASELINE_LEFT, "Exit");
if (id(text_sensor_arm).state == "on") { it.printf(22, 210, id(arialB), id(my_white), "Alarm State: !ARMED!"); }
else if (id(text_sensor_arm).state == "off") { it.printf(5, 210, id(arialB), id(my_white), "Alarm State: !DISARMED!"); }
if ((id(touch_7).state) | (id(touch_8).state) | (id(touch_9).state))
{
id(text_sensor_arm).publish_state("on"); //create a input_boolean.digicode_arm in HA to trigger an automation to put alarm on
}
else if ((id(touch_4).state) | (id(touch_5).state) | (id(touch_6).state))
{
id(text_sensor_arm).publish_state("off"); //create input_boolean.digicode_arm in HA to trigger an automation to put alarm off
}
if (id(touch_c).state) {
id(display_page1).turn_on();
}
}
3D Print files : https://www.thingiverse.com/thing:5256800
GPIO21 in my ESPhome code, Vin of the ESP32 for 5V Vcc.
A diode can be add in parallel of the piezo for security (free wheel diode).
thats the light sensor part, cheap and simple way to adapt the brightness of a ILI9341…
Enjoy
UPDATE 27/03/2022 : i optimized the code, no more need to stay press on the numbers, just stay 2 second on OK or C key. I still try to improve the code…