]> git.basschouten.com Git - openhab-addons.git/blob
94c3a0a89bf19f8db2874652d9a21242171b1e5f
[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.digitalstrom.internal.discovery;
14
15 import java.util.HashMap;
16 import java.util.Hashtable;
17 import java.util.Map;
18
19 import org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants;
20 import org.openhab.binding.digitalstrom.internal.handler.BridgeHandler;
21 import org.openhab.binding.digitalstrom.internal.handler.CircuitHandler;
22 import org.openhab.binding.digitalstrom.internal.handler.DeviceHandler;
23 import org.openhab.binding.digitalstrom.internal.handler.SceneHandler;
24 import org.openhab.binding.digitalstrom.internal.handler.ZoneTemperatureControlHandler;
25 import org.openhab.binding.digitalstrom.internal.lib.climate.TemperatureControlSensorTransmitter;
26 import org.openhab.binding.digitalstrom.internal.lib.climate.jsonresponsecontainer.impl.TemperatureControlStatus;
27 import org.openhab.binding.digitalstrom.internal.lib.listener.DeviceStatusListener;
28 import org.openhab.binding.digitalstrom.internal.lib.listener.SceneStatusListener;
29 import org.openhab.binding.digitalstrom.internal.lib.listener.TemperatureControlStatusListener;
30 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.Circuit;
31 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.Device;
32 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.GeneralDeviceInformation;
33 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.DeviceStateUpdate;
34 import org.openhab.binding.digitalstrom.internal.lib.structure.devices.deviceparameters.constants.ChangeableDeviceConfigEnum;
35 import org.openhab.binding.digitalstrom.internal.lib.structure.scene.InternalScene;
36 import org.openhab.binding.digitalstrom.internal.providers.DsDeviceThingTypeProvider;
37 import org.openhab.core.config.discovery.AbstractDiscoveryService;
38 import org.openhab.core.config.discovery.DiscoveryService;
39 import org.openhab.core.thing.ThingTypeUID;
40 import org.osgi.framework.BundleContext;
41 import org.osgi.framework.ServiceRegistration;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 /**
46  * The {@link DiscoveryServiceManager} manages the different scene and device discovery services and informs them about
47  * new added or removed scenes and devices.
48  *
49  * @author Michael Ochel - Initial contribution
50  * @author Matthias Siegele - Initial contribution
51  */
52 public class DiscoveryServiceManager
53         implements SceneStatusListener, DeviceStatusListener, TemperatureControlStatusListener {
54
55     private final Logger logger = LoggerFactory.getLogger(DiscoveryServiceManager.class);
56
57     private final Map<String, AbstractDiscoveryService> discoveryServices;
58     private final Map<String, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
59     private final String bridgeUID;
60
61     /**
62      * Creates a new {@link DiscoveryServiceManager} and generates automatically all {@link SceneDiscoveryService}s and
63      * {@link org.openhab.binding.digitalstrom.internal.discovery.DeviceDiscoveryService}s for all supported
64      * {@link org.openhab.core.thing.type.ThingType}s of the
65      * {@link org.openhab.binding.digitalstrom.internal.handler.DeviceHandler} and {@link SceneHandler}.
66      *
67      * @param bridgeHandler (must not be null)
68      */
69     public DiscoveryServiceManager(BridgeHandler bridgeHandler) {
70         bridgeUID = bridgeHandler.getThing().getUID().getAsString();
71         discoveryServices = new HashMap<>(SceneHandler.SUPPORTED_THING_TYPES.size()
72                 + DeviceHandler.SUPPORTED_THING_TYPES.size() + CircuitHandler.SUPPORTED_THING_TYPES.size()
73                 + ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES.size());
74         for (ThingTypeUID type : SceneHandler.SUPPORTED_THING_TYPES) {
75             discoveryServices.put(type.getId(), new SceneDiscoveryService(bridgeHandler, type));
76         }
77         for (ThingTypeUID type : DeviceHandler.SUPPORTED_THING_TYPES) {
78             discoveryServices.put(type.getId(), new DeviceDiscoveryService(bridgeHandler, type));
79         }
80         for (ThingTypeUID type : CircuitHandler.SUPPORTED_THING_TYPES) {
81             discoveryServices.put(type.getId(), new DeviceDiscoveryService(bridgeHandler, type));
82         }
83         for (ThingTypeUID type : ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES) {
84             discoveryServices.put(type.getId(), new ZoneTemperatureControlDiscoveryService(bridgeHandler, type));
85         }
86         bridgeHandler.registerSceneStatusListener(this);
87         bridgeHandler.registerDeviceStatusListener(this);
88         bridgeHandler.registerTemperatureControlStatusListener(this);
89     }
90
91     /**
92      * Deactivates all {@link SceneDiscoveryService}s and {@link DeviceDiscoveryService}s of this
93      * {@link DiscoveryServiceManager} and unregisters them from the given {@link BundleContext}.
94      *
95      * @param bundleContext (must not be null)
96      */
97     public void unregisterDiscoveryServices(BundleContext bundleContext) {
98         if (discoveryServices != null) {
99             for (AbstractDiscoveryService service : discoveryServices.values()) {
100                 if (service instanceof SceneDiscoveryService sceneDisServ) {
101                     ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(bridgeUID + sceneDisServ.getID());
102                     sceneDisServ.deactivate();
103                     serviceReg.unregister();
104                     discoveryServiceRegs.remove(bridgeUID + sceneDisServ.getID());
105                 }
106                 if (service instanceof DeviceDiscoveryService devDisServ) {
107                     ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(bridgeUID + devDisServ.getID());
108                     devDisServ.deactivate();
109                     serviceReg.unregister();
110                     discoveryServiceRegs.remove(bridgeUID + devDisServ.getID());
111                 }
112                 if (service instanceof ZoneTemperatureControlDiscoveryService devDisServ) {
113                     ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(bridgeUID + devDisServ.getID());
114                     devDisServ.deactivate();
115                     serviceReg.unregister();
116                     discoveryServiceRegs.remove(bridgeUID + devDisServ.getID());
117                 }
118             }
119         }
120     }
121
122     /**
123      * Registers all {@link SceneDiscoveryService}s and {@link DeviceDiscoveryService}s of this
124      * {@link DiscoveryServiceManager} to the given {@link BundleContext}.
125      *
126      * @param bundleContext (must not be null)
127      */
128     public void registerDiscoveryServices(BundleContext bundleContext) {
129         if (discoveryServices != null) {
130             for (AbstractDiscoveryService service : discoveryServices.values()) {
131                 if (service instanceof SceneDiscoveryService discoveryService) {
132                     this.discoveryServiceRegs.put(bridgeUID + discoveryService.getID(), bundleContext
133                             .registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
134                 }
135                 if (service instanceof DeviceDiscoveryService discoveryService) {
136                     this.discoveryServiceRegs.put(bridgeUID + discoveryService.getID(), bundleContext
137                             .registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
138                 }
139                 if (service instanceof ZoneTemperatureControlDiscoveryService discoveryService) {
140                     this.discoveryServiceRegs.put(bridgeUID + discoveryService.getID(), bundleContext
141                             .registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
142                 }
143             }
144         }
145     }
146
147     @Override
148     public String getSceneStatusListenerID() {
149         return SceneStatusListener.SCENE_DISCOVERY;
150     }
151
152     @Override
153     public void onSceneStateChanged(boolean flag) {
154         // nothing to do
155     }
156
157     @Override
158     public void onSceneRemoved(InternalScene scene) {
159         if (discoveryServices.get(scene.getSceneType()) != null) {
160             ((SceneDiscoveryService) discoveryServices.get(scene.getSceneType())).onSceneRemoved(scene);
161         }
162     }
163
164     @Override
165     public void onSceneAdded(InternalScene scene) {
166         if (discoveryServices.get(scene.getSceneType()) != null) {
167             ((SceneDiscoveryService) discoveryServices.get(scene.getSceneType())).onSceneAdded(scene);
168         }
169     }
170
171     @Override
172     public void onDeviceStateChanged(DeviceStateUpdate deviceStateUpdate) {
173         // nothing to do
174     }
175
176     @Override
177     public void onDeviceRemoved(GeneralDeviceInformation device) {
178         if (device instanceof Device dev) {
179             String id = dev.getHWinfo().substring(0, 2);
180             if (dev.isSensorDevice()) {
181                 id = dev.getHWinfo().replace("-", "");
182             }
183             if (discoveryServices.get(id) != null) {
184                 ((DeviceDiscoveryService) discoveryServices.get(id)).onDeviceRemoved(device);
185             }
186         }
187         if (device instanceof Circuit) {
188             if (discoveryServices.get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString()) != null) {
189                 ((DeviceDiscoveryService) discoveryServices
190                         .get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString())).onDeviceRemoved(device);
191             }
192         }
193     }
194
195     @Override
196     public void onDeviceAdded(GeneralDeviceInformation device) {
197         try {
198             if (device instanceof Device dev) {
199                 String id = dev.getHWinfo().substring(0, 2);
200                 if (dev.isSensorDevice()) {
201                     id = dev.getHWinfo();
202                 }
203                 if (discoveryServices.get(id) != null) {
204                     ((DeviceDiscoveryService) discoveryServices.get(id)).onDeviceAdded(device);
205                 }
206             }
207             if (device instanceof Circuit) {
208                 if (discoveryServices.get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString()) != null) {
209                     ((DeviceDiscoveryService) discoveryServices
210                             .get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString()))
211                             .onDeviceAdded(device);
212                 }
213             }
214         } catch (RuntimeException ex) {
215             logger.warn("Unable to add devices {}", device, ex);
216         }
217     }
218
219     @Override
220     public void onDeviceConfigChanged(ChangeableDeviceConfigEnum whatConfig) {
221         // nothing to do
222     }
223
224     @Override
225     public void onSceneConfigAdded(short sceneId) {
226         // nothing to do
227     }
228
229     @Override
230     public String getDeviceStatusListenerID() {
231         return DeviceStatusListener.DEVICE_DISCOVERY;
232     }
233
234     @Override
235     public void configChanged(TemperatureControlStatus tempControlStatus) {
236         // currently only this thing-type exists
237         if (discoveryServices.get(DigitalSTROMBindingConstants.THING_TYPE_ZONE_TEMERATURE_CONTROL.toString()) != null) {
238             ((ZoneTemperatureControlDiscoveryService) discoveryServices
239                     .get(DigitalSTROMBindingConstants.THING_TYPE_ZONE_TEMERATURE_CONTROL.toString()))
240                     .configChanged(tempControlStatus);
241         }
242     }
243
244     @Override
245     public void registerTemperatureSensorTransmitter(
246             TemperatureControlSensorTransmitter temperatureSensorTransreciver) {
247         // nothing to do
248     }
249
250     @Override
251     public Integer getTemperationControlStatusListenrID() {
252         return TemperatureControlStatusListener.DISCOVERY;
253     }
254
255     @Override
256     public void onTargetTemperatureChanged(Float newValue) {
257         // nothing to do
258     }
259
260     @Override
261     public void onControlValueChanged(Integer newValue) {
262         // nothing to do
263     }
264 }