]> git.basschouten.com Git - openhab-addons.git/blob
3f305c4d68f809aa80d2159934996f6044721446
[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         LocalDateTime result = LocalDateTime.of(year, (payload[2] >> 4) & 0x0f, payload[1] & 0x1f, minutes / 60,
110                 minutes % 60);
111         return result;
112     }
113
114     /**
115      * Returns class of the event.
116      *
117      * @return event class of the event
118      * @see EventClass
119      */
120     public EventClass getEventClass() {
121         final int eventClassIdx = (getResponse().getPayload()[1] >> 5) & 0x07;
122         return EventClass.values()[eventClassIdx];
123     }
124
125     /**
126      * Returns number of partion the event is about.
127      *
128      * @return partition number
129      */
130     public int getPartition() {
131         return ((getResponse().getPayload()[4] >> 3) & 0x1f) + 1;
132     }
133
134     /**
135      * Returns number of partition keypad related to the event.
136      *
137      * @return partition keypad number
138      */
139     public int getPartitionKeypad() {
140         return ((getResponse().getPayload()[4] >> 2) & 0x3f) + 1;
141     }
142
143     /**
144      * Returns event code the describes the event. It can be used to retrieve description text for this event.
145      *
146      * @return event code
147      * @see ReadEventDescCommand
148      */
149     public int getEventCode() {
150         final byte[] payload = getResponse().getPayload();
151         return ((payload[4] & 0x03) << 8) + (payload[5] & 0xff);
152     }
153
154     /**
155      * Returns state restoration flag.
156      *
157      * @return <code>true</code> if this is restoration of some state (i.e.
158      *         arming and disarming have the same code but different restoration
159      *         flag)
160      */
161     public boolean isRestore() {
162         return (getResponse().getPayload()[4] & 0x04) != 0;
163     }
164
165     /**
166      * Return source of the event.
167      *
168      * @return event source (zone number, user number, etc depending on event)
169      */
170     public int getSource() {
171         return getResponse().getPayload()[6] & 0xff;
172     }
173
174     /**
175      * Returns object number for the event.
176      *
177      * @return object number (0..7)
178      */
179     public int getObject() {
180         return (getResponse().getPayload()[7] >> 5) & 0x07;
181     }
182
183     /**
184      * Returns user control number for the event.
185      *
186      * @return user control number
187      */
188     public int getUserControlNumber() {
189         return getResponse().getPayload()[7] & 0x1f;
190     }
191
192     /**
193      * Return index of previous event in the log. Can be used to iterate over tha event log.
194      *
195      * @return index of previous event record in the log
196      */
197     public int getNextIndex() {
198         final byte[] payload = getResponse().getPayload();
199         return (payload[8] << 16) + ((payload[9] & 0xff) << 8) + (payload[10] & 0xff);
200     }
201
202     /**
203      * Returns current event index.
204      *
205      * @return index of current record echoed by communication module
206      */
207     public int getCurrentIndex() {
208         final byte[] payload = getResponse().getPayload();
209         return (payload[11] << 16) + ((payload[12] & 0xff) << 8) + (payload[13] & 0xff);
210     }
211
212     @Override
213     protected boolean isResponseValid(SatelMessage response) {
214         // validate response
215         if (response.getPayload().length != 14) {
216             logger.debug("Invalid payload length: {}", response.getPayload().length);
217             return false;
218         }
219         return true;
220     }
221 }