]> git.basschouten.com Git - openhab-addons.git/blob
ce9891b312cdf0cd7d6140eead12b411ab9ec9fd
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.alarmdecoder.internal.protocol;
14
15 import java.util.List;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19
20 /**
21  * The {@link KeypadMessage} class represents a parsed keypad (KPM) message.
22  * Based partly on code from the OH1 alarmdecoder binding by Bernd Pfrommer.
23  *
24  * @author Bob Adair - Initial contribution
25  */
26 @NonNullByDefault
27 public class KeypadMessage extends ADMessage {
28
29     // Example: [00110011000000003A--],010,[f70700000010808c18020000000000],"ARMED ***STAY** ZONE BYPASSED "
30
31     public static final int BIT_READY = 17;
32     public static final int BIT_ARMEDAWAY = 16;
33     public static final int BIT_ARMEDHOME = 15;
34     public static final int BIT_BACKLIGHT = 14;
35     public static final int BIT_PRORGAM = 13;
36     public static final int BIT_BYPASSED = 9;
37     public static final int BIT_ACPOWER = 8;
38     public static final int BIT_CHIME = 7;
39     public static final int BIT_ALARMOCCURRED = 6;
40     public static final int BIT_ALARM = 5;
41     public static final int BIT_LOWBAT = 4;
42     public static final int BIT_DELAYOFF = 3;
43     public static final int BIT_FIRE = 2;
44     public static final int BIT_SYSFAULT = 1;
45     public static final int BIT_PERIMETER = 0;
46
47     public final String bitField;
48     public final int numericCode;
49     public final String rawData;
50     public final String alphaMessage;
51     public final int nbeeps;
52     public final int status;
53
54     private final int upper;
55     private final int lower;
56
57     public KeypadMessage(String message) throws IllegalArgumentException {
58         super(message);
59         List<String> parts = splitMsg(message.replace("!KPM:", ""));
60
61         if (parts.size() != 4) {
62             throw new IllegalArgumentException("Invalid number of parts in keypad message");
63         }
64         if (parts.get(0).length() != 22) {
65             throw new IllegalArgumentException("Invalid field length in keypad message");
66         }
67
68         bitField = parts.get(0);
69         rawData = parts.get(2);
70         alphaMessage = parts.get(3).replaceAll("^\"|\"$", "");
71
72         try {
73             int numeric = 0;
74             try {
75                 numeric = Integer.parseInt(parts.get(1));
76             } catch (NumberFormatException e) {
77                 numeric = Integer.parseInt(parts.get(1), 16);
78             }
79             this.numericCode = numeric;
80
81             this.upper = Integer.parseInt(parts.get(0).substring(1, 6), 2);
82             this.nbeeps = Integer.parseInt(parts.get(0).substring(6, 7));
83             this.lower = Integer.parseInt(parts.get(0).substring(7, 17), 2);
84             this.status = ((upper & 0x1F) << 13) | ((nbeeps & 0x3) << 10) | lower;
85         } catch (NumberFormatException e) {
86             throw new IllegalArgumentException("keypad msg contains invalid number: " + e.getMessage(), e);
87         }
88     }
89
90     public int getZone() {
91         return numericCode;
92     }
93
94     /**
95      * Returns a string containing the keypad text
96      */
97     public String getText() {
98         return alphaMessage;
99     }
100
101     /**
102      * Returns the value of an individual bit in the status field
103      *
104      * @param bit status field bit to test
105      * @return true if bit is 1, false if bit is 0
106      */
107     public boolean getStatus(int bit) {
108         int v = (status >> bit) & 0x1;
109         return (v == 0) ? false : true;
110     }
111
112     /**
113      * Returns true if the READY status bit is set
114      */
115     public boolean panelClear() {
116         return ((status & (1 << BIT_READY)) != 0);
117     }
118
119     /**
120      * Returns a string containing the address mask of the message in hex
121      */
122     public String getAddressMask() {
123         return rawData.substring(3, 11);
124     }
125
126     /**
127      * Returns a long containing the address mask of the message
128      */
129     public long getLongAddressMask() {
130         return Long.parseLong(getAddressMask(), 16);
131     }
132
133     /**
134      * Compares two KeypadMessage objects
135      *
136      * @param obj KeypadMessage to compare against
137      * @return true if messages are equal, false if obj is null, messages are not equal, or obj is not a KeypadMessage
138      *         object.
139      */
140     @Override
141     public boolean equals(@Nullable Object obj) {
142         if (obj == null) {
143             return false;
144         } else if (this == obj) {
145             return true;
146         } else if (obj instanceof KeypadMessage other) {
147             return this.message.equals(other.message);
148         } else {
149             return false;
150         }
151     }
152 }