2 * Copyright (c) 2010-2022 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.miele.internal.discovery;
15 import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.List;
23 import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
24 import org.openhab.binding.miele.internal.handler.ApplianceStatusListener;
25 import org.openhab.binding.miele.internal.handler.MieleApplianceHandler;
26 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler;
27 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceClassObject;
28 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty;
29 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.HomeDevice;
30 import org.openhab.core.config.discovery.AbstractDiscoveryService;
31 import org.openhab.core.config.discovery.DiscoveryResult;
32 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingTypeUID;
35 import org.openhab.core.thing.ThingUID;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The {@link MieleApplianceDiscoveryService} tracks appliances that are
41 * associated with the Miele@Home gateway
43 * @author Karel Goderis - Initial contribution
44 * @author Martin Lepsy - Added protocol information in order so support WiFi devices
45 * @author Jacob Laursen - Fixed multicast and protocol support (ZigBee/LAN)
47 public class MieleApplianceDiscoveryService extends AbstractDiscoveryService implements ApplianceStatusListener {
49 private final Logger logger = LoggerFactory.getLogger(MieleApplianceDiscoveryService.class);
51 private static final int SEARCH_TIME = 60;
53 private MieleBridgeHandler mieleBridgeHandler;
55 public MieleApplianceDiscoveryService(MieleBridgeHandler mieleBridgeHandler) {
56 super(MieleApplianceHandler.SUPPORTED_THING_TYPES, SEARCH_TIME, false);
57 this.mieleBridgeHandler = mieleBridgeHandler;
60 public void activate() {
61 mieleBridgeHandler.registerApplianceStatusListener(this);
65 public void deactivate() {
66 removeOlderResults(new Date().getTime());
67 mieleBridgeHandler.unregisterApplianceStatusListener(this);
71 public Set<ThingTypeUID> getSupportedThingTypes() {
72 return MieleApplianceHandler.SUPPORTED_THING_TYPES;
76 public void startScan() {
77 List<HomeDevice> appliances = mieleBridgeHandler.getHomeDevices();
78 if (appliances != null) {
79 for (HomeDevice l : appliances) {
80 onApplianceAddedInternal(l);
86 protected synchronized void stopScan() {
88 removeOlderResults(getTimestampOfLastScan());
92 public void onApplianceAdded(HomeDevice appliance) {
93 onApplianceAddedInternal(appliance);
96 private void onApplianceAddedInternal(HomeDevice appliance) {
97 ThingUID thingUID = getThingUID(appliance);
98 if (thingUID != null) {
99 ThingUID bridgeUID = mieleBridgeHandler.getThing().getUID();
100 Map<String, Object> properties = new HashMap<>(9);
102 FullyQualifiedApplianceIdentifier applianceIdentifier = appliance.getApplianceIdentifier();
103 properties.put(Thing.PROPERTY_VENDOR, appliance.Vendor);
104 properties.put(Thing.PROPERTY_MODEL_ID, appliance.getApplianceModel());
105 properties.put(Thing.PROPERTY_SERIAL_NUMBER, appliance.getSerialNumber());
106 properties.put(Thing.PROPERTY_FIRMWARE_VERSION, appliance.getFirmwareVersion());
107 properties.put(PROPERTY_PROTOCOL_ADAPTER, appliance.ProtocolAdapterName);
108 properties.put(APPLIANCE_ID, applianceIdentifier.getApplianceId());
109 String deviceClass = appliance.getDeviceClass();
110 if (deviceClass != null) {
111 properties.put(PROPERTY_DEVICE_CLASS, deviceClass);
113 String connectionType = appliance.getConnectionType();
114 if (connectionType != null) {
115 properties.put(PROPERTY_CONNECTION_TYPE, connectionType);
117 String connectionBaudRate = appliance.getConnectionBaudRate();
118 if (connectionBaudRate != null) {
119 properties.put(PROPERTY_CONNECTION_BAUD_RATE, connectionBaudRate);
122 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
123 .withBridge(bridgeUID).withLabel(deviceClass != null ? deviceClass : appliance.getApplianceModel())
124 .withRepresentationProperty(APPLIANCE_ID).build();
126 thingDiscovered(discoveryResult);
128 logger.debug("Discovered an unsupported appliance of vendor '{}' with id {}", appliance.Vendor,
134 public void onApplianceRemoved(HomeDevice appliance) {
135 ThingUID thingUID = getThingUID(appliance);
137 if (thingUID != null) {
138 thingRemoved(thingUID);
143 public void onApplianceStateChanged(FullyQualifiedApplianceIdentifier applianceIdentifier, DeviceClassObject dco) {
148 public void onAppliancePropertyChanged(FullyQualifiedApplianceIdentifier applianceIdentifier, DeviceProperty dp) {
152 private ThingUID getThingUID(HomeDevice appliance) {
153 ThingUID bridgeUID = mieleBridgeHandler.getThing().getUID();
154 String modelId = appliance.getDeviceClass();
156 if (modelId != null) {
157 ThingTypeUID thingTypeUID = getThingTypeUidFromModelId(modelId);
159 if (getSupportedThingTypes().contains(thingTypeUID)) {
160 ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, appliance.getApplianceIdentifier().getId());
170 private ThingTypeUID getThingTypeUidFromModelId(String modelId) {
172 * Coffee machine CVA 6805 is reported as CoffeeSystem, but thing type is
173 * coffeemachine. At least until it is known if any models are actually reported
174 * as CoffeeMachine, we need this special mapping.
176 if (MIELE_DEVICE_CLASS_COFFEE_SYSTEM.equals(modelId)) {
177 return THING_TYPE_COFFEEMACHINE;
180 String thingTypeId = modelId.replaceAll("[^a-zA-Z0-9_]", "_").toLowerCase();
182 return new ThingTypeUID(BINDING_ID, thingTypeId);