2 * Copyright (c) 2010-2021 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.openwebnet.internal.discovery;
15 import java.util.HashMap;
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;
40 * The {@link OpenWebNetDeviceDiscoveryService} is responsible for discovering OpenWebNet devices connected to a
43 * @author Massimo Valla - Initial contribution
46 public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
47 implements DiscoveryService, ThingHandlerService {
49 private final Logger logger = LoggerFactory.getLogger(OpenWebNetDeviceDiscoveryService.class);
51 private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.DEVICE_SUPPORTED_THING_TYPES;
52 private static final int SEARCH_TIME_SEC = 60;
54 private @NonNullByDefault({}) OpenWebNetBridgeHandler bridgeHandler;
55 private @NonNullByDefault({}) ThingUID bridgeUID;
57 public OpenWebNetDeviceDiscoveryService() {
58 super(SUPPORTED_THING_TYPES, SEARCH_TIME_SEC);
62 public Set<ThingTypeUID> getSupportedThingTypes() {
63 return SUPPORTED_THING_TYPES;
67 protected void startScan() {
68 logger.info("------ SEARCHING for DEVICES on bridge '{}' ({}) ...", bridgeHandler.getThing().getLabel(),
70 bridgeHandler.searchDevices();
74 protected void stopScan() {
75 logger.debug("------ stopScan() on bridge '{}'", bridgeUID);
76 bridgeHandler.scanStopped();
80 public void abortScan() {
81 logger.debug("------ abortScan() on bridge '{}'", bridgeUID);
82 bridgeHandler.scanStopped();
86 * Create and notify to Inbox a new DiscoveryResult based on WHERE, OpenDeviceType and BaseOpenMessage
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)
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;
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;
103 case ZIGBEE_DIMMER_SWITCH:
104 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_ZB_DIMMER;
105 thingLabel = OpenWebNetBindingConstants.THING_LABEL_ZB_DIMMER;
106 deviceWho = Who.LIGHTING;
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;
113 case SCS_DIMMER_SWITCH:
114 thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_DIMMER;
115 thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_DIMMER;
116 deviceWho = Who.LIGHTING;
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;
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;
133 logger.warn("Device type {} is not supported, default to GENERIC device (WHERE={})", deviceType, where);
134 if (where instanceof WhereZigBee) {
135 thingLabel = "ZigBee " + thingLabel;
137 if (baseMsg != null) {
138 deviceWho = baseMsg.getWho();
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);
150 String tId = bridgeHandler.thingIdFromWhere(where);
151 ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, tId);
153 DiscoveryResult discoveryResult = null;
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);
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 + ")";
174 thingLabel = thingLabel + " (WHERE=" + whereConfig + ")";
176 discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(thingTypeUID).withProperties(properties)
177 .withRepresentationProperty(OpenWebNetBindingConstants.PROPERTY_OWNID).withBridge(bridgeUID)
178 .withLabel(thingLabel).build();
179 thingDiscovered(discoveryResult);
183 public void deactivate() {
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();
198 public @Nullable ThingHandler getThingHandler() {
199 return bridgeHandler;