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