]> git.basschouten.com Git - openhab-addons.git/blob
b892c4b8c4e9b0fb17ad70991d9cf69a074e5f49
[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.satel.internal.command;
14
15 import java.time.LocalDateTime;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.openhab.binding.satel.internal.protocol.SatelMessage;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * Command class for command that reads one record from the event log.
24  *
25  * @author Krzysztof Goworek - Initial contribution
26  */
27 @NonNullByDefault
28 public class ReadEventCommand extends SatelCommandBase {
29
30     private final Logger logger = LoggerFactory.getLogger(this.getClass());
31
32     public static final byte COMMAND_CODE = (byte) 0x8c;
33
34     /**
35      * Event class: zone alarms, partition alarms, arming, troubles, etc.
36      *
37      * @author Krzysztof Goworek - Initial contribution
38      *
39      */
40     public enum EventClass {
41         ZONE_ALARMS("zone and tamper alarms"),
42         PARTITION_ALARMS("partition and expander alarms"),
43         ARMING("arming, disarming, alarm clearing"),
44         BYPASSES("zone bypasses and unbypasses"),
45         ACCESS_CONTROL("access control"),
46         TROUBLES("troubles"),
47         USER_FUNCTIONS("user functions"),
48         SYSTEM_EVENTS("system events");
49
50         private String description;
51
52         EventClass(String description) {
53             this.description = description;
54         }
55
56         public String getDescription() {
57             return description;
58         }
59     }
60
61     /**
62      * Creates new command class instance to read a record under given index.
63      *
64      * @param eventIndex index of event record to retrieve, -1 for the most recent one
65      */
66     public ReadEventCommand(int eventIndex) {
67         super(COMMAND_CODE, getIndexBytes(eventIndex));
68     }
69
70     private static byte[] getIndexBytes(int index) {
71         return new byte[] { (byte) ((index >> 16) & 0xff), (byte) ((index >> 8) & 0xff), (byte) (index & 0xff) };
72     }
73
74     /**
75      * Checks whether response data contains valid event record.
76      *
77      * @return <code>true</code> if returned record is empty (likely the last
78      *         record in the log)
79      */
80     public boolean isEmpty() {
81         return (getResponse().getPayload()[0] & 0x20) == 0;
82     }
83
84     /**
85      * Checks whether event record is present in the response data.
86      *
87      * @return <code>true</code> if event data is present in the response
88      */
89     public boolean isEventPresent() {
90         return (getResponse().getPayload()[0] & 0x10) != 0;
91     }
92
93     /**
94      * Returns date and time of the event.
95      *
96      * @return date and time of the event
97      */
98     public LocalDateTime getTimestamp() {
99         final byte[] payload = getResponse().getPayload();
100         final int currentYear = LocalDateTime.now().getYear();
101         final int yearBase = currentYear / 4;
102         final int yearMarker = (payload[0] >> 6) & 0x03;
103         int year = 4 * yearBase + yearMarker;
104         final int minutes = ((payload[2] & 0x0f) << 8) + (payload[3] & 0xff);
105
106         if (year > currentYear) {
107             year -= 4;
108         }
109         return LocalDateTime.of(year, (payload[2] >> 4) & 0x0f, payload[1] & 0x1f, minutes / 60, minutes % 60);
110     }
111
112     /**
113      * Returns class of the event.
114      *
115      * @return event class of the event
116      * @see EventClass
117      */
118     public EventClass getEventClass() {
119         final int eventClassIdx = (getResponse().getPayload()[1] >> 5) & 0x07;
120         return EventClass.values()[eventClassIdx];
121     }
122
123     /**
124      * Returns number of partion the event is about.
125      *
126      * @return partition number
127      */
128     public int getPartition() {
129         return ((getResponse().getPayload()[4] >> 3) & 0x1f) + 1;
130     }
131
132     /**
133      * Returns number of partition keypad related to the event.
134      *
135      * @return partition keypad number
136      */
137     public int getPartitionKeypad() {
138         return ((getResponse().getPayload()[4] >> 2) & 0x3f) + 1;
139     }
140
141     /**
142      * Returns event code the describes the event. It can be used to retrieve description text for this event.
143      *
144      * @return event code
145      * @see ReadEventDescCommand
146      */
147     public int getEventCode() {
148         final byte[] payload = getResponse().getPayload();
149         return ((payload[4] & 0x03) << 8) + (payload[5] & 0xff);
150     }
151
152     /**
153      * Returns state restoration flag.
154      *
155      * @return <code>true</code> if this is restoration of some state (i.e.
156      *         arming and disarming have the same code but different restoration
157      *         flag)
158      */
159     public boolean isRestore() {
160         return (getResponse().getPayload()[4] & 0x04) != 0;
161     }
162
163     /**
164      * Return source of the event.
165      *
166      * @return event source (zone number, user number, etc depending on event)
167      */
168     public int getSource() {
169         return getResponse().getPayload()[6] & 0xff;
170     }
171
172     /**
173      * Returns object number for the event.
174      *
175      * @return object number (0..7)
176      */
177     public int getObject() {
178         return (getResponse().getPayload()[7] >> 5) & 0x07;
179     }
180
181     /**
182      * Returns user control number for the event.
183      *
184      * @return user control number
185      */
186     public int getUserControlNumber() {
187         return getResponse().getPayload()[7] & 0x1f;
188     }
189
190     /**
191      * Return index of previous event in the log. Can be used to iterate over tha event log.
192      *
193      * @return index of previous event record in the log
194      */
195     public int getNextIndex() {
196         final byte[] payload = getResponse().getPayload();
197         return (payload[8] << 16) + ((payload[9] & 0xff) << 8) + (payload[10] & 0xff);
198     }
199
200     /**
201      * Returns current event index.
202      *
203      * @return index of current record echoed by communication module
204      */
205     public int getCurrentIndex() {
206         final byte[] payload = getResponse().getPayload();
207         return (payload[11] << 16) + ((payload[12] & 0xff) << 8) + (payload[13] & 0xff);
208     }
209
210     @Override
211     protected boolean isResponseValid(SatelMessage response) {
212         // validate response
213         if (response.getPayload().length != 14) {
214             logger.debug("Invalid payload length: {}", response.getPayload().length);
215             return false;
216         }
217         return true;
218     }
219 }