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