]> git.basschouten.com Git - openhab-addons.git/blob
ec162526d372642f5237eaf68f7b0e8cd1394a49
[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.knx.internal.handler;
14
15 import java.net.InetSocketAddress;
16 import java.text.MessageFormat;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.knx.internal.KNXBindingConstants;
21 import org.openhab.binding.knx.internal.client.CustomKNXNetworkLinkIP;
22 import org.openhab.binding.knx.internal.client.IPClient;
23 import org.openhab.binding.knx.internal.client.KNXClient;
24 import org.openhab.binding.knx.internal.client.NoOpClient;
25 import org.openhab.binding.knx.internal.config.IPBridgeConfiguration;
26 import org.openhab.core.net.NetworkAddressService;
27 import org.openhab.core.thing.Bridge;
28 import org.openhab.core.thing.ThingStatus;
29 import org.openhab.core.thing.ThingStatusDetail;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * The {@link IPBridgeThingHandler} is responsible for handling commands, which are
35  * sent to one of the channels. It implements a KNX/IP Gateway, that either acts a a
36  * conduit for other {@link DeviceThingHandler}s, or for Channels that are
37  * directly defined on the bridge
38  *
39  * @author Karel Goderis - Initial contribution
40  * @author Simon Kaufmann - Refactoring & cleanup
41  */
42 @NonNullByDefault
43 public class IPBridgeThingHandler extends KNXBridgeBaseThingHandler {
44     private static final String MODE_ROUTER = "ROUTER";
45     private static final String MODE_TUNNEL = "TUNNEL";
46
47     private final Logger logger = LoggerFactory.getLogger(IPBridgeThingHandler.class);
48
49     private @Nullable IPClient client;
50     private final NetworkAddressService networkAddressService;
51
52     public IPBridgeThingHandler(Bridge bridge, NetworkAddressService networkAddressService) {
53         super(bridge);
54         this.networkAddressService = networkAddressService;
55     }
56
57     @Override
58     public void initialize() {
59         IPBridgeConfiguration config = getConfigAs(IPBridgeConfiguration.class);
60         int autoReconnectPeriod = config.getAutoReconnectPeriod();
61         if (autoReconnectPeriod != 0 && autoReconnectPeriod < 30) {
62             logger.info("autoReconnectPeriod for {} set to {}s, allowed range is 0 (never) or >30", thing.getUID(),
63                     autoReconnectPeriod);
64             autoReconnectPeriod = 30;
65             config.setAutoReconnectPeriod(autoReconnectPeriod);
66         }
67         String localSource = config.getLocalSourceAddr();
68         String connectionTypeString = config.getType();
69         int port = config.getPortNumber().intValue();
70         String ip = config.getIpAddress();
71         InetSocketAddress localEndPoint = null;
72         boolean useNAT = false;
73         int ipConnectionType;
74         if (MODE_TUNNEL.equalsIgnoreCase(connectionTypeString)) {
75             useNAT = config.getUseNAT() != null ? config.getUseNAT() : false;
76             ipConnectionType = CustomKNXNetworkLinkIP.TUNNELING;
77         } else if (MODE_ROUTER.equalsIgnoreCase(connectionTypeString)) {
78             useNAT = false;
79             if (ip == null || ip.isEmpty()) {
80                 ip = KNXBindingConstants.DEFAULT_MULTICAST_IP;
81             }
82             ipConnectionType = CustomKNXNetworkLinkIP.ROUTING;
83         } else {
84             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
85                     MessageFormat.format("Unknown IP connection type {0}. Known types are either 'TUNNEL' or 'ROUTER'",
86                             connectionTypeString));
87             return;
88         }
89         if (ip == null) {
90             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
91                     "The 'ipAddress' of the gateway must be configured in 'TUNNEL' mode");
92             return;
93         }
94
95         if (config.getLocalIp() != null && !config.getLocalIp().isEmpty()) {
96             localEndPoint = new InetSocketAddress(config.getLocalIp(), 0);
97         } else {
98             localEndPoint = new InetSocketAddress(networkAddressService.getPrimaryIpv4HostAddress(), 0);
99         }
100
101         updateStatus(ThingStatus.UNKNOWN);
102         client = new IPClient(ipConnectionType, ip, localSource, port, localEndPoint, useNAT, autoReconnectPeriod,
103                 thing.getUID(), config.getResponseTimeout().intValue(), config.getReadingPause().intValue(),
104                 config.getReadRetriesLimit().intValue(), getScheduler(), this);
105
106         client.initialize();
107     }
108
109     @Override
110     public void dispose() {
111         super.dispose();
112         if (client != null) {
113             client.dispose();
114             client = null;
115         }
116     }
117
118     @Override
119     protected KNXClient getClient() {
120         KNXClient ret = client;
121         if (ret == null) {
122             return new NoOpClient();
123         }
124         return ret;
125     }
126 }