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