2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mielecloud.internal.webservice;
15 import java.util.HashSet;
16 import java.util.List;
18 import java.util.concurrent.CopyOnWriteArrayList;
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;
29 * Handles event dispatching to {@link DeviceStateListener}s.
31 * @author Björn Lange - Initial contribution
34 public class DeviceStateDispatcher {
35 private final Logger logger = LoggerFactory.getLogger(this.getClass());
37 private final List<DeviceStateListener> listeners = new CopyOnWriteArrayList<>();
38 private Set<String> previousDeviceIdentifiers = new HashSet<>();
39 private final DeviceCache cache = new DeviceCache();
42 * Adds a listener. The listener will be immediately invoked with the current status of all known devices.
44 * @param listener The listener to add.
46 public void addListener(DeviceStateListener listener) {
47 if (listeners.contains(listener)) {
48 logger.warn("Listener '{}' was registered multiple times.", listener);
50 listeners.add(listener);
52 cache.getDeviceIds().forEach(deviceIdentifier -> cache.getDevice(deviceIdentifier)
53 .ifPresent(device -> listener.onDeviceStateUpdated(new DeviceState(deviceIdentifier, device))));
59 public void removeListener(DeviceStateListener listener) {
60 listeners.remove(listener);
64 * Clears the internal device state cache.
66 public void clearCache() {
71 * Dispatches device status updates to all registered {@link DeviceStateListener}. This includes device removal.
73 * @param devices {@link DeviceCollection} which contains the state information to dispatch.
75 public void dispatchDeviceStateUpdates(DeviceCollection devices) {
76 cache.replaceAllDevices(devices);
77 dispatchDevicesRemoved(devices);
78 cache.getDeviceIds().forEach(this::dispatchDeviceState);
82 * Dispatches the cached state of the device identified by the given device identifier.
84 public void dispatchDeviceState(String deviceIdentifier) {
85 cache.getDevice(deviceIdentifier).ifPresent(device -> listeners
86 .forEach(listener -> listener.onDeviceStateUpdated(new DeviceState(deviceIdentifier, device))));
90 * Dispatches device action updates to all registered {@link DeviceStateListener}.
92 * @param deviceId ID of the device to dispatch the {@link Actions} for.
93 * @param actions {@link Actions} to dispatch.
95 public void dispatchActionStateUpdates(String deviceId, Actions actions) {
96 listeners.forEach(listener -> listener.onProcessActionUpdated(new ActionsState(deviceId, actions)));
99 private void dispatchDevicesRemoved(DeviceCollection devices) {
100 Set<String> presentDeviceIdentifiers = devices.getDeviceIdentifiers();
101 Set<String> removedDeviceIdentifiers = previousDeviceIdentifiers;
102 removedDeviceIdentifiers.removeAll(presentDeviceIdentifiers);
104 previousDeviceIdentifiers = devices.getDeviceIdentifiers();
106 removedDeviceIdentifiers
107 .forEach(deviceIdentifier -> listeners.forEach(listener -> listener.onDeviceRemoved(deviceIdentifier)));