]> git.basschouten.com Git - openhab-addons.git/blob
cf9bd30cfe921ac91a6a87438795a92c5d6337af
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.miele.internal.discovery;
14
15 import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
16
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
26 import org.openhab.binding.miele.internal.api.dto.DeviceClassObject;
27 import org.openhab.binding.miele.internal.api.dto.DeviceProperty;
28 import org.openhab.binding.miele.internal.api.dto.HomeDevice;
29 import org.openhab.binding.miele.internal.handler.ApplianceStatusListener;
30 import org.openhab.binding.miele.internal.handler.MieleApplianceHandler;
31 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler;
32 import org.openhab.core.config.discovery.AbstractDiscoveryService;
33 import org.openhab.core.config.discovery.DiscoveryResult;
34 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingTypeUID;
37 import org.openhab.core.thing.ThingUID;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * The {@link MieleApplianceDiscoveryService} tracks appliances that are
43  * associated with the Miele@Home gateway
44  *
45  * @author Karel Goderis - Initial contribution
46  * @author Martin Lepsy - Added protocol information in order so support WiFi devices
47  * @author Jacob Laursen - Fixed multicast and protocol support (ZigBee/LAN)
48  */
49 @NonNullByDefault
50 public class MieleApplianceDiscoveryService extends AbstractDiscoveryService implements ApplianceStatusListener {
51
52     private final Logger logger = LoggerFactory.getLogger(MieleApplianceDiscoveryService.class);
53
54     private static final int SEARCH_TIME = 60;
55
56     private MieleBridgeHandler mieleBridgeHandler;
57
58     public MieleApplianceDiscoveryService(MieleBridgeHandler mieleBridgeHandler) {
59         super(MieleApplianceHandler.SUPPORTED_THING_TYPES, SEARCH_TIME, false);
60         this.mieleBridgeHandler = mieleBridgeHandler;
61     }
62
63     public void activate() {
64         mieleBridgeHandler.registerApplianceStatusListener(this);
65     }
66
67     @Override
68     public void deactivate() {
69         removeOlderResults(new Date().getTime());
70         mieleBridgeHandler.unregisterApplianceStatusListener(this);
71     }
72
73     @Override
74     public Set<ThingTypeUID> getSupportedThingTypes() {
75         return MieleApplianceHandler.SUPPORTED_THING_TYPES;
76     }
77
78     @Override
79     public void startScan() {
80         List<HomeDevice> appliances = mieleBridgeHandler.getHomeDevices();
81         for (HomeDevice l : appliances) {
82             onApplianceAddedInternal(l);
83         }
84     }
85
86     @Override
87     protected synchronized void stopScan() {
88         super.stopScan();
89         removeOlderResults(getTimestampOfLastScan());
90     }
91
92     @Override
93     public void onApplianceAdded(HomeDevice appliance) {
94         onApplianceAddedInternal(appliance);
95     }
96
97     private void onApplianceAddedInternal(HomeDevice appliance) {
98         ThingUID thingUID = getThingUID(appliance);
99         if (thingUID != null) {
100             ThingUID bridgeUID = mieleBridgeHandler.getThing().getUID();
101             Map<String, Object> properties = new HashMap<>(9);
102
103             FullyQualifiedApplianceIdentifier applianceIdentifier = appliance.getApplianceIdentifier();
104             String vendor = appliance.Vendor;
105             if (vendor != null) {
106                 properties.put(Thing.PROPERTY_VENDOR, vendor);
107             }
108             properties.put(Thing.PROPERTY_MODEL_ID, appliance.getApplianceModel());
109             properties.put(Thing.PROPERTY_SERIAL_NUMBER, appliance.getSerialNumber());
110             properties.put(Thing.PROPERTY_FIRMWARE_VERSION, appliance.getFirmwareVersion());
111             String protocolAdapterName = appliance.ProtocolAdapterName;
112             if (protocolAdapterName != null) {
113                 properties.put(PROPERTY_PROTOCOL_ADAPTER, protocolAdapterName);
114             }
115             properties.put(APPLIANCE_ID, applianceIdentifier.getApplianceId());
116             String deviceClass = appliance.getDeviceClass();
117             if (deviceClass != null) {
118                 properties.put(PROPERTY_DEVICE_CLASS, deviceClass);
119             }
120             String connectionType = appliance.getConnectionType();
121             if (connectionType != null) {
122                 properties.put(PROPERTY_CONNECTION_TYPE, connectionType);
123             }
124             String connectionBaudRate = appliance.getConnectionBaudRate();
125             if (connectionBaudRate != null) {
126                 properties.put(PROPERTY_CONNECTION_BAUD_RATE, connectionBaudRate);
127             }
128
129             DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
130                     .withBridge(bridgeUID).withLabel(deviceClass != null ? deviceClass : appliance.getApplianceModel())
131                     .withRepresentationProperty(APPLIANCE_ID).build();
132
133             thingDiscovered(discoveryResult);
134         } else {
135             logger.debug("Discovered an unsupported appliance of vendor '{}' with id {}", appliance.Vendor,
136                     appliance.UID);
137         }
138     }
139
140     @Override
141     public void onApplianceRemoved(HomeDevice appliance) {
142         ThingUID thingUID = getThingUID(appliance);
143
144         if (thingUID != null) {
145             thingRemoved(thingUID);
146         }
147     }
148
149     @Override
150     public void onApplianceStateChanged(FullyQualifiedApplianceIdentifier applianceIdentifier, DeviceClassObject dco) {
151         // nothing to do
152     }
153
154     @Override
155     public void onAppliancePropertyChanged(FullyQualifiedApplianceIdentifier applianceIdentifier, DeviceProperty dp) {
156         // nothing to do
157     }
158
159     private @Nullable ThingUID getThingUID(HomeDevice appliance) {
160         ThingUID bridgeUID = mieleBridgeHandler.getThing().getUID();
161         String modelId = appliance.getDeviceClass();
162
163         if (modelId != null) {
164             ThingTypeUID thingTypeUID = getThingTypeUidFromModelId(modelId);
165
166             if (getSupportedThingTypes().contains(thingTypeUID)) {
167                 ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, appliance.getApplianceIdentifier().getId());
168                 return thingUID;
169             } else {
170                 return null;
171             }
172         } else {
173             return null;
174         }
175     }
176
177     private ThingTypeUID getThingTypeUidFromModelId(String modelId) {
178         /*
179          * Coffee machine CVA 6805 is reported as CoffeeSystem, but thing type is
180          * coffeemachine. At least until it is known if any models are actually reported
181          * as CoffeeMachine, we need this special mapping.
182          */
183         if (MIELE_DEVICE_CLASS_COFFEE_SYSTEM.equals(modelId)) {
184             return THING_TYPE_COFFEEMACHINE;
185         }
186
187         String thingTypeId = modelId.replaceAll("[^a-zA-Z0-9_]", "_").toLowerCase();
188
189         return new ThingTypeUID(BINDING_ID, thingTypeId);
190     }
191 }