]> git.basschouten.com Git - openhab-addons.git/blob
7b49ca4f2ccc120819434ed70b7781c7b5342c43
[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.wolfsmartset.internal.handler;
14
15 import static org.openhab.binding.wolfsmartset.internal.WolfSmartsetBindingConstants.*;
16
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.concurrent.ConcurrentHashMap;
23
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;
47
48 /**
49  * The {@link WolfSmartsetSystemBridgeHandler} is the handler for a WolfSmartset system.
50  *
51  * @author Bo Biene - Initial contribution
52  */
53 @NonNullByDefault
54 public class WolfSmartsetSystemBridgeHandler extends BaseBridgeHandler {
55
56     private final Logger logger = LoggerFactory.getLogger(WolfSmartsetSystemBridgeHandler.class);
57
58     private @NonNullByDefault({}) String systemId;
59
60     private final Map<String, WolfSmartsetUnitThingHandler> unitHandlers = new ConcurrentHashMap<>();
61
62     private @Nullable GetSystemListDTO savedSystem;
63     private @Nullable List<SubMenuEntryWithMenuItemTabView> savedUnits;
64     private Map<String, State> stateCache = new ConcurrentHashMap<>();
65
66     public WolfSmartsetSystemBridgeHandler(Bridge bridge) {
67         super(bridge);
68     }
69
70     @Override
71     public void initialize() {
72         systemId = getConfigAs(WolfSmartsetSystemConfiguration.class).systemId;
73         logger.debug("SystemBridge: Initializing system '{}'", systemId);
74         clearSavedState();
75         updateStatus(WolfSmartsetUtils.isBridgeOnline(getBridge()) ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
76     }
77
78     @Override
79     public Collection<Class<? extends ThingHandlerService>> getServices() {
80         return Set.of(WolfSmartsetSystemDiscoveryService.class);
81     }
82
83     @Override
84     public void dispose() {
85         logger.debug("SystemBridge: Disposing system '{}'", systemId);
86     }
87
88     @Override
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();
96         }
97     }
98
99     @Override
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);
104     }
105
106     @Override
107     public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
108         if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
109             updateStatus(ThingStatus.ONLINE);
110         } else {
111             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
112         }
113     }
114
115     @Override
116     public void handleCommand(ChannelUID channelUID, Command command) {
117         if (command instanceof RefreshType) {
118             State state = stateCache.get(channelUID.getId());
119             if (state != null) {
120                 updateState(channelUID.getId(), state);
121             }
122         }
123     }
124
125     /**
126      * Return the associated account bridge handler
127      * 
128      * @return returns the {@link WolfSmartsetAccountBridgeHandler} linked to this
129      *         {@link WolfSmartsetSystemBridgeHandler}
130      */
131     public @Nullable WolfSmartsetAccountBridgeHandler getAccountBridgeHandler() {
132         var bridgeHandler = this.getBridge();
133         if (bridgeHandler != null) {
134             return (WolfSmartsetAccountBridgeHandler) bridgeHandler.getHandler();
135         }
136         return null;
137     }
138
139     /**
140      * Return the subordinated unit handler
141      * 
142      * @return a List of {@link WolfSmartsetUnitThingHandler} with the subordinated unit handler
143      */
144     public Collection<WolfSmartsetUnitThingHandler> getUnitHandler() {
145         return unitHandlers.values();
146     }
147
148     /**
149      * Returns the list configuration of the units available for this system
150      * 
151      * @return a list of {@link SubMenuEntryWithMenuItemTabView} representing the available units for this system
152      */
153     public List<SubMenuEntryWithMenuItemTabView> getUnits() {
154         List<SubMenuEntryWithMenuItemTabView> localSavedUnits = savedUnits;
155         return localSavedUnits == null ? EMPTY_UNITS : localSavedUnits;
156     }
157
158     /**
159      * Return the configuration of this system
160      * 
161      * @return {@link GetSystemListDTO} representing the this system
162      */
163     public @Nullable GetSystemListDTO getSystemConfig() {
164         return savedSystem;
165     }
166
167     /**
168      * Return the id of this system
169      * 
170      * @return the id of this system
171      */
172     public String getSystemId() {
173         return systemId;
174     }
175
176     /**
177      * Update the system state with the dto
178      * 
179      * @param systemState {@link GetSystemStateListDTO} the dto representing the current state of this system
180      */
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");
191             }
192         }
193     }
194
195     /**
196      * Process the available fault messages
197      * 
198      * @param faultMessages {@link ReadFaultMessagesDTO} the dto representing the list of the current faultmessages
199      */
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());
206                 }
207             }
208         }
209     }
210
211     /**
212      * Update the configuration of the system and the subordinated units
213      * 
214      * @param system {@link GetSystemListDTO} representing this system
215      * @param systemDescription {@link GetGuiDescriptionForGatewayDTO} repesenting the units of this system
216      */
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;
223
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);
234
235             updateUnitsConfiguration(systemDescription);
236         } else {
237             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
238                     "Unable to retrieve configuration");
239         }
240     }
241
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();
246
247         if (fachmannNode.isPresent()) {
248             for (var submenu : fachmannNode.get().getSubMenuEntries()) {
249                 for (var tabmenu : submenu.getTabViews()) {
250                     listUnits.add(new SubMenuEntryWithMenuItemTabView(submenu, tabmenu));
251
252                     var handler = unitHandlers.get(tabmenu.bundleId.toString());
253                     if (handler != null) {
254                         handler.updateConfiguration(submenu, tabmenu);
255                     }
256                 }
257             }
258
259         }
260         savedUnits = listUnits;
261     }
262
263     private void clearSavedState() {
264         savedSystem = null;
265         savedUnits = null;
266         stateCache.clear();
267     }
268 }