RF door sensors reporting open at regular intervals
Opened this issue · 12 comments
Problem
I updated to the latest dev branch since I had some issues with the ESP32 disconnecting randomly after unexpected power loss and now I have a new problem. Basically, each door sensor will report to home assistant that it has been opened when it has not every 72 minutes or so since the last time it falsely reported it. Maybe something to do with rfSerialLookup
? I do like this new feature though.
Platform
Vista-20P, 6150RF, 6x 5816WMWH, ESP32, Home Assistant 2023.2.3
Config
#for documentation see project at https://github.com/Dilbert66/esphome-VistaECP
substitutions:
systemName: "vistaalarm"
accessCode: !secret access_code #Only comes into effect if needed for arming and quickarm is not set
maxZones: "48" #maximum amount of zones that your panel supports
maxPartitions: "3" #maximum amount of partitions that your panel supports
rfSerialLookup: "0397567:09:80,0931570:10:80,0037117:11:80,0117340:12:80,0136928:13:80,0798385:14:80,0199136:15:80,0474834:16:80" # list of RF serial numbers with associated zone and bitmask.
#Format: "serial1#:zone1:mask1,serial2#:zone2:mask2"
#Mask: hex value used to mask out open/close bit from RF returned value
defaultPartition: "1"
#assign a new virtual keypad address to each active partition using programs *190 - *196
#and enter it below. For unused partitions, use 0 as the keypad address.
keypadAddr1: "19" #partition 1 virtual keyapd
keypadAddr2: "0" #partition 2 virtual keypad. set to 0 to disable
keypadAddr3: "0" #partition 3 virtual keypad. set to 0 to disable
##esp32
rxPin: "22" #GPIO pin to use for data receive (yellow line)
txPin: "21" #GPIO pin to use for data transmit (green line)
monitorPin: "18" #GPIO pin to use for monitoring module traffic such as RF or Expanders . Set to -1 to disable
##esp8266
# rxPin: "5" #GPIO pin to use for data receive (yellow line)
# txPin: "4" #GPIO pin to use for data transmit (green line)
# monitorPin: "14" #GPIO pin to use for monitoring module traffic such as RF or Expanders . Set to -1 to disable
# module addresses:
# 07 4229 zone expander zones 9-16
# 08 4229 zone expander zones 17-24
# 09 4229 zone expander zones 25-32
# 10 4229 zone expander zones 33-40
# 11 4229 zone expander zones 41 48
# 12 4204 relay module
# 13 4204 relay module
# 14 4204 relay module
# 15 4204 relay module
expanderAddr1: "8" # 1st zone expander emulator (4229) address to use . Set to 0 to disable.
expanderAddr2: "0" # 2nd expander emulator address to use . Set to 0 to disable.
relayAddr1: "0" # relay module emulation (4204) addresses. Set to 0 to disable
relayAddr2: "0"
relayAddr3: "0"
relayAddr4: "0"
TTL: "15000" # time to live in ms for zone/fire status before expiring;
quickArm: "false"
lrrSupervisor: "true" # set to true if we don't have an LRR monitoring supervisor we can emulate one to get the statuses
esphome:
name: $systemName
platform: ESP32
#board: nodemcu-32s
board: mhetesp32devkit
# platform: ESP8266
# board: nodemcuv2
# subdirectory where library *.h and *.cpp are placed
includes:
- vistaEcpInterface/
wifi:
networks:
- ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "$systemName"
password: !secret wifi_password_backup
logger:
baud_rate: 115200
level: DEBUG
api:
encryption:
key: !secret encryption_key
ota:
password: !secret ota_password
safe_mode: True
on_begin:
- lambda: |-
disconnectVista();
status_led:
pin:
number: GPIO2
inverted: yes
time:
- platform: homeassistant
id: local_time
custom_component:
- lambda: |-
auto VistaECP = new vistaECPHome($keypadAddr1,$rxPin,$txPin,$monitorPin,$maxZones,$maxPartitions);
VistaECP->defaultPartition=$defaultPartition;
VistaECP->partitionKeypads[1]=$keypadAddr1;
VistaECP->partitionKeypads[2]=$keypadAddr2;
VistaECP->partitionKeypads[3]=$keypadAddr3;
VistaECP->rfSerialLookup="$rfSerialLookup";
VistaECP->accessCode="$accessCode";
VistaECP->quickArm=$quickArm;
VistaECP->expanderAddr1=$expanderAddr1; //zone expander
VistaECP->expanderAddr2=$expanderAddr2;
VistaECP->relayAddr1=$relayAddr1; //relay module
VistaECP->relayAddr2=$relayAddr2;
VistaECP->relayAddr3=$relayAddr3;
VistaECP->relayAddr4=$relayAddr4;
VistaECP->lrrSupervisor=$lrrSupervisor;
VistaECP->TTL=$TTL;
VistaECP->debug=1;
VistaECP->onSystemStatusChange([&](std::string statusCode,uint8_t partition) {
switch(partition) {
case 1: id(system_status).publish_state(statusCode);break;
case 2: break;
case 3: break;
default: break;
}
});
VistaECP->onLine1DisplayChange([&](std::string msg,uint8_t partition) {
switch(partition) {
case 1: id(l1).publish_state(msg); break;
case 2: break;
case 3: break;
default: break;
}
});
VistaECP->onLine2DisplayChange([&](std::string msg,uint8_t partition) {
switch(partition) {
case 1: id(l2).publish_state(msg); break;
case 2: break;
case 3: break;
default: break;
}
});
VistaECP->onBeepsChange([&](std::string beeps,uint8_t partition) {
switch(partition) {
case 1: id(beep1).publish_state(beeps); break;
case 2: break;
case 3: break;
default: break;
}
});
VistaECP->onZoneExtendedStatusChange([&](std::string msg) {
id(zoneExtended).publish_state(msg);
});
VistaECP->onLrrMsgChange([&](std::string msg) {
id(m1).publish_state(msg);
});
VistaECP->onRfMsgChange([&](std::string msg) {
id(rf1).publish_state(msg);
});
VistaECP->onStatusChange([&](sysState led,bool open,uint8_t partition) {
switch(partition) {
case 1:
switch(led) {
case sfire: id(fire).publish_state(open);break;
case salarm: id(alarm1).publish_state(open);break;
case strouble: id(trouble).publish_state(open);break;
case sarmedstay: id(stay).publish_state(open);break;
case sarmedaway: id(away).publish_state(open);break;
case sinstant: id(instant).publish_state(open);break;
case sready: id(ready).publish_state(open);break;
case sac: id(ac).publish_state(open);break;
case sbypass: id(bypass).publish_state(open);break;
case schime: id(chime).publish_state(open);break;
case sbat: id(bat).publish_state(open);break;
case sarmednight: id(night).publish_state(open);break;
case sarmed: id(armed).publish_state(open);break;
default: break;
};
break;
case 2: break;
case 3: break;
default: break;
}
});
VistaECP->onZoneStatusChange([&](uint8_t zone, std::string open) {
switch (zone) {
case 9: id(z9).publish_state(open); break;
case 10: id(z10).publish_state(open); break;
case 11: id(z11).publish_state(open); break;
case 12: id(z12).publish_state(open); break;
case 13: id(z13).publish_state(open); break;
case 14: id(z14).publish_state(open); break;
case 15: id(z15).publish_state(open); break;
case 16: id(z16).publish_state(open); break;
// Emulated Zone
case 17: id(z17).publish_state(open); break;
// case 25: id(z25).publish_state(open); break;
default: break;
}
}); //you can add more zones above . Also add the text sensor entry below
VistaECP->onRelayStatusChange([&](uint8_t addr,uint8_t zone,bool open) {
switch(addr) {
case 12:
switch (zone) {
case 1: id(r1).publish_state(open); break;
case 2: id(r2).publish_state(open); break;
}
break;
case 13: break;
default: break;
}
}); //add as many case and switch statements as needed to control your binary sensor outputs
return {VistaECP};
binary_sensor:
#- platform: gpio #example use of pin d8 as a zone trigger port for the emulated zone expander
# pin: D8
# id: pind8
# device_class: window
# on_press: #zone,on/off
# - lambda: |-
# vista.setExpFault(17,1);
# on_release:
# - lambda: |-
# vista.setExpFault(17,0);
#system status indicator definitions
- platform: template
id: trouble
name: "$systemName Trouble"
#device_class: problem
- platform: template
id: bypass
name: "$systemName Bypass"
- platform: template
id: away
name: "$systemName Away"
- platform: template
id: armed
name: "$systemName Armed"
- platform: template
id: stay
name: "$systemName Stay"
- platform: template
id: instant
name: "$systemName Instant"
- platform: template
id: night
name: "$systemName Night"
- platform: template
id: ac
name: "$systemName AC"
device_class: plug
- platform: template
id: chime
name: "$systemName Chime"
- platform: template
id: alarm1
name: "$systemName Alarm"
- platform: template
id: bat
name: "$systemName Battery"
device_class: problem
- platform: template
id: fire
device_class: smoke
name: "$systemName Fire"
- platform: template
id: ready
name: "$systemName Ready"
#device_class: problem
#relay module channels add as many as you need. To hide, comment out the name: attribute
- platform: template
id: r1
# name: "$systemName Relay1"
- platform: template
id: r2
# name: "$systemName Relay2"
#zone definitions. Add more (also add to the switch statment above). To hide, comment out the name: attribute
text_sensor:
#zone definitions
- platform: template
id: z9
name: "$systemName Front Door"
- platform: template
id: z10
name: "$systemName Patio Door"
- platform: template
id: z11
name: "$systemName Garage Door"
- platform: template
id: z12
name: "$systemName Basement Door"
- platform: template
id: z13
name: "$systemName Main Motion"
- platform: template
id: z14
name: "$systemName Smoke Detector"
- platform: template
id: z15
name: "$systemName Garage Man Door"
- platform: template
id: z16
name: "$systemName Garage Basement Door"
- platform: template
id: z17
name: "$systemName Test"
#system status
- platform: template
id: system_status
name: "$systemName System Status"
icon: "mdi:shield"
- platform: template
id: m1
name: "$systemName Lrr Msg"
icon: "mdi:alert-box"
- platform: template
id: rf1
name: "$systemName RF Msg"
icon: "mdi:alert-box"
- platform: template
id: l1
name: "$systemName Line1"
- platform: template
id: l2
name: "$systemName Line2"
- platform: template
id: beep1
name: "$systemName Beeps"
- platform: template
id: zoneExtended
name: "$systemName Zone Status"
switch:
- platform: template
name: "$systemName Connection"
id: connection_status_switch
lambda: |-
return vista.keybusConnected;
icon: "mdi:shield-link-variant"
turn_on_action:
- switch.toggle: restart_switch
turn_off_action:
- lambda: |-
disconnectVista();
- platform: restart
id: restart_switch
Logs
Well, I can see that the panel is sending RF device statuses with the status of 0x84 and since your bit mask is set to 0x80, it sees it as an open. Do you have a status with a close event so we can determine what the correct bit mask should be.
I think the heartbeat that rf devices send every 60 to 90 minutes is causing the issue. I'll check my code in how it handles the mask.
I've pushed a small update on dev. Just an update to vistalarm.h that has it ignoring RF heartbeat status messages for zone updates. See if that addresses your issue. I'd still like to see a close RF status as well to see if there isnt anything else at play here.
Ok, I see the issue. You should be using 0x20 as the mask and not 0x80. With rf sensors there are 4 possible loops that can be used and the corresponding masks would be 0x80, 0x40, 0x20 and 0x10. Your's has two loops defined. 0x80 is always on and 0x20 is what determine the open/close status (giving a on value of 0xa0 on and 0x80 off). I don't know the logic at this time as to how the loops are selected. The rf serial lookup is still experimental at this time. So change the mask value (3rd entry of each record) of each sensor to 0x20.
Ok. It looks like changing the mask fixed the issue. One question about the rf serial lookup is would I figure out the mask for motion sensors and smoke detectors?
Only way is to trigger then reset them and see what the value changes to in the RFX line in the log. It's a guessing game as I don't know the logic that determines it. I don't have enough data from other users to compare. I also do not have any rf sensors set up so can't test myself. I'm only working off a bench test system as far as the vista is concerned.
Ok, I tested the smoke detector. B0 when triggered and 00 when disarmed. Not sure how to determine the mask for that. Still waiting/trying to trigger the motion detector.
Edit: For documentation sake, I believe the smoke detector is a 5806W3.
Ok, so the PIR motion produces an 80 when triggered and 00 when cleared.
ok, Great. From what I see you can use 0x80 mask for the PIR and smoke detectors as they all set bit 7 (0x80) on and off. For the door sensors, you use 0x20 for the mask as bit 7 (0x80) of the status seems to always be on but bit 5 (0x20) is the one that toggles to indicate open/close status. Interesting though that the smoke sensor set bit 7, 5 and 4 on for active and 0 for idle. You only need to test for one of those bits so might as well use bit 7(0x80)
FYI, i've changed the way the RF devices are entered in the yaml to make it easier. It will use whatever info you have setup from program *56 for loop# and zone#. No need to worry about masks. Just enter the serial:loop#:zone#. You can see this document for default loop numbers for various devices:
https://advancedsecurityllc.com/wp-content/uploads/5800%20Wireless%20Device%20List.pdf