Hello, this project is about connecting Jablotron alarm JA-107 over Jablotron RS485 interface JA-121T wirelesly connected to HA over ESPhome (wifi).
You can find other “project” for connecting alarm main unit directly (over USB) to HA. I think, that JA-121T is more secure and wireless, but with limited options. GitHub - kukulich/home-assistant-jablotron100: Home Assistant custom component for JABLOTRON 100+ alar
I share this, because this can help to someone or someone can make this code better.
What is working:
- Read stale of zones (armed/ready/other…) [text sensor]
- Set and Unset armed state [two switches]
- Read PGS [binary sensors]
- Set PGs [switch] (un/set confirmed by binary sensor)
- very limited ability to read some periphery state
Hardware:
Please use ESP32 because of hardware UARTs and serial converter TTL (3.3V) to RS485 (from china).
This assume that you have installed ESPhome addon and you have read information about custom components. (Custom Sensor Component — ESPHome)
First you need to put C file to your ESPhome directory /config/ esphome/esp32-alarm
#include "esphome.h"
#include <vector>
#include <sstream>
#include <bitset>
using namespace std;
//please read notes in .yaml file
class JA121T : public Component, public UARTDevice {
public:
JA121T(UARTComponent *parent) : UARTDevice(parent) {}
void setup() override {
// This will be called by App.setup()
}
//Sensors
TextSensor *received_line = new TextSensor();
TextSensor *version = new TextSensor();
TextSensor *error = new TextSensor();
//PG[0] is not used
TextSensor * PG[11] = { new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor() };
//STATE[0] is not used
TextSensor * STATE[11] = { new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor() };
//PRFSTATE[0] is used
/*
TextSensor * PRFSTATE[64] = { new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor(),
new TextSensor(), new TextSensor(), new TextSensor(), new TextSensor() };
*/
vector<string> split (const string &s, char delim) {
vector<string> result;
stringstream ss (s);
string item;
while (getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
int readline(int readch, char *buffer, int len)
{
static int pos = 0;
int rpos;
if (readch > 0) {
switch (readch) {
case '\n': // Ignore new-lines
break;
case '\r': // Return on CR
rpos = pos;
pos = 0; // Reset position index ready for next time
return rpos;
default:
if (pos < len-1) {
buffer[pos++] = readch;
buffer[pos] = 0;
}
}
}
// No end of line has been found, so return -1.
return -1;
}
void loop() override {
const int max_line_length = 80;
static char buffer[max_line_length];
while (available()) {
if(readline(read(), buffer, max_line_length) > 0) {
// nacteny radek v bufferu (jeden, bez "\n")
string line(buffer); //convert to string
received_line->publish_state(line); // publish line
vector<string> data = split (line+" ", ' ');
//ESP_LOGD("JA121T", "Data: '%s' '%s' '%s'", data[0].c_str(), data[1].c_str(), data[2].c_str());
//Version
if (data[0].compare("JA-121T,") == 0) {
ESP_LOGD("JA121T", "Version: %s", line.c_str());
version->publish_state(line);
}
//OK
if (data[0].compare("OK") == 0) {
ESP_LOGD("JA121T", "> OK");
error->publish_state("0");
}
//ERROR
if (data[0].compare("ERROR") == 0) {
ESP_LOGD("JA121T", "> ERROR");
error->publish_state("1");
}
//PGs
if (data[0].compare("PG") == 0) {
//ESP_LOGD("JA121T", "> PG");
int pg=atoi( data[1].c_str() );
//ESP_LOGD("JA121T", "pg= %i", pg);
int size=(sizeof(PG)/sizeof(*PG));
//ESP_LOGD("JA121T", "size= %i", size);
if (pg<size) {
//ESP_LOGD("JA121T", "> - %i", pg);
ESP_LOGD("JA121T", "> PG %i is %s", pg, data[2].c_str());
if (data[2].compare("OFF") == 0) {
PG[pg]->publish_state("0");
}
if (data[2].compare("ON") == 0) {
PG[pg]->publish_state("1");
}
}
else
{
ESP_LOGD("JA121T", "PG %i out of array", pg);
}
}
//STATE
if (data[0].compare("STATE") == 0) {
int state=atoi( data[1].c_str() );
//ESP_LOGD("JA121T", "state= %i", state);
int size=(sizeof(STATE)/sizeof(*STATE));
//ESP_LOGD("JA121T", "size= %i", size);
if (state<size) {
//ESP_LOGD("JA121T", "> - %i", state);
ESP_LOGD("JA121T", "> STATE %i is %s",state,data[2].c_str());
STATE[state]->publish_state(data[2].c_str());
if (data[2].compare("READY") == 0) {
}
if (data[2].compare("ARMED") == 0) {
}
if (data[2].compare("ARMED_PART") == 0) {
}
if (data[2].compare("MAINTENANCE") == 0) {
}
if (data[2].compare("SERVICE") == 0) {
}
if (data[2].compare("BLOCKED") == 0) {
}
if (data[2].compare("OFF") == 0) {
}
}
else
{
ESP_LOGD("JA121T", "STATE %i out of array", state);
}
}
//PRFSTATE
if (data[0].compare("PRFSTATE") == 0) {
for (int i = 0; i < 8; i++) { //8x8=64 perif.
string one="0x"+data[1].substr (i*2,2); //each char of responce from left
stringstream ss;
ss << hex << one;
unsigned n;
ss >> n;
bitset<8> b(n);
ESP_LOGD("JA121T", "> Decoded byte %i: %s",i,b.to_string().c_str());
/*
for (int j = 0; j < 8; j++) {
if (b[j] >0) {
ESP_LOGD("JA121T", "> Perif %i = 1",(j+(i*8)));
PRFSTATE[j+(i*8)]->publish_state("1");
}
else{
PRFSTATE[j+(i*8)]->publish_state("0");
}
}
*/
}
}
}
}
}
};
This code creates component JA121T (with UART defined in .yaml). Commented lines (PRFSTATE) are for periphery state (but when you uncommented all, ESP is not 100% stable - wifi log connection problems).
Receiver line from Jablotron protocol is in “received_line” text sensor (please disable this sensor in logger). When you UN/ARM or change PGs alarm send new line automaticaly and values are decodes and saved in arrays PG[] and STATE[] (index 0 is not used, because of Jablotron terminoligy).
If you want more PGs or Zones make a array larger (code detects array size).
Definiton for ESPhome (.yaml file)
esphome:
name: esp32-alarm
platform: ESP32
board: esp32dev
includes:
- esp32-alarm/src/ja121t.h
#NOTES:
#this is overkill for esphome (many ensors)
#do not try ESP8266
#if you use (max) 64 pheriphery, you "can" read it by textsensor (commented),
# but is impossible to convert it to binary sensor like PGs. If you try it ESP don't
# boot/log to wifi/home assistant/no connection for log
#There is probubly some way to use array in yaml, but I cannot fing informations.
# Enable logging
logger:
hardware_uart: UART0
# Enable Home Assistant API
api:
ota:
password: "#####################"
wifi:
ssid: "#####################"
password: "#####################"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp32-Alarm Fallback Hotspot"
password: "#####################"
captive_portal:
globals:
# For PGs switches
- id: PG001_g
type: bool
initial_value: "0"
- id: PG002_g
type: bool
initial_value: "0"
- id: PG003_g
type: bool
initial_value: "0"
- id: PG004_g
type: bool
initial_value: "0"
- id: PG005_g
type: bool
initial_value: "0"
- id: PG006_g
type: bool
initial_value: "0"
- id: PG007_g
type: bool
initial_value: "0"
- id: PG008_g
type: bool
initial_value: "0"
- id: PG009_g
type: bool
initial_value: "0"
- id: PG010_g
type: bool
initial_value: "0"
uart:
tx_pin: GPIO17 #TX2
rx_pin: GPIO16 #RX2
baud_rate: 9600
id: uart_bus
switch:
- platform: template
name: "JA100-Read version"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: 'VER'
#SET
- platform: template
name: "JA100-SET01"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 1'
- platform: template
name: "JA100-SET02"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 2'
- platform: template
name: "JA100-SET03"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 3'
- platform: template
name: "JA100-SET04"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 4'
- platform: template
name: "JA100-SET05"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 5'
- platform: template
name: "JA100-SET06"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 6'
- platform: template
name: "JA100-SET07"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 7'
- platform: template
name: "JA100-SET08"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 8'
- platform: template
name: "JA100-SET09"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 9'
- platform: template
name: "JA100-SET10"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### SET 10'
#UNSET
- platform: template
name: "JA100-UNSET01"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 1'
- platform: template
name: "JA100-UNSET02"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 2'
- platform: template
name: "JA100-UNSET03"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 3'
- platform: template
name: "JA100-UNSET04"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 4'
- platform: template
name: "JA100-UNSET05"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 5'
- platform: template
name: "JA100-UNSET06"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 6'
- platform: template
name: "JA100-UNSET07"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 7'
- platform: template
name: "JA100-UNSET08"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 8'
- platform: template
name: "JA100-UNSET09"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 9'
- platform: template
name: "JA100-UNSET10"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: '###CODE### UNSET 10'
#Commands
- platform: template
name: "JA100-Read states"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: 'STATE'
- platform: template
name: "JA100-Read PGs"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: 'PGSTATE 1 2 3 4 5 6 7 8 9 10' #this (and array in .h) limit number of PGs
- platform: template
name: "JA100-Read periphery states"
icon: mdi:play
lambda: |-
return false;
turn_on_action:
- uart.write: 'PRFSTATE'
#PG
- platform: template
name: "JA100-PG001"
icon: mdi:toggle-switch
lambda: |-
if (id(PG001_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 1'
- globals.set:
id: PG001_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 1'
- globals.set:
id: PG001_g
value: '0'
- platform: template
name: "JA100-PG002"
icon: mdi:toggle-switch
lambda: |-
if (id(PG002_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 2'
- globals.set:
id: PG002_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 2'
- globals.set:
id: PG002_g
value: '0'
- platform: template
name: "JA100-PG003"
icon: mdi:toggle-switch
lambda: |-
if (id(PG003_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 3'
- globals.set:
id: PG003_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 3'
- globals.set:
id: PG003_g
value: '0'
- platform: template
name: "JA100-PG004"
icon: mdi:toggle-switch
lambda: |-
if (id(PG004_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 4'
- globals.set:
id: PG004_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 4'
- globals.set:
id: PG004_g
value: '0'
- platform: template
name: "JA100-PG005"
icon: mdi:toggle-switch
lambda: |-
if (id(PG005_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 5'
- globals.set:
id: PG005_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 5'
- globals.set:
id: PG005_g
value: '0'
- platform: template
name: "JA100-PG006"
icon: mdi:toggle-switch
lambda: |-
if (id(PG006_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 6'
- globals.set:
id: PG006_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 6'
- globals.set:
id: PG006_g
value: '0'
- platform: template
name: "JA100-PG007"
icon: mdi:toggle-switch
lambda: |-
if (id(PG007_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 7'
- globals.set:
id: PG007_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 7'
- globals.set:
id: PG007_g
value: '0'
- platform: template
name: "JA100-PG008"
icon: mdi:toggle-switch
lambda: |-
if (id(PG008_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 8'
- globals.set:
id: PG008_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 8'
- globals.set:
id: PG008_g
value: '0'
- platform: template
name: "JA100-PG009"
icon: mdi:toggle-switch
lambda: |-
if (id(PG009_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 9'
- globals.set:
id: PG009_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 9'
- globals.set:
id: PG009_g
value: '0'
- platform: template
name: "JA100-PG010"
icon: mdi:toggle-switch
lambda: |-
if (id(PG010_g)) {
return true;
} else {
return false;
}
turn_on_action:
- uart.write: '###CODE### PGON 10'
- globals.set:
id: PG010_g
value: '1'
turn_off_action:
- uart.write: '###CODE### PGOFF 10'
- globals.set:
id: PG010_g
value: '0'
text_sensor:
- platform: custom
lambda: |-
auto JA121 = new JA121T(id(uart_bus));
App.register_component(JA121);
return {JA121->received_line, JA121->version, JA121->error,
JA121->PG[1],JA121->PG[2],JA121->PG[3],JA121->PG[4],JA121->PG[5],JA121->PG[6],JA121->PG[7],JA121->PG[8],JA121->PG[9],JA121->PG[10],
JA121->STATE[1],JA121->STATE[2],JA121->STATE[3],JA121->STATE[4],JA121->STATE[5],JA121->STATE[6],JA121->STATE[7],JA121->STATE[8],JA121->STATE[9],JA121->STATE[10]};
# JA121->PRFSTATE[0],JA121->PRFSTATE[1],JA121->PRFSTATE[2],JA121->PRFSTATE[3],JA121->PRFSTATE[4],JA121->PRFSTATE[5],JA121->PRFSTATE[6],JA121->PRFSTATE[7],JA121->PRFSTATE[8],JA121->PRFSTATE[9],
# JA121->PRFSTATE[10],JA121->PRFSTATE[11],JA121->PRFSTATE[12],JA121->PRFSTATE[13],JA121->PRFSTATE[14],JA121->PRFSTATE[15],JA121->PRFSTATE[16],JA121->PRFSTATE[17],JA121->PRFSTATE[18],JA121->PRFSTATE[19],
# JA121->PRFSTATE[20],JA121->PRFSTATE[21],JA121->PRFSTATE[22],JA121->PRFSTATE[23],JA121->PRFSTATE[24],JA121->PRFSTATE[25],JA121->PRFSTATE[26],JA121->PRFSTATE[27],JA121->PRFSTATE[28],JA121->PRFSTATE[29],
# JA121->PRFSTATE[30],JA121->PRFSTATE[31],JA121->PRFSTATE[32],JA121->PRFSTATE[33],JA121->PRFSTATE[34],JA121->PRFSTATE[35],JA121->PRFSTATE[36],JA121->PRFSTATE[37],JA121->PRFSTATE[38],JA121->PRFSTATE[39],
# JA121->PRFSTATE[40],JA121->PRFSTATE[41],JA121->PRFSTATE[42],JA121->PRFSTATE[43],JA121->PRFSTATE[44],JA121->PRFSTATE[45],JA121->PRFSTATE[46],JA121->PRFSTATE[47],JA121->PRFSTATE[48],JA121->PRFSTATE[49],
# JA121->PRFSTATE[50],JA121->PRFSTATE[51],JA121->PRFSTATE[52],JA121->PRFSTATE[53],JA121->PRFSTATE[54],JA121->PRFSTATE[55],JA121->PRFSTATE[56],JA121->PRFSTATE[57],JA121->PRFSTATE[58],JA121->PRFSTATE[59],
# JA121->PRFSTATE[60],JA121->PRFSTATE[61],JA121->PRFSTATE[62],JA121->PRFSTATE[63]
text_sensors:
- name: "received_line"
icon: mdi:textlong
- name: "version"
icon: mdi:textshort
- name: "error"
- id: PG001_i
on_value:
- binary_sensor.template.publish:
id: PG001_t #turn binary sensor
state: !lambda 'return id(PG001_i).state == "1";'
- globals.set: #turn switch
id: PG001_g
value: !lambda 'return id(PG001_i).state == "1";'
- id: PG002_i
on_value:
- binary_sensor.template.publish:
id: PG002_t #turn binary sensor
state: !lambda 'return id(PG002_i).state == "1";'
- globals.set:
id: PG002_g #turn switch
value: !lambda 'return id(PG002_i).state == "1";'
- id: PG003_i
on_value:
- binary_sensor.template.publish:
id: PG003_t #turn binary sensor
state: !lambda 'return id(PG003_i).state == "1";'
- globals.set:
id: PG003_g #turn switch
value: !lambda 'return id(PG003_i).state == "1";'
- id: PG004_i
on_value:
- binary_sensor.template.publish:
id: PG004_t #turn binary sensor
state: !lambda 'return id(PG004_i).state == "1";'
- globals.set:
id: PG004_g #turn switch
value: !lambda 'return id(PG004_i).state == "1";'
- id: PG005_i
on_value:
- binary_sensor.template.publish:
id: PG005_t #turn binary sensor
state: !lambda 'return id(PG005_i).state == "1";'
- globals.set:
id: PG005_g #turn switch
value: !lambda 'return id(PG005_i).state == "1";'
- id: PG006_i
on_value:
- binary_sensor.template.publish:
id: PG006_t #turn binary sensor
state: !lambda 'return id(PG006_i).state == "1";'
- globals.set:
id: PG006_g #turn switch
value: !lambda 'return id(PG006_i).state == "1";'
- id: PG007_i
on_value:
- binary_sensor.template.publish:
id: PG007_t #turn binary sensor
state: !lambda 'return id(PG007_i).state == "1";'
- globals.set:
id: PG007_g #turn switch
value: !lambda 'return id(PG007_i).state == "1";'
- id: PG008_i
on_value:
- binary_sensor.template.publish:
id: PG008_t #turn binary sensor
state: !lambda 'return id(PG008_i).state == "1";'
- globals.set:
id: PG008_g #turn switch
value: !lambda 'return id(PG008_i).state == "1";'
- id: PG009_i
on_value:
- binary_sensor.template.publish:
id: PG009_t #turn binary sensor
state: !lambda 'return id(PG009_i).state == "1";'
- globals.set:
id: PG009_g #turn switch
value: !lambda 'return id(PG009_i).state == "1";'
- id: PG010_i
on_value:
- binary_sensor.template.publish:
id: PG010_t #turn binary sensor
state: !lambda 'return id(PG010_i).state == "1";'
- globals.set:
id: PG010_g #turn switch
value: !lambda 'return id(PG010_i).state == "1";'
#STATE
- name: "state01"
icon: mdi:security
- name: "state02"
icon: mdi:security
- name: "state03"
icon: mdi:security
- name: "state04"
icon: mdi:security
- name: "state05"
icon: mdi:security
- name: "state06"
icon: mdi:security
- name: "state07"
icon: mdi:security
- name: "state08"
icon: mdi:security
- name: "state09"
icon: mdi:security
- name: "state10"
icon: mdi:security
#PRFSTATE
# - name: "PRF000"
# - name: "PRF001"
# - name: "PRF002"
# - name: "PRF003"
# - name: "PRF004"
# - name: "PRF005"
# - name: "PRF006"
# - name: "PRF007"
# - name: "PRF008"
# - name: "PRF009"
# - name: "PRF010"
# - name: "PRF011"
# - name: "PRF012"
# - name: "PRF013"
# - name: "PRF014"
# - name: "PRF015"
# - name: "PRF016"
# - name: "PRF017"
# - name: "PRF018"
# - name: "PRF019"
# - name: "PRF020"
# - name: "PRF021"
# - name: "PRF022"
# - name: "PRF023"
# - name: "PRF024"
# - name: "PRF025"
# - name: "PRF026"
# - name: "PRF027"
# - name: "PRF028"
# - name: "PRF029"
# - name: "PRF030"
# - name: "PRF031"
# - name: "PRF032"
# - name: "PRF033"
# - name: "PRF034"
# - name: "PRF035"
# - name: "PRF036"
# - name: "PRF037"
# - name: "PRF038"
# - name: "PRF039"
# - name: "PRF040"
# - name: "PRF041"
# - name: "PRF042"
# - name: "PRF043"
# - name: "PRF044"
# - name: "PRF045"
# - name: "PRF046"
# - name: "PRF047"
# - name: "PRF048"
# - name: "PRF049"
# - name: "PRF050"
# - name: "PRF051"
# - name: "PRF052"
# - name: "PRF053"
# - name: "PRF054"
# - name: "PRF055"
# - name: "PRF056"
# - name: "PRF057"
# - name: "PRF058"
# - name: "PRF059"
# - name: "PRF060"
# - name: "PRF061"
# - name: "PRF062"
# - name: "PRF063"
binary_sensor:
#PG
- platform: template
id: PG001_t
name: "PG001"
- platform: template
id: PG002_t
name: "PG002"
- platform: template
id: PG003_t
name: "PG003"
- platform: template
id: PG004_t
name: "PG004"
- platform: template
id: PG005_t
name: "PG005"
- platform: template
id: PG006_t
name: "PG006"
- platform: template
id: PG007_t
name: "PG007"
- platform: template
id: PG008_t
name: "PG008"
- platform: template
id: PG009_t
name: "PG009"
- platform: template
id: PG010_t
name: "PG010"
On the begining, includes file must point to previous C file “ja121t.h”.
Fill your passwords to “#####################” and set alarm user code to “###CODE###” (with prefix, if you use it). Set limited access for this user in alarm (only some zones and PGs).
I can’t find how to make C file to publish textsensors and binary sensors together, so this sensors are translated in ESPhome.
Global (PG00x_g) are for rememberig PGs switch states when changed form HA (and before are readed back from alarm).
Reading version of JA-121T, “ERROR” and “OK” is useless.
You can malually read zone states and PGs states (if you need more than 10, please edit line near “JA100-Read PGs”).
Use “SET” and “UNSET” switches for ARM/DISARM zomes.
Use “PG” switches and template binary sensors (PG00x_t) for control PGs.
If you chnaged arrays on C file, you need to change mapping on line where component is registered (orded of items have to be same).
Because of some limitations (probubly in ESPhome) is not possible to translate all PRFSTATE (pheriphery) to binary sensors.
You can translate zone states to your language in tempate sensor (configuration.yaml / sensors section)
- platform: template
sensors:
alarm_nahore:
friendly_name: Nahoře
value_template: >-
{% if is_state('sensor.state01', 'READY') %}
Odkódováno
{% elif is_state('sensor.state01', 'ARMED') %}
Zakódováno
{% elif is_state('sensor.state01', 'ARMED_PART') %}
Zak. částečně
{% elif is_state('sensor.state01', 'MAINTENANCE') %}
Údržba
{% elif is_state('sensor.state01', 'SERVICE') %}
Seervis
{% elif is_state('sensor.state01', 'BLOCKED') %}
Blokováno
{% elif is_state('sensor.state01', 'OFF') %}
Nepoužito
{% else %}
Neznámý
{% endif %}
When you turn system on and state of zones is not known, you can use automation to read it: (automations.yaml)
- id: '##########'
alias: G Alarm Reload States
description: ''
trigger:
- platform: time_pattern
minutes: /1
condition:
- condition: or
conditions:
- condition: state
entity_id: sensor.alarm_nahore
state: Neznámý
- condition: state
entity_id: sensor.alarm_dole
state: Neznámý
# add more zones
action:
- service: switch.turn_on
target:
entity_id: switch.ja100_read_states
Here is example of automation whitch waits for confirmed un/lock of zone:
- id: '##########'
alias: Open garage doors
description: ''
trigger:
- platform: state
entity_id: binary_sensor.some_remote
to: 'on'
from: 'off'
condition: []
action:
- choose:
- alias: If is locked than unlock and open
conditions:
- condition: template
value_template: '{{ states(''sensor.state01'') != ''READY'' }}'
sequence:
- service: switch.turn_on
target:
entity_id: switch.ja100_unset01
- alias: Wait for unlock
wait_template: '{{ states(''sensor.state01'') == ''READY'' }}'
timeout: 00:00:10
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.completed }}'
sequence:
- service: switch.turn_on
target:
entity_id: switch.door_opener
default:
- service: .... do something when fails to disarm
mode: single