This commit is contained in:
Vasilis Pantelis 2025-01-08 22:46:25 +01:00 committed by GitHub
commit 3e71bc603f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 305 additions and 242 deletions

View File

@ -88,6 +88,7 @@ public enum DSCAlarmCode {
ZoneRestored("610", "Zone Restored", "610: General status of the zone - restored."),
EnvisalinkZoneTimerDump("615", "Envisalink Zone Timer Dump",
"615: The raw zone timers used inside the Envisalink."),
BypassedZonesBitfield("616", "Bypassed Zones Bitfield", "616: Bypassed zones bitfield."),
DuressAlarm("620", "Duress Alarm", "620: A duress code has been entered on a system keypad."),
FireKeyAlarm("621", "Fire Key Alarm", "621: A Fire key alarm has been activated."),
FireKeyRestored("622", "Fire Key Alarm Restore", "622: A Fire key alarm has been restored."),

View File

@ -79,9 +79,16 @@ public class DSCAlarmMessage {
* Processes the incoming DSC Alarm message and extracts the information.
*/
private void processDSCAlarmMessage() {
DSCAlarmCode dscAlarmCode;
if (message.length() <= 3) {
codeReceived = "-1";
data = "";
DSCAlarmCode dscAlarmCode = DSCAlarmCode.UnknownCode;
name = dscAlarmCode.getName();
description = dscAlarmCode.getDescription();
logger.debug("parseAPIMessage(): Invalid Message Received");
return;
}
if (message.length() > 3) {
try {
if (message.length() >= 8 && message.charAt(2) == ':' && message.charAt(5) == ':') {
timeStamp = message.substring(0, 8);
@ -100,31 +107,28 @@ public class DSCAlarmMessage {
return;
}
dscAlarmCode = DSCAlarmCode.getDSCAlarmCodeValue(codeReceived);
DSCAlarmCode dscAlarmCode = DSCAlarmCode.getDSCAlarmCodeValue(codeReceived);
if (dscAlarmCode != null) {
name = dscAlarmCode.getName();
description = dscAlarmCode.getDescription();
MessageParameters messageParms = DSCALARM_MESSAGE_PARAMETERS.get(dscAlarmCode);
MessageParameters messageParams = DSCALARM_MESSAGE_PARAMETERS.get(dscAlarmCode);
if (messageParms != null) {
boolean hasPartition = messageParms.hasPartition();
boolean hasZone = messageParms.hasZone();
if (messageParams != null) {
boolean hasPartition = messageParams.hasPartition();
boolean hasZone = messageParams.hasZone();
if (hasPartition) {
partition = message.substring(3, 4);
}
if (hasZone) {
if (hasPartition) {
zone = message.substring(4);
} else {
zone = message.substring(3);
}
int zoneIndex = hasPartition ? 4 : 3;
zone = message.substring(zoneIndex);
}
messageType = messageParms.getType();
messageType = messageParams.getType();
}
switch (dscAlarmCode) {
@ -216,7 +220,6 @@ public class DSCAlarmMessage {
break;
}
break;
case PartitionArmed: /* 652 */
mode = message.substring(4);
if ("0".equals(mode)) {
@ -233,8 +236,7 @@ public class DSCAlarmMessage {
case UserClosing: /* 700 */
user = message.substring(4);
name = name.concat(": " + user);
description = codeReceived + ": Partition " + partition + " has been armed by user " + user
+ ".";
description = codeReceived + ": Partition " + partition + " has been armed by user " + user + ".";
messageType = DSCAlarmMessageType.PARTITION_EVENT;
break;
case UserOpening: /* 750 */
@ -249,18 +251,9 @@ public class DSCAlarmMessage {
break;
}
logger.debug(
"parseAPIMessage(): Message Received ({}) - Code: {}, Name: {}, Description: {}, Data: {}\r\n",
logger.debug("parseAPIMessage(): Message Received ({}) - Code: {}, Name: {}, Description: {}, Data: {}\r\n",
message, codeReceived, name, description, data);
}
} else {
codeReceived = "-1";
data = "";
dscAlarmCode = DSCAlarmCode.getDSCAlarmCodeValue(codeReceived);
name = dscAlarmCode.getName();
description = dscAlarmCode.getDescription();
logger.debug("parseAPIMessage(): Invalid Message Received");
}
}
/**
@ -451,6 +444,8 @@ public class DSCAlarmMessage {
new MessageParameters(DSCAlarmMessageType.ZONE_EVENT, false, true));
DSCALARM_MESSAGE_PARAMETERS.put(DSCAlarmCode.EnvisalinkZoneTimerDump,
new MessageParameters(DSCAlarmMessageType.PANEL_EVENT, false, false));
DSCALARM_MESSAGE_PARAMETERS.put(DSCAlarmCode.BypassedZonesBitfield,
new MessageParameters(DSCAlarmMessageType.ZONE_EVENT, false, false));
DSCALARM_MESSAGE_PARAMETERS.put(DSCAlarmCode.DuressAlarm,
new MessageParameters(DSCAlarmMessageType.PANEL_EVENT, false, false));
DSCALARM_MESSAGE_PARAMETERS.put(DSCAlarmCode.FireKeyAlarm,

View File

@ -37,6 +37,7 @@ import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.binding.BaseBridgeHandler;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.slf4j.Logger;
@ -449,24 +450,36 @@ public abstract class DSCAlarmBaseBridgeHandler extends BaseBridgeHandler {
return thing;
}
public List<Thing> findAllZoneThings() {
List<Thing> things = getThing().getThings();
return things.stream().filter(this::isZoneThing).toList();
}
private boolean isZoneThing(Thing thing) {
ThingHandler thingHandler = thing.getHandler();
if (thingHandler == null) {
return false;
}
DSCAlarmBaseThingHandler handler = (DSCAlarmBaseThingHandler) thingHandler;
return DSCAlarmThingType.ZONE.equals(handler.getDSCAlarmThingType());
}
/**
* Handles an incoming message from the DSC Alarm System.
*
* @param incomingMessage
*/
public synchronized void handleIncomingMessage(String incomingMessage) {
if (incomingMessage != null && !incomingMessage.isEmpty()) {
if (incomingMessage == null || incomingMessage.isEmpty()) {
logger.debug("handleIncomingMessage(): No Message Received!");
return;
}
DSCAlarmMessage dscAlarmMessage = new DSCAlarmMessage(incomingMessage);
DSCAlarmMessageType dscAlarmMessageType = dscAlarmMessage.getDSCAlarmMessageType();
logger.debug("handleIncomingMessage(): Message received: {} - {}", incomingMessage,
dscAlarmMessage.toString());
DSCAlarmEvent event = new DSCAlarmEvent(this);
event.dscAlarmEventMessage(dscAlarmMessage);
DSCAlarmThingType dscAlarmThingType = null;
int partitionId = 0;
int zoneId = 0;
logger.debug("handleIncomingMessage(): Message received: {} - {}", incomingMessage, dscAlarmMessage);
DSCAlarmCode dscAlarmCode = DSCAlarmCode
.getDSCAlarmCodeValue(dscAlarmMessage.getMessageInfo(DSCAlarmMessageInfoType.CODE));
@ -491,6 +504,13 @@ public abstract class DSCAlarmBaseBridgeHandler extends BaseBridgeHandler {
}
}
DSCAlarmEvent event = new DSCAlarmEvent(this);
event.dscAlarmEventMessage(dscAlarmMessage);
DSCAlarmThingType dscAlarmThingType = null;
int partitionId = 0;
int zoneId = 0;
switch (dscAlarmMessageType) {
case PANEL_EVENT:
dscAlarmThingType = DSCAlarmThingType.PANEL;
@ -511,8 +531,22 @@ public abstract class DSCAlarmBaseBridgeHandler extends BaseBridgeHandler {
break;
}
if (dscAlarmThingType != null) {
if (dscAlarmThingType == null) {
return;
}
if (DSCAlarmCode.BypassedZonesBitfield.equals(dscAlarmCode)) {
List<Thing> allZoneThings = findAllZoneThings();
for (Thing zone : allZoneThings) {
handleIncomingMessage(event, zone, dscAlarmThingType);
}
} else {
Thing thing = findThing(dscAlarmThingType, partitionId, zoneId);
handleIncomingMessage(event, thing, dscAlarmThingType);
}
}
private void handleIncomingMessage(DSCAlarmEvent event, Thing thing, DSCAlarmThingType dscAlarmThingType) {
logger.debug("handleIncomingMessage(): Thing Search - '{}'", thing);
@ -535,10 +569,6 @@ public abstract class DSCAlarmBaseBridgeHandler extends BaseBridgeHandler {
}
}
}
} else {
logger.debug("handleIncomingMessage(): No Message Received!");
}
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {

View File

@ -14,7 +14,9 @@ package org.openhab.binding.dscalarm.internal.handler;
import static org.openhab.binding.dscalarm.internal.DSCAlarmBindingConstants.*;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import org.openhab.binding.dscalarm.internal.DSCAlarmCode;
import org.openhab.binding.dscalarm.internal.DSCAlarmEvent;
@ -129,11 +131,11 @@ public class ZoneThingHandler extends DSCAlarmBaseThingHandler {
DSCAlarmEvent dscAlarmEvent = (DSCAlarmEvent) event;
DSCAlarmMessage dscAlarmMessage = dscAlarmEvent.getDSCAlarmMessage();
ChannelUID channelUID = null;
DSCAlarmCode dscAlarmCode = DSCAlarmCode
.getDSCAlarmCodeValue(dscAlarmMessage.getMessageInfo(DSCAlarmMessageInfoType.CODE));
logger.debug("dscAlarmEventRecieved(): Thing - {} Command - {}", thing.getUID(), dscAlarmCode);
ChannelUID channelUID;
int state = 0;
String status = "";
@ -173,10 +175,45 @@ public class ZoneThingHandler extends DSCAlarmBaseThingHandler {
updateChannel(channelUID, state, "");
zoneMessage(status);
break;
case BypassedZonesBitfield:
state = isZoneByPassed(dscAlarmMessage) ? 1 : 0;
channelUID = new ChannelUID(getThing().getUID(), ZONE_BYPASS_MODE);
updateChannel(channelUID, state, "");
break;
default:
break;
}
}
}
}
private boolean isZoneByPassed(DSCAlarmMessage dscAlarmMessage) {
String data = dscAlarmMessage.getMessageInfo(DSCAlarmMessageInfoType.DATA);
List<Integer> bypassedZones = parseZoneIdsFromHex(data);
return bypassedZones.contains(getZoneNumber());
}
private List<Integer> parseZoneIdsFromHex(String data) {
// List to store bypassed zones
List<Integer> bypassedZones = new ArrayList<>();
// Process each byte in the HEX string
for (int byteIndex = 0; byteIndex < data.length() / 2; byteIndex++) {
// Get two characters representing the byte (2 HEX characters = 1 byte)
String byteHex = data.substring(byteIndex * 2, byteIndex * 2 + 2);
// Convert the HEX string to an integer
int byteValue = Integer.parseInt(byteHex, 16);
// Process each bit in the byte (8 bits per byte)
for (int bit = 0; bit < 8; bit++) {
if ((byteValue & (1 << bit)) != 0) {
// Calculate the zone number (1-based)
int zoneNumber = byteIndex * 8 + bit + 1;
bypassedZones.add(zoneNumber);
}
}
}
return bypassedZones;
}
}