]> git.basschouten.com Git - openhab-addons.git/blob
2c336689882d94de310b832b6d5509532ea51874
[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.mielecloud.internal.webservice;
14
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.concurrent.CopyOnWriteArrayList;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.binding.mielecloud.internal.webservice.api.ActionsState;
22 import org.openhab.binding.mielecloud.internal.webservice.api.DeviceState;
23 import org.openhab.binding.mielecloud.internal.webservice.api.json.Actions;
24 import org.openhab.binding.mielecloud.internal.webservice.api.json.DeviceCollection;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * Handles event dispatching to {@link DeviceStateListener}s.
30  *
31  * @author Björn Lange - Initial contribution
32  */
33 @NonNullByDefault
34 public class DeviceStateDispatcher {
35     private final Logger logger = LoggerFactory.getLogger(this.getClass());
36
37     private final List<DeviceStateListener> listeners = new CopyOnWriteArrayList<>();
38     private Set<String> previousDeviceIdentifiers = new HashSet<>();
39     private final DeviceCache cache = new DeviceCache();
40
41     /**
42      * Adds a listener. The listener will be immediately invoked with the current status of all known devices.
43      *
44      * @param listener The listener to add.
45      */
46     public void addListener(DeviceStateListener listener) {
47         if (listeners.contains(listener)) {
48             logger.warn("Listener '{}' was registered multiple times.", listener);
49         }
50         listeners.add(listener);
51
52         cache.getDeviceIds().forEach(deviceIdentifier -> cache.getDevice(deviceIdentifier)
53                 .ifPresent(device -> listener.onDeviceStateUpdated(new DeviceState(deviceIdentifier, device))));
54     }
55
56     /**
57      * Removes a listener.
58      */
59     public void removeListener(DeviceStateListener listener) {
60         listeners.remove(listener);
61     }
62
63     /**
64      * Clears the internal device state cache.
65      */
66     public void clearCache() {
67         cache.clear();
68     }
69
70     /**
71      * Dispatches device status updates to all registered {@link DeviceStateListener}. This includes device removal.
72      *
73      * @param devices {@link DeviceCollection} which contains the state information to dispatch.
74      */
75     public void dispatchDeviceStateUpdates(DeviceCollection devices) {
76         cache.replaceAllDevices(devices);
77         dispatchDevicesRemoved(devices);
78         cache.getDeviceIds().forEach(this::dispatchDeviceState);
79     }
80
81     /**
82      * Dispatches the cached state of the device identified by the given device identifier.
83      */
84     public void dispatchDeviceState(String deviceIdentifier) {
85         cache.getDevice(deviceIdentifier).ifPresent(device -> listeners
86                 .forEach(listener -> listener.onDeviceStateUpdated(new DeviceState(deviceIdentifier, device))));
87     }
88
89     /**
90      * Dispatches device action updates to all registered {@link DeviceStateListener}.
91      *
92      * @param deviceId ID of the device to dispatch the {@link Actions} for.
93      * @param actions {@link Actions} to dispatch.
94      */
95     public void dispatchActionStateUpdates(String deviceId, Actions actions) {
96         listeners.forEach(listener -> listener.onProcessActionUpdated(new ActionsState(deviceId, actions)));
97     }
98
99     private void dispatchDevicesRemoved(DeviceCollection devices) {
100         Set<String> presentDeviceIdentifiers = devices.getDeviceIdentifiers();
101         Set<String> removedDeviceIdentifiers = previousDeviceIdentifiers;
102         removedDeviceIdentifiers.removeAll(presentDeviceIdentifiers);
103
104         previousDeviceIdentifiers = devices.getDeviceIdentifiers();
105
106         removedDeviceIdentifiers
107                 .forEach(deviceIdentifier -> listeners.forEach(listener -> listener.onDeviceRemoved(deviceIdentifier)));
108     }
109 }