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.digitalstrom.internal.discovery;
15 import java.util.HashMap;
16 import java.util.Hashtable;
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.openhab.core.thing.type.ThingType;
41 import org.osgi.framework.BundleContext;
42 import org.osgi.framework.ServiceRegistration;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * The {@link DiscoveryServiceManager} manages the different scene and device discovery services and informs them about
48 * new added or removed scenes and devices.
50 * @author Michael Ochel - Initial contribution
51 * @author Matthias Siegele - Initial contribution
53 public class DiscoveryServiceManager
54 implements SceneStatusListener, DeviceStatusListener, TemperatureControlStatusListener {
56 private final Logger logger = LoggerFactory.getLogger(DiscoveryServiceManager.class);
58 private final Map<String, AbstractDiscoveryService> discoveryServices;
59 private final Map<String, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
60 private final String bridgeUID;
63 * Creates a new {@link DiscoveryServiceManager} and generates automatically all {@link SceneDiscoveryService}s and
64 * {@link DeviceDiscoveryService}s for all supported {@link ThingType}s of the {@link DeviceHandler} and
65 * {@link SceneHandler}.
67 * @param bridgeHandler (must not be null)
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));
77 for (ThingTypeUID type : DeviceHandler.SUPPORTED_THING_TYPES) {
78 discoveryServices.put(type.getId(), new DeviceDiscoveryService(bridgeHandler, type));
80 for (ThingTypeUID type : CircuitHandler.SUPPORTED_THING_TYPES) {
81 discoveryServices.put(type.getId(), new DeviceDiscoveryService(bridgeHandler, type));
83 for (ThingTypeUID type : ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES) {
84 discoveryServices.put(type.getId(), new ZoneTemperatureControlDiscoveryService(bridgeHandler, type));
86 bridgeHandler.registerSceneStatusListener(this);
87 bridgeHandler.registerDeviceStatusListener(this);
88 bridgeHandler.registerTemperatureControlStatusListener(this);
92 * Deactivates all {@link SceneDiscoveryService}s and {@link DeviceDiscoveryService}s of this
93 * {@link DiscoveryServiceManager} and unregisters them from the given {@link BundleContext}.
95 * @param bundleContext (must not be null)
97 public void unregisterDiscoveryServices(BundleContext bundleContext) {
98 if (discoveryServices != null) {
99 for (AbstractDiscoveryService service : discoveryServices.values()) {
100 if (service instanceof SceneDiscoveryService) {
101 SceneDiscoveryService sceneDisServ = (SceneDiscoveryService) service;
102 ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(bridgeUID + sceneDisServ.getID());
103 sceneDisServ.deactivate();
104 serviceReg.unregister();
105 discoveryServiceRegs.remove(bridgeUID + sceneDisServ.getID());
107 if (service instanceof DeviceDiscoveryService) {
108 DeviceDiscoveryService devDisServ = (DeviceDiscoveryService) service;
109 ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(bridgeUID + devDisServ.getID());
110 devDisServ.deactivate();
111 serviceReg.unregister();
112 discoveryServiceRegs.remove(bridgeUID + devDisServ.getID());
114 if (service instanceof ZoneTemperatureControlDiscoveryService) {
115 ZoneTemperatureControlDiscoveryService devDisServ = (ZoneTemperatureControlDiscoveryService) service;
116 ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.get(bridgeUID + devDisServ.getID());
117 devDisServ.deactivate();
118 serviceReg.unregister();
119 discoveryServiceRegs.remove(bridgeUID + devDisServ.getID());
126 * Registers all {@link SceneDiscoveryService}s and {@link DeviceDiscoveryService}s of this
127 * {@link DiscoveryServiceManager} to the given {@link BundleContext}.
129 * @param bundleContext (must not be null)
131 public void registerDiscoveryServices(BundleContext bundleContext) {
132 if (discoveryServices != null) {
133 for (AbstractDiscoveryService service : discoveryServices.values()) {
134 if (service instanceof SceneDiscoveryService) {
135 this.discoveryServiceRegs.put(bridgeUID + ((SceneDiscoveryService) service).getID(), bundleContext
136 .registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
138 if (service instanceof DeviceDiscoveryService) {
139 this.discoveryServiceRegs.put(bridgeUID + ((DeviceDiscoveryService) service).getID(), bundleContext
140 .registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
142 if (service instanceof ZoneTemperatureControlDiscoveryService) {
143 this.discoveryServiceRegs
144 .put(bridgeUID + ((ZoneTemperatureControlDiscoveryService) service).getID(), bundleContext
145 .registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
152 public String getSceneStatusListenerID() {
153 return SceneStatusListener.SCENE_DISCOVERY;
157 public void onSceneStateChanged(boolean flag) {
162 public void onSceneRemoved(InternalScene scene) {
163 if (discoveryServices.get(scene.getSceneType()) != null) {
164 ((SceneDiscoveryService) discoveryServices.get(scene.getSceneType())).onSceneRemoved(scene);
169 public void onSceneAdded(InternalScene scene) {
170 if (discoveryServices.get(scene.getSceneType()) != null) {
171 ((SceneDiscoveryService) discoveryServices.get(scene.getSceneType())).onSceneAdded(scene);
176 public void onDeviceStateChanged(DeviceStateUpdate deviceStateUpdate) {
181 public void onDeviceRemoved(GeneralDeviceInformation device) {
182 if (device instanceof Device) {
183 String id = ((Device) device).getHWinfo().substring(0, 2);
184 if (((Device) device).isSensorDevice()) {
185 id = ((Device) device).getHWinfo().replace("-", "");
187 if (discoveryServices.get(id) != null) {
188 ((DeviceDiscoveryService) discoveryServices.get(id)).onDeviceRemoved(device);
191 if (device instanceof Circuit) {
192 if (discoveryServices.get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString()) != null) {
193 ((DeviceDiscoveryService) discoveryServices
194 .get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString())).onDeviceRemoved(device);
200 public void onDeviceAdded(GeneralDeviceInformation device) {
202 if (device instanceof Device) {
203 String id = ((Device) device).getHWinfo().substring(0, 2);
204 if (((Device) device).isSensorDevice()) {
205 id = ((Device) device).getHWinfo();
207 if (discoveryServices.get(id) != null) {
208 ((DeviceDiscoveryService) discoveryServices.get(id)).onDeviceAdded(device);
211 if (device instanceof Circuit) {
212 if (discoveryServices.get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString()) != null) {
213 ((DeviceDiscoveryService) discoveryServices
214 .get(DsDeviceThingTypeProvider.SupportedThingTypes.circuit.toString()))
215 .onDeviceAdded(device);
218 } catch (RuntimeException ex) {
219 logger.warn("Unable to add devices {}", device, ex);
224 public void onDeviceConfigChanged(ChangeableDeviceConfigEnum whatConfig) {
229 public void onSceneConfigAdded(short sceneId) {
234 public String getDeviceStatusListenerID() {
235 return DeviceStatusListener.DEVICE_DISCOVERY;
239 public void configChanged(TemperatureControlStatus tempControlStatus) {
240 // currently only this thing-type exists
241 if (discoveryServices.get(DigitalSTROMBindingConstants.THING_TYPE_ZONE_TEMERATURE_CONTROL.toString()) != null) {
242 ((ZoneTemperatureControlDiscoveryService) discoveryServices
243 .get(DigitalSTROMBindingConstants.THING_TYPE_ZONE_TEMERATURE_CONTROL.toString()))
244 .configChanged(tempControlStatus);
249 public void registerTemperatureSensorTransmitter(
250 TemperatureControlSensorTransmitter temperatureSensorTransreciver) {
255 public Integer getTemperationControlStatusListenrID() {
256 return TemperatureControlStatusListener.DISCOVERY;
260 public void onTargetTemperatureChanged(Float newValue) {
265 public void onControlValueChanged(Integer newValue) {