]> git.basschouten.com Git - openhab-addons.git/blob
5e68b956e7360ffb803ef188dd5147b90aca57fc
[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(deviceWho, where);
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 whereConfig = where.value();
156         if (where instanceof WhereZigBee && WhereZigBee.UNIT_02.equals(((WhereZigBee) where).getUnit())) {
157             logger.debug("UNIT=02 found (WHERE={}) -> will remove previous result if exists", where);
158             thingRemoved(thingUID); // remove previously discovered thing
159             // re-create thingUID with new type
160             thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS;
161             thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_ON_OFF_SWITCH_2UNITS;
162             thingUID = new ThingUID(thingTypeUID, bridgeUID, tId);
163             whereConfig = ((WhereZigBee) where).valueWithUnit(WhereZigBee.UNIT_ALL); // replace unit '02' with '00'
164             logger.debug("UNIT=02, switching type from {} to {}",
165                     OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH,
166                     OpenWebNetBindingConstants.THING_TYPE_ZB_ON_OFF_SWITCH_2UNITS);
167         }
168         Map<String, Object> properties = new HashMap<>(2);
169         properties.put(OpenWebNetBindingConstants.CONFIG_PROPERTY_WHERE, whereConfig);
170         properties.put(OpenWebNetBindingConstants.PROPERTY_OWNID, ownId);
171         if (thingTypeUID == OpenWebNetBindingConstants.THING_TYPE_GENERIC_DEVICE) {
172             thingLabel = thingLabel + " (WHO=" + deviceWho + ", WHERE=" + whereConfig + ")";
173         } else {
174             thingLabel = thingLabel + " (WHERE=" + whereConfig + ")";
175         }
176         discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID).withProperties(properties)
177                 .withRepresentationProperty(OpenWebNetBindingConstants.PROPERTY_OWNID).withBridge(bridgeUID)
178                 .withLabel(thingLabel).build();
179         thingDiscovered(discoveryResult);
180     }
181
182     @Override
183     public void deactivate() {
184         super.deactivate();
185     }
186
187     @Override
188     public void setThingHandler(@Nullable ThingHandler handler) {
189         if (handler instanceof OpenWebNetBridgeHandler) {
190             logger.debug("attaching {} to handler {} ", this, handler);
191             bridgeHandler = (OpenWebNetBridgeHandler) handler;
192             bridgeHandler.deviceDiscoveryService = this;
193             bridgeUID = bridgeHandler.getThing().getUID();
194         }
195     }
196
197     @Override
198     public @Nullable ThingHandler getThingHandler() {
199         return bridgeHandler;
200     }
201 }