2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.paradoxalarm.internal.parsers;
15 import org.openhab.binding.paradoxalarm.internal.model.PartitionState;
16 import org.openhab.binding.paradoxalarm.internal.model.ZoneState;
17 import org.openhab.binding.paradoxalarm.internal.model.ZoneStateFlags;
18 import org.openhab.binding.paradoxalarm.internal.util.ParadoxUtil;
21 * The {@link EvoParser} Implementation of parser interface for EVO type panels
23 * @author Konstantin Polihronov - Initial contribution
25 public class EvoParser extends AbstractParser {
28 public PartitionState calculatePartitionState(byte[] partitionFlags) {
29 byte firstByte = partitionFlags[0];
30 PartitionState state = new PartitionState();
31 state.setArmed(ParadoxUtil.isBitSet(firstByte, 0));
32 state.setArmedInAway(ParadoxUtil.isBitSet(firstByte, 1));
33 state.setArmedInStay(ParadoxUtil.isBitSet(firstByte, 2));
34 state.setArmedInNoEntry(ParadoxUtil.isBitSet(firstByte, 3));
36 state.setInAlarm(ParadoxUtil.isBitSet(firstByte, 4));
37 state.setInSilentAlarm(ParadoxUtil.isBitSet(firstByte, 5));
38 state.setInAudibleAlarm(ParadoxUtil.isBitSet(firstByte, 6));
39 state.setInFireAlarm(ParadoxUtil.isBitSet(firstByte, 7));
41 byte secondByte = partitionFlags[1];
42 state.setReadyToArm(ParadoxUtil.isBitSet(secondByte, 0));
43 state.setInExitDelay(ParadoxUtil.isBitSet(secondByte, 1));
44 state.setInEntryDelay(ParadoxUtil.isBitSet(secondByte, 2));
45 state.setInTrouble(ParadoxUtil.isBitSet(secondByte, 3));
46 state.setHasAlarmInMemory(ParadoxUtil.isBitSet(secondByte, 4));
47 state.setInZoneBypass(ParadoxUtil.isBitSet(secondByte, 5));
49 byte thirdByte = partitionFlags[2];
50 state.setHasZoneInTamperTrouble(ParadoxUtil.isBitSet(thirdByte, 4));
51 state.setHasZoneInLowBatteryTrouble(ParadoxUtil.isBitSet(thirdByte, 5));
52 state.setHasZoneInFireLoopTrouble(ParadoxUtil.isBitSet(thirdByte, 6));
53 state.setHasZoneInSupervisionTrouble(ParadoxUtil.isBitSet(thirdByte, 7));
55 byte sixthByte = partitionFlags[5];
56 state.setStayInstantReady(ParadoxUtil.isBitSet(sixthByte, 0));
57 state.setForceReady(ParadoxUtil.isBitSet(sixthByte, 1));
58 state.setBypassReady(ParadoxUtil.isBitSet(sixthByte, 2));
59 state.setInhibitReady(ParadoxUtil.isBitSet(sixthByte, 3));
60 state.setAllZoneClosed(ParadoxUtil.isBitSet(sixthByte, 4));
66 public ZoneState calculateZoneState(int id, ZoneStateFlags zoneStateFlags) {
67 int index = (id - 1) / 8;
68 int bitNumber = id % 8 - 1;
70 // Every zone state is represented by a bit set/unset in the big byte array retrieved from the memory of the
72 byte[] zonesOpened = zoneStateFlags.getZonesOpened();
73 boolean isOpened = ParadoxUtil.isBitSet(zonesOpened[index], bitNumber);
75 byte[] zonesTampered = zoneStateFlags.getZonesTampered();
76 boolean isTampered = ParadoxUtil.isBitSet(zonesTampered[index], bitNumber);
78 byte[] zonesLowBattery = zoneStateFlags.getZonesLowBattery();
79 boolean hasLowBattery = ParadoxUtil.isBitSet(zonesLowBattery[index], bitNumber);
81 ZoneState zoneState = new ZoneState(isOpened, isTampered, hasLowBattery);
83 calculateSpecialFlags(zoneStateFlags, id, zoneState);
88 private void calculateSpecialFlags(ZoneStateFlags zoneStateFlags, int index, ZoneState zoneState) {
89 // Each byte is filled with 8 special zone flags.
90 // Each bit of the byte represents a specific flag.
92 // 0 = Zone supervision trouble
93 // 1 = Zone in TX delay
94 // 2 = Zone shutted down
96 // 4 = Zone activated intellizone delay
97 // 5 = Zone activated entry delay
98 // 6 = Zone presently in alarm
99 // 7 = Zone generated an alarm
101 // The index of the actual zones and partitions enumerates from 1-N. In the arrays we need to index it from 0.
102 int specialFlagsIndex = index - 1;
103 byte[] zoneSpecialFlags = zoneStateFlags.getZoneSpecialFlags();
104 byte currentZoneFlags = zoneSpecialFlags[specialFlagsIndex];
106 zoneState.setSupervisionTrouble(ParadoxUtil.isBitSet(currentZoneFlags, 0));
107 zoneState.setInTxDelay(ParadoxUtil.isBitSet(currentZoneFlags, 1));
108 zoneState.setShuttedDown(ParadoxUtil.isBitSet(currentZoneFlags, 2));
109 zoneState.setBypassed(ParadoxUtil.isBitSet(currentZoneFlags, 3));
110 zoneState.setHasActivatedIntellizoneDelay(ParadoxUtil.isBitSet(currentZoneFlags, 4));
111 zoneState.setHasActivatedEntryDelay(ParadoxUtil.isBitSet(currentZoneFlags, 5));
112 zoneState.setPresentlyInAlarm(ParadoxUtil.isBitSet(currentZoneFlags, 6));
113 zoneState.setGeneratedAlarm(ParadoxUtil.isBitSet(currentZoneFlags, 7));