]> git.basschouten.com Git - openhab-addons.git/blob
98c766adc938bcf5615f28ff654f305902582f36
[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.velux.internal.bridge.slip;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.binding.velux.internal.bridge.common.GetScenes;
17 import org.openhab.binding.velux.internal.bridge.slip.utils.KLF200Response;
18 import org.openhab.binding.velux.internal.bridge.slip.utils.Packet;
19 import org.openhab.binding.velux.internal.things.VeluxKLFAPI.Command;
20 import org.openhab.binding.velux.internal.things.VeluxKLFAPI.CommandNumber;
21 import org.openhab.binding.velux.internal.things.VeluxProductState;
22 import org.openhab.binding.velux.internal.things.VeluxScene;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 /**
27  * Protocol specific bridge communication supported by the Velux bridge:
28  * <B>Retrieve Scenes</B>
29  * <P>
30  * Common Message semantic: Communication with the bridge and (optionally) storing returned information within the class
31  * itself.
32  * <P>
33  * As 3rd level class it defines informations how to send query and receive answer through the
34  * {@link org.openhab.binding.velux.internal.bridge.VeluxBridgeProvider VeluxBridgeProvider}
35  * as described by the interface {@link org.openhab.binding.velux.internal.bridge.slip.SlipBridgeCommunicationProtocol
36  * SlipBridgeCommunicationProtocol}.
37  * <P>
38  * Methods in addition to the mentioned interface:
39  * <UL>
40  * <LI>{@link #getScenes()} to retrieve the set of current scenes.</LI>
41  * </UL>
42  *
43  * @see GetScenes
44  * @see SlipBridgeCommunicationProtocol
45  *
46  *
47  * @author Guenther Schreiner - Initial contribution.
48  */
49 @NonNullByDefault
50 class SCgetScenes extends GetScenes implements SlipBridgeCommunicationProtocol {
51     private final Logger logger = LoggerFactory.getLogger(SCgetScenes.class);
52
53     private static final String DESCRIPTION = "Retrieve Scenes";
54     private static final Command COMMAND = Command.GW_GET_SCENE_LIST_REQ;
55
56     /*
57      * Message Objects
58      */
59
60     private boolean success;
61     private boolean finished;
62
63     private int sceneIdx;
64     private VeluxScene[] scenes = new VeluxScene[0];
65
66     /*
67      * ===========================================================
68      * Methods required for interface {@link BridgeCommunicationProtocol}.
69      */
70
71     @Override
72     public String name() {
73         return DESCRIPTION;
74     }
75
76     @Override
77     public CommandNumber getRequestCommand() {
78         success = false;
79         finished = false;
80         logger.debug("getRequestCommand() returns {} ({}).", COMMAND.name(), COMMAND.getCommand());
81         return COMMAND.getCommand();
82     }
83
84     @Override
85     public byte[] getRequestDataAsArrayOfBytes() {
86         return EMPTYDATA;
87     }
88
89     @Override
90     public void setResponse(short responseCommand, byte[] thisResponseData, boolean isSequentialEnforced) {
91         KLF200Response.introLogging(logger, responseCommand, thisResponseData);
92         success = false;
93         finished = false;
94         Packet responseData = new Packet(thisResponseData);
95         switch (Command.get(responseCommand)) {
96             case GW_GET_SCENE_LIST_CFM:
97                 if (!KLF200Response.isLengthValid(logger, responseCommand, thisResponseData, 1)) {
98                     finished = true;
99                     break;
100                 }
101                 int ntfTotalNumberOfObjects = responseData.getOneByteValue(0);
102                 scenes = new VeluxScene[ntfTotalNumberOfObjects];
103                 if (ntfTotalNumberOfObjects == 0) {
104                     logger.trace("setResponse(): no scenes defined.");
105                     success = true;
106                     finished = true;
107                 } else {
108                     logger.trace("setResponse(): {} scenes defined.", ntfTotalNumberOfObjects);
109                 }
110                 sceneIdx = 0;
111                 break;
112             case GW_GET_SCENE_LIST_NTF:
113                 if (thisResponseData.length < 1) {
114                     logger.trace("setResponse(): malformed response packet (length is {} less than one).",
115                             thisResponseData.length);
116                     finished = true;
117                     break;
118                 }
119                 int ntfNumberOfObject = responseData.getOneByteValue(0);
120                 logger.trace("setResponse(): NTF number of objects={}.", ntfNumberOfObject);
121                 if (ntfNumberOfObject == 0) {
122                     logger.trace("setResponse(): finished.");
123                     finished = true;
124                     success = true;
125                 }
126                 if (thisResponseData.length != (2 + 65 * ntfNumberOfObject)) {
127                     logger.trace("setResponse(): malformed response packet (real length {}, expected length {}).",
128                             thisResponseData.length, (2 + 65 * ntfNumberOfObject));
129                     finished = true;
130                     break;
131                 }
132                 for (int objectIndex = 0; objectIndex < ntfNumberOfObject; objectIndex++) {
133                     int ntfSceneID = responseData.getOneByteValue(1 + 65 * objectIndex);
134                     int beginOfString = 2 + 65 * objectIndex;
135                     String ntfSceneName = responseData.getString(beginOfString, 64);
136                     logger.trace("setResponse(): scene {}, name {}.", ntfSceneID, ntfSceneName);
137                     scenes[sceneIdx++] = new VeluxScene(ntfSceneName, ntfSceneID, false, new VeluxProductState[0]);
138                 }
139                 int ntfRemainingNumberOfObject = responseData.getOneByteValue(1 + 65 * ntfNumberOfObject);
140                 logger.trace("setResponse(): {} scenes remaining.", ntfRemainingNumberOfObject);
141                 if (ntfRemainingNumberOfObject == 0) {
142                     logger.trace("setResponse(): finished.");
143                     finished = true;
144                     success = true;
145                 }
146                 break;
147             default:
148                 KLF200Response.errorLogging(logger, responseCommand);
149                 finished = true;
150         }
151         KLF200Response.outroLogging(logger, success, finished);
152     }
153
154     @Override
155     public boolean isCommunicationFinished() {
156         return finished;
157     }
158
159     @Override
160     public boolean isCommunicationSuccessful() {
161         return success;
162     }
163
164     /**
165      * ===========================================================
166      * <P>
167      * Public Methods required for abstract class {@link GetScenes}.
168      */
169     @Override
170     public VeluxScene[] getScenes() {
171         logger.trace("getScenes(): returning {} scenes.", scenes.length);
172         return scenes;
173     }
174 }