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.wolfsmartset.internal.handler;
15 import static org.openhab.binding.wolfsmartset.internal.WolfSmartsetBindingConstants.*;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.List;
22 import java.util.concurrent.ConcurrentHashMap;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.wolfsmartset.internal.config.WolfSmartsetSystemConfiguration;
27 import org.openhab.binding.wolfsmartset.internal.discovery.WolfSmartsetSystemDiscoveryService;
28 import org.openhab.binding.wolfsmartset.internal.dto.GetGuiDescriptionForGatewayDTO;
29 import org.openhab.binding.wolfsmartset.internal.dto.GetSystemListDTO;
30 import org.openhab.binding.wolfsmartset.internal.dto.GetSystemStateListDTO;
31 import org.openhab.binding.wolfsmartset.internal.dto.ReadFaultMessagesDTO;
32 import org.openhab.binding.wolfsmartset.internal.dto.SubMenuEntryWithMenuItemTabView;
33 import org.openhab.core.thing.Bridge;
34 import org.openhab.core.thing.ChannelUID;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingStatus;
37 import org.openhab.core.thing.ThingStatusDetail;
38 import org.openhab.core.thing.ThingStatusInfo;
39 import org.openhab.core.thing.binding.BaseBridgeHandler;
40 import org.openhab.core.thing.binding.ThingHandler;
41 import org.openhab.core.thing.binding.ThingHandlerService;
42 import org.openhab.core.types.Command;
43 import org.openhab.core.types.RefreshType;
44 import org.openhab.core.types.State;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
49 * The {@link WolfSmartsetSystemBridgeHandler} is the handler for a WolfSmartset system.
51 * @author Bo Biene - Initial contribution
54 public class WolfSmartsetSystemBridgeHandler extends BaseBridgeHandler {
56 private final Logger logger = LoggerFactory.getLogger(WolfSmartsetSystemBridgeHandler.class);
58 private @NonNullByDefault({}) String systemId;
60 private final Map<String, WolfSmartsetUnitThingHandler> unitHandlers = new ConcurrentHashMap<>();
62 private @Nullable GetSystemListDTO savedSystem;
63 private @Nullable List<SubMenuEntryWithMenuItemTabView> savedUnits;
64 private Map<String, State> stateCache = new ConcurrentHashMap<>();
66 public WolfSmartsetSystemBridgeHandler(Bridge bridge) {
71 public void initialize() {
72 systemId = getConfigAs(WolfSmartsetSystemConfiguration.class).systemId;
73 logger.debug("SystemBridge: Initializing system '{}'", systemId);
75 updateStatus(WolfSmartsetUtils.isBridgeOnline(getBridge()) ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
79 public Collection<Class<? extends ThingHandlerService>> getServices() {
80 return Collections.singleton(WolfSmartsetSystemDiscoveryService.class);
84 public void dispose() {
85 logger.debug("SystemBridge: Disposing system '{}'", systemId);
89 public void childHandlerInitialized(ThingHandler unitHandler, Thing unitThing) {
90 String unitId = (String) unitThing.getConfiguration().get(CONFIG_UNIT_ID);
91 unitHandlers.put(unitId, (WolfSmartsetUnitThingHandler) unitHandler);
92 logger.debug("SystemBridge: Saving unit handler for {} with id {}", unitThing.getUID(), unitId);
93 var accountBridgeHandler = getAccountBridgeHandler();
94 if (accountBridgeHandler != null) {
95 accountBridgeHandler.scheduleRefreshJob();
100 public void childHandlerDisposed(ThingHandler unitHandler, Thing unitThing) {
101 String unitId = (String) unitThing.getConfiguration().get(CONFIG_UNIT_ID);
102 unitHandlers.remove(unitId);
103 logger.debug("SystemBridge: Removing unit handler for {} with id {}", unitThing.getUID(), unitId);
107 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
108 if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
109 updateStatus(ThingStatus.ONLINE);
111 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
116 public void handleCommand(ChannelUID channelUID, Command command) {
117 if (command instanceof RefreshType) {
118 State state = stateCache.get(channelUID.getId());
120 updateState(channelUID.getId(), state);
126 * Return the associated account bridge handler
128 * @return returns the {@link WolfSmartsetAccountBridgeHandler} linked to this
129 * {@link WolfSmartsetSystemBridgeHandler}
131 public @Nullable WolfSmartsetAccountBridgeHandler getAccountBridgeHandler() {
132 var bridgeHandler = this.getBridge();
133 if (bridgeHandler != null) {
134 return (WolfSmartsetAccountBridgeHandler) bridgeHandler.getHandler();
140 * Return the subordinated unit handler
142 * @return a List of {@link WolfSmartsetUnitThingHandler} with the subordinated unit handler
144 public Collection<WolfSmartsetUnitThingHandler> getUnitHandler() {
145 return unitHandlers.values();
149 * Returns the list configuration of the units available for this system
151 * @return a list of {@link SubMenuEntryWithMenuItemTabView} representing the available units for this system
153 public List<SubMenuEntryWithMenuItemTabView> getUnits() {
154 List<SubMenuEntryWithMenuItemTabView> localSavedUnits = savedUnits;
155 return localSavedUnits == null ? EMPTY_UNITS : localSavedUnits;
159 * Return the configuration of this system
161 * @return {@link GetSystemListDTO} representing the this system
163 public @Nullable GetSystemListDTO getSystemConfig() {
168 * Return the id of this system
170 * @return the id of this system
172 public String getSystemId() {
177 * Update the system state with the dto
179 * @param systemState {@link GetSystemStateListDTO} the dto representing the current state of this system
181 public void updateSystemState(@Nullable GetSystemStateListDTO systemState) {
182 if (systemState != null) {
183 if (systemState.getIsSystemDeleted()) {
184 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "System has been deleted");
185 } else if (systemState.getIsSystemShareDeleted()) {
186 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
187 "System share has been removed");
188 } else if (systemState.getIsSystemShareRejected()) {
189 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
190 "System share has been rejected");
196 * Process the available fault messages
198 * @param faultMessages {@link ReadFaultMessagesDTO} the dto representing the list of the current faultmessages
200 public void updateFaultMessages(@Nullable ReadFaultMessagesDTO faultMessages) {
201 if (faultMessages != null) {
202 if (faultMessages.getCurrentMessages() != null) {
203 for (var message : faultMessages.getCurrentMessages()) {
204 logger.warn("System {} faultmessage: {}, since {}", systemId, message.getDescription(),
205 message.getOccurTimeLocal());
212 * Update the configuration of the system and the subordinated units
214 * @param system {@link GetSystemListDTO} representing this system
215 * @param systemDescription {@link GetGuiDescriptionForGatewayDTO} repesenting the units of this system
217 public void updateConfiguration(@Nullable GetSystemListDTO system,
218 @Nullable GetGuiDescriptionForGatewayDTO systemDescription) {
219 if (system != null && systemDescription != null) {
220 logger.debug("SystemBridge: Updating channels for system id {}, name {}", system.getId(), system.getName());
221 updateStatus(ThingStatus.ONLINE);
222 savedSystem = system;
224 Map<String, String> properties = editProperties();
225 properties.put(Thing.PROPERTY_FIRMWARE_VERSION, system.getGatewaySoftwareVersion());
226 properties.put(THING_PROPERTY_GATEWAY_ID, system.getGatewayId().toString());
227 properties.put(THING_PROPERTY_GATEWAY_USERNAME, system.getGatewayUsername());
228 properties.put(THING_PROPERTY_INSTALLATION_DATE, system.getInstallationDate());
229 properties.put(THING_PROPERTY_LOCATION, system.getLocation());
230 properties.put(THING_PROPERTY_OPERATOR_NAME, system.getOperatorName());
231 properties.put(THING_PROPERTY_USERNAME_OWNER, system.getUserNameOwner());
232 properties.put(THING_PROPERTY_ACCESSLEVEL, system.getAccessLevel().toString());
233 updateProperties(properties);
235 updateUnitsConfiguration(systemDescription);
237 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
238 "Unable to retrieve configuration");
242 private void updateUnitsConfiguration(GetGuiDescriptionForGatewayDTO systemDescription) {
243 List<SubMenuEntryWithMenuItemTabView> listUnits = new ArrayList<>();
244 var fachmannNode = systemDescription.getMenuItems().stream()
245 .filter(m -> "Fachmann".equalsIgnoreCase(m.getName())).findFirst();
247 if (fachmannNode.isPresent()) {
248 for (var submenu : fachmannNode.get().getSubMenuEntries()) {
249 for (var tabmenu : submenu.getTabViews()) {
250 listUnits.add(new SubMenuEntryWithMenuItemTabView(submenu, tabmenu));
252 var handler = unitHandlers.get(tabmenu.bundleId.toString());
253 if (handler != null) {
254 handler.updateConfiguration(submenu, tabmenu);
260 savedUnits = listUnits;
263 private void clearSavedState() {