]> git.basschouten.com Git - openhab-addons.git/blob
b2993208e5f36478951a85532872fea818c96f93
[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.rotel.internal.protocol;
14
15 import static org.openhab.binding.rotel.internal.RotelBindingConstants.*;
16
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.rotel.internal.RotelException;
23 import org.openhab.binding.rotel.internal.RotelModel;
24 import org.openhab.binding.rotel.internal.communication.RotelCommand;
25 import org.openhab.core.util.HexUtils;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Abstract class for handling a Rotel protocol (build of command messages, decoding of incoming data)
31  *
32  * @author Laurent Garnier - Initial contribution
33  */
34 @NonNullByDefault
35 public abstract class RotelAbstractProtocolHandler {
36
37     private final Logger logger = LoggerFactory.getLogger(RotelAbstractProtocolHandler.class);
38
39     protected final RotelModel model;
40
41     private final List<RotelMessageEventListener> listeners = new ArrayList<>();
42
43     /**
44      * Constructor
45      *
46      * @param model the Rotel model in use
47      */
48     public RotelAbstractProtocolHandler(RotelModel model) {
49         this.model = model;
50     }
51
52     public abstract RotelProtocol getProtocol();
53
54     /**
55      * Build the message associated to a Rotel command
56      *
57      * @param cmd the command to execute
58      * @param value the integer value to consider for volume, bass or treble adjustment
59      *
60      * @throws RotelException - In case the command is not supported by the protocol
61      */
62     public abstract byte[] buildCommandMessage(RotelCommand cmd, @Nullable Integer value) throws RotelException;
63
64     public abstract void handleIncomingData(byte[] inDataBuffer, int length);
65
66     public void handleInIncomingError() {
67         dispatchKeyValue(KEY_ERROR, MSG_VALUE_ON);
68     }
69
70     /**
71      * Analyze an incoming message and dispatch corresponding (key, value) to the event listeners
72      *
73      * @param incomingMessage the received message
74      */
75     protected void handleIncomingMessage(byte[] incomingMessage) {
76         logger.debug("handleIncomingMessage: bytes {}", HexUtils.bytesToHex(incomingMessage));
77
78         try {
79             validateResponse(incomingMessage);
80         } catch (RotelException e) {
81             return;
82         }
83
84         handleValidMessage(incomingMessage);
85     }
86
87     /**
88      * Validate the content of a feedback message
89      *
90      * @param responseMessage the buffer containing the feedback message
91      *
92      * @throws RotelException - If the message has unexpected content
93      */
94     protected abstract void validateResponse(byte[] responseMessage) throws RotelException;
95
96     /**
97      * Analyze a valid HEX message and dispatch corresponding (key, value) to the event listeners
98      *
99      * @param incomingMessage the received message
100      */
101     protected abstract void handleValidMessage(byte[] incomingMessage);
102
103     /**
104      * Add a listener to the list of listeners to be notified with events
105      *
106      * @param listener the listener
107      */
108     public void addEventListener(RotelMessageEventListener listener) {
109         listeners.add(listener);
110     }
111
112     /**
113      * Remove a listener from the list of listeners to be notified with events
114      *
115      * @param listener the listener
116      */
117     public void removeEventListener(RotelMessageEventListener listener) {
118         listeners.remove(listener);
119     }
120
121     /**
122      * Dispatch an event (key, value) to the event listeners
123      *
124      * @param key the key
125      * @param value the value
126      */
127     protected void dispatchKeyValue(String key, String value) {
128         RotelMessageEvent event = new RotelMessageEvent(this, key, value);
129         for (int i = 0; i < listeners.size(); i++) {
130             listeners.get(i).onNewMessageEvent(event);
131         }
132     }
133 }