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