]> git.basschouten.com Git - openhab-addons.git/blob
08adb7284c1c454523acebc73b8a327213da46c3
[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.bluetooth.daikinmadoka.internal.model.commands;
14
15 import java.util.concurrent.Executor;
16 import java.util.concurrent.TimeUnit;
17 import java.util.concurrent.locks.Condition;
18 import java.util.concurrent.locks.Lock;
19 import java.util.concurrent.locks.ReentrantLock;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaMessage;
23 import org.openhab.binding.bluetooth.daikinmadoka.internal.model.MadokaParsingException;
24
25 /**
26  * Abstract class for all BLE commands sent to the controller
27  *
28  * @author Benjamin Lafois - Initial contribution
29  *
30  */
31 @NonNullByDefault
32 public abstract class BRC1HCommand {
33
34     public enum State {
35         NEW,
36         ENQUEUED,
37         SENT,
38         SUCCEEDED,
39         FAILED
40     }
41
42     private volatile State state = State.NEW;
43
44     private final Lock stateLock = new ReentrantLock();
45
46     private final Condition stateCondition = stateLock.newCondition();
47
48     public abstract void handleResponse(Executor executor, ResponseListener listener, MadokaMessage mm)
49             throws MadokaParsingException;
50
51     /**
52      * THis command returns the message to be sent
53      *
54      * @return
55      */
56     public abstract byte[][] getRequest();
57
58     /**
59      * This is the command number, in the protocol
60      *
61      * @return
62      */
63     public abstract int getCommandId();
64
65     /**
66      * Returns current state of the command.
67      *
68      * @return current state
69      */
70     public State getState() {
71         return state;
72     }
73
74     /**
75      * Sets state of the command.
76      *
77      * @param state new state
78      */
79     public void setState(State state) {
80         stateLock.lock();
81         try {
82             this.state = state;
83             stateCondition.signalAll();
84         } finally {
85             stateLock.unlock();
86         }
87     }
88
89     public boolean awaitStateChange(long timeout, TimeUnit unit, State... expectedStates) throws InterruptedException {
90         stateLock.lock();
91         try {
92             long nanosTimeout = unit.toNanos(timeout);
93             while (!isInAnyState(expectedStates)) {
94                 if (nanosTimeout <= 0L) {
95                     return false;
96                 }
97                 nanosTimeout = stateCondition.awaitNanos(nanosTimeout);
98             }
99         } finally {
100             stateLock.unlock();
101         }
102         return true;
103     }
104
105     private boolean isInAnyState(State[] acceptedStates) {
106         for (State acceptedState : acceptedStates) {
107             if (acceptedState == state) {
108                 return true;
109             }
110         }
111         return false;
112     }
113 }