]> git.basschouten.com Git - openhab-addons.git/blob
3668722bdaef130451d6a3d5ea047ace5eabcb12
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.openwebnet.internal.discovery;
14
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.openwebnet.OpenWebNetBindingConstants;
22 import org.openhab.binding.openwebnet.handler.OpenWebNetBridgeHandler;
23 import org.openhab.core.config.discovery.AbstractDiscoveryService;
24 import org.openhab.core.config.discovery.DiscoveryResult;
25 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
26 import org.openhab.core.config.discovery.DiscoveryService;
27 import org.openhab.core.thing.ThingTypeUID;
28 import org.openhab.core.thing.ThingUID;
29 import org.openhab.core.thing.binding.ThingHandler;
30 import org.openhab.core.thing.binding.ThingHandlerService;
31 import org.openwebnet4j.OpenDeviceType;
32 import org.openwebnet4j.message.BaseOpenMessage;
33 import org.openwebnet4j.message.Where;
34 import org.openwebnet4j.message.WhereZigBee;
35 import org.openwebnet4j.message.Who;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@link OpenWebNetDeviceDiscoveryService} is responsible for discovering OpenWebNet devices connected to a
41  * bridge/gateway
42  *
43  * @author Massimo Valla - Initial contribution
44  */
45 @NonNullByDefault
46 public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
47         implements DiscoveryService, ThingHandlerService {
48
49     private final Logger logger = LoggerFactory.getLogger(OpenWebNetDeviceDiscoveryService.class);
50
51     private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.DEVICE_SUPPORTED_THING_TYPES;
52     private static final int SEARCH_TIME_SEC = 60;
53
54     private @NonNullByDefault({}) OpenWebNetBridgeHandler bridgeHandler;
55     private @NonNullByDefault({}) ThingUID bridgeUID;
56
57     public OpenWebNetDeviceDiscoveryService() {
58         super(SUPPORTED_THING_TYPES, SEARCH_TIME_SEC);
59     }
60
61     @Override
62     public Set<ThingTypeUID> getSupportedThingTypes() {
63         return OpenWebNetDeviceDiscoveryService.SUPPORTED_THING_TYPES;
64     }
65
66     @Override
67     protected void startScan() {
68         logger.info("------ SEARCHING for DEVICES on bridge '{}' ({}) ...", bridgeHandler.getThing().getLabel(),
69                 bridgeUID);
70         bridgeHandler.searchDevices();
71     }
72
73     @Override
74     protected void stopScan() {
75         logger.debug("------ stopScan() on bridge '{}'", bridgeUID);
76         bridgeHandler.scanStopped();
77     }
78
79     @Override
80     public void abortScan() {
81         logger.debug("------ abortScan() on bridge '{}'", bridgeUID);
82         bridgeHandler.scanStopped();
83     }
84
85     /**
86      * Create and notify to Inbox a new DiscoveryResult based on WHERE, OpenDeviceType and BaseOpenMessage
87      *
88      * @param where the discovered device's address (WHERE)
89      * @param deviceType {@link OpenDeviceType} of the discovered device
90      * @param message the OWN message received that identified the device (optional)
91      */
92     public void newDiscoveryResult(Where where, OpenDeviceType deviceType, @Nullable BaseOpenMessage baseMsg) {
93         logger.info("newDiscoveryResult() WHERE={}, deviceType={}", where, deviceType);
94         ThingTypeUID thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_GENERIC_DEVICE; // generic device
95         String thingLabel = OpenWebNetBindingConstants.THING_LABEL_GENERIC_DEVICE;
96         Who deviceWho = Who.UNKNOWN;
97         switch (deviceType) {
98             case ZIGBEE_ON_OFF_SWITCH:
99                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH;
100                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_ON_OFF_SWITCH;
101                 deviceWho = Who.LIGHTING;
102                 break;
103             case ZIGBEE_DIMMER_SWITCH:
104                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_DIMMER;
105                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_DIMMER;
106                 deviceWho = Who.LIGHTING;
107                 break;
108             case SCS_ON_OFF_SWITCH:
109                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_ON_OFF_SWITCH;
110                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_ON_OFF_SWITCH;
111                 deviceWho = Who.LIGHTING;
112                 break;
113             case SCS_DIMMER_SWITCH:
114                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_DIMMER;
115                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_DIMMER;
116                 deviceWho = Who.LIGHTING;
117                 break;
118             case SCS_SHUTTER_SWITCH:
119             case SCS_SHUTTER_CONTROL: {
120                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_AUTOMATION;
121                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_AUTOMATION;
122                 deviceWho = Who.AUTOMATION;
123                 break;
124             }
125             case ZIGBEE_SHUTTER_SWITCH:
126             case ZIGBEE_SHUTTER_CONTROL: {
127                 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_AUTOMATION;
128                 thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_AUTOMATION;
129                 deviceWho = Who.AUTOMATION;
130                 break;
131             }
132             default:
133                 logger.warn("Device type {} is not supported, default to GENERIC device (WHERE={})", deviceType, where);
134                 if (where instanceof WhereZigBee) {
135                     thingLabel = "ZigBee " + thingLabel;
136                 }
137                 if (baseMsg != null) {
138                     deviceWho = baseMsg.getWho();
139                 }
140         }
141
142         String ownId = bridgeHandler.ownIdFromWhoWhere(where, deviceWho);
143         if (thingTypeUID == OpenWebNetBindingConstants.THING_TYPE_BUS_ON_OFF_SWITCH) {
144             if (bridgeHandler.getRegisteredDevice(ownId) != null) {
145                 logger.debug("dimmer/switch with WHERE={} already registered, skipping this discovery result", where);
146                 return;
147             }
148         }
149
150         String tId = bridgeHandler.thingIdFromWhere(where);
151         ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, tId);
152
153         DiscoveryResult discoveryResult = null;
154
155         String whereLabel = where.value();
156         if (where instanceof WhereZigBee && WhereZigBee.UNIT_02.equals(((WhereZigBee) where).getUnit())) {
157             logger.debug("UNIT=02 found (WHERE={})", where);
158             logger.debug("will remove previous result if exists");
159             thingRemoved(thingUID); // remove previously discovered thing
160             // re-create thingUID with new type
161             thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS;
162             thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_ON_OFF_SWITCH_2UNITS;
163             thingUID = new ThingUID(thingTypeUID, bridgeUID, tId);
164             whereLabel = whereLabel.replace("02#", "00#"); // replace unit '02' with all unit '00'
165             logger.debug("UNIT=02, switching type from {} to {}",
166                     OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH,
167                     OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS);
168         }
169         Map<String, Object> properties = new HashMap<>(2);
170         properties.put(OpenWebNetBindingConstants.CONFIG_PROPERTY_WHERE, bridgeHandler.normalizeWhere(where));
171         properties.put(OpenWebNetBindingConstants.PROPERTY_OWNID, ownId);
172         if (thingTypeUID == OpenWebNetBindingConstants.THING_TYPE_GENERIC_DEVICE) {
173             thingLabel = thingLabel + " (WHO=" + deviceWho + ", WHERE=" + whereLabel + ")";
174         } else {
175             thingLabel = thingLabel + " (WHERE=" + whereLabel + ")";
176         }
177         discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID).withProperties(properties)
178                 .withRepresentationProperty(OpenWebNetBindingConstants.PROPERTY_OWNID).withBridge(bridgeUID)
179                 .withLabel(thingLabel).build();
180         thingDiscovered(discoveryResult);
181     }
182
183     @Override
184     public void deactivate() {
185         super.deactivate();
186     }
187
188     @Override
189     public void setThingHandler(@Nullable ThingHandler handler) {
190         if (handler instanceof OpenWebNetBridgeHandler) {
191             logger.debug("attaching {} to handler {} ", this, handler);
192             bridgeHandler = (OpenWebNetBridgeHandler) handler;
193             bridgeHandler.deviceDiscoveryService = this;
194             bridgeUID = bridgeHandler.getThing().getUID();
195         }
196     }
197
198     @Override
199     public @Nullable ThingHandler getThingHandler() {
200         return bridgeHandler;
201     }
202 }