diff --git a/bundles/org.openhab.binding.knx/README.md b/bundles/org.openhab.binding.knx/README.md index ca316ee591fcd..6ac60a148577d 100644 --- a/bundles/org.openhab.binding.knx/README.md +++ b/bundles/org.openhab.binding.knx/README.md @@ -223,9 +223,7 @@ It is created by the ETS tool and cannot be changed via the ETS user interface. For _Secure tunneling_ with a Secure IP Interface (or a router in tunneling mode), more parameters are required. A unique device authentication key, and a specific tunnel identifier and password need to be available. -- All information can be looked up in ETS and provided separately: `tunnelDeviceAuthentication`, `tunnelUserPassword`. -`tunnelUserId` is a number which is not directly visible in ETS, but can be looked up in keyring export or deduced (typically 2 for the first tunnel of a device, 3 for the second one, ...). -`tunnelUserPasswort` is set in ETS in the properties of the tunnel (below the IP interface you will see the different tunnels listed) denoted as "Password". `tunnelDeviceAuthentication` is set in the properties of the IP interface itself, check for a tab "IP" and a description "Authentication Code". +- All information can be looked up in ETS and provided separately: `tunnelDeviceAuthentication`, `tunnelUserPassword`. `tunnelUserId` is a number which is not directly visible in ETS, but can be looked up in keyring export or deduced (typically 2 for the first tunnel of a device, 3 for the second one, ...). `tunnelUserPasswort` is set in ETS in the properties of the tunnel (below the IP interface you will see the different tunnels listed) denoted as "Password". `tunnelDeviceAuthentication` is set in the properties of the IP interface itself, check for a tab "IP" and a description "Authentication Code". ### KNX Data Secure diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/WriteSpecImpl.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/WriteSpecImpl.java index 1515c5ac4cdbf..00b4f45f7c68b 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/WriteSpecImpl.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/WriteSpecImpl.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.knx.internal.channel; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.knx.internal.client.OutboundSpec; import org.openhab.core.types.Type; @@ -25,6 +26,7 @@ * @author Simon Kaufmann - initial contribution and API. * */ +@NonNullByDefault public class WriteSpecImpl extends AbstractSpec implements OutboundSpec { private final Type type; diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/client/ReadDatapoint.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/client/ReadDatapoint.java index 628e81de50b63..b9e6558b24801 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/client/ReadDatapoint.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/client/ReadDatapoint.java @@ -12,6 +12,9 @@ */ package org.openhab.binding.knx.internal.client; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + import tuwien.auto.calimero.datapoint.Datapoint; /** @@ -19,6 +22,7 @@ * * @author Karel Goderis - Initial contribution */ +@NonNullByDefault public class ReadDatapoint { private final Datapoint datapoint; @@ -56,7 +60,7 @@ public int hashCode() { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (this == obj) { return true; } @@ -66,14 +70,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } + @Nullable ReadDatapoint other = (ReadDatapoint) obj; - if (datapoint == null) { - if (other.datapoint != null) { - return false; - } - } else if (!datapoint.getMainAddress().equals(other.datapoint.getMainAddress())) { - return false; - } - return true; + return datapoint.getMainAddress().equals(other.datapoint.getMainAddress()); } } diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/KNXCoreTypeMapper.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/KNXCoreTypeMapper.java index 1f32068d2b9f3..481f418f4700b 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/KNXCoreTypeMapper.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/KNXCoreTypeMapper.java @@ -26,6 +26,8 @@ import java.util.Locale; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.knx.internal.KNXTypeMapper; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; @@ -84,11 +86,12 @@ * If for a 'MainType' there is currently no specific mapping registered, * you can find a commented example line, with it's correct 'DPTXlator' class. * - * @author Kai Kreuzer - * @author Volker Daube - * @author Jan N. Klug + * @author Kai Kreuzer - initial contribution + * @author Volker Daube - improvements + * @author Jan N. Klug - improvements * @author Helmut Lehmeyer - Java8, generic DPT Mapper */ +@NonNullByDefault @Component public class KNXCoreTypeMapper implements KNXTypeMapper { @@ -735,7 +738,7 @@ private String quantityTypeToDPTValue(QuantityType qt, int mainNumber, int su } @Override - public String toDPTValue(Type type, String dptID) { + public @Nullable String toDPTValue(Type type, @Nullable String dptID) { DPT dpt; int mainNumber = getMainNumber(dptID); if (mainNumber == -1) { @@ -838,7 +841,7 @@ public String toDPTValue(Type type, String dptID) { } @Override - public Type toType(Datapoint datapoint, byte[] data) { + public @Nullable Type toType(Datapoint datapoint, byte[] data) { try { DPTXlator translator = TranslatorTypes.createTranslator(datapoint.getMainNumber(), datapoint.getDPT()); translator.setData(data); @@ -996,7 +999,7 @@ public Type toType(Datapoint datapoint, byte[] data) { if (typeClass.equals(DateTimeType.class)) { String date = formatDateTime(value, datapoint.getDPT()); - if ((date == null) || (date.isEmpty())) { + if (date.isEmpty()) { logger.debug("toType: KNX clock msg ignored: date object null or empty {}.", date); return null; } else { @@ -1033,7 +1036,8 @@ public Type toType(Datapoint datapoint, byte[] data) { * @return the openHAB type (command or state) class or {@code null} if the datapoint type id is not supported. */ @Override - public Class toTypeClass(String dptId) { + public @Nullable Class toTypeClass(@Nullable String dptId) { + @Nullable Class ohClass = dptTypeMap.get(dptId); if (ohClass == null) { int mainNumber = getMainNumber(dptId); @@ -1052,7 +1056,7 @@ public Class toTypeClass(String dptId) { * @param typeClass the openHAB type class * @return the datapoint type id */ - public String toDPTid(Class typeClass) { + public @Nullable String toDPTid(Class typeClass) { return defaultDptMap.get(typeClass); } @@ -1114,7 +1118,7 @@ private String formatDateTime(String value, String dpt) { * @throws IllegalArgumentException if none of the datapoint types DPT_DATE or * DPT_TIMEOFDAY has been used. */ - private static String formatDateTime(DateTimeType dateType, String dpt) { + private static String formatDateTime(DateTimeType dateType, @Nullable String dpt) { if (DPTXlatorDate.DPT_DATE.getID().equals(dpt)) { return dateType.format("%tF"); } else if (DPTXlatorTime.DPT_TIMEOFDAY.getID().equals(dpt)) { @@ -1132,7 +1136,7 @@ private static String formatDateTime(DateTimeType dateType, String dpt) { * @param dptID String with DPT ID * @return sub number or -1 */ - private int getSubNumber(String dptID) { + private int getSubNumber(@Nullable String dptID) { int result = -1; if (dptID == null) { throw new IllegalArgumentException("Parameter dptID cannot be null"); @@ -1159,7 +1163,7 @@ private int getSubNumber(String dptID) { * @param dptID String with DPT ID * @return main number or -1 */ - private int getMainNumber(String dptID) { + private int getMainNumber(@Nullable String dptID) { int result = -1; if (dptID == null) { throw new IllegalArgumentException("Parameter dptID cannot be null"); diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/factory/KNXHandlerFactory.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/factory/KNXHandlerFactory.java index 913786aeea948..b93a7d629bc8c 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/factory/KNXHandlerFactory.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/factory/KNXHandlerFactory.java @@ -17,6 +17,8 @@ import java.util.Arrays; import java.util.Collection; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.knx.internal.handler.DeviceThingHandler; import org.openhab.binding.knx.internal.handler.IPBridgeThingHandler; import org.openhab.binding.knx.internal.handler.SerialBridgeThingHandler; @@ -42,12 +44,14 @@ * * @author Simon Kaufmann - Initial contribution and API */ +@NonNullByDefault @Component(service = ThingHandlerFactory.class, configurationPid = "binding.knx") public class KNXHandlerFactory extends BaseThingHandlerFactory { public static final Collection SUPPORTED_THING_TYPES_UIDS = Arrays.asList(THING_TYPE_DEVICE, THING_TYPE_IP_BRIDGE, THING_TYPE_SERIAL_BRIDGE); + @Nullable private NetworkAddressService networkAddressService; @Activate @@ -62,8 +66,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { } @Override - public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID, - ThingUID bridgeUID) { + public @Nullable Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, + @Nullable ThingUID thingUID, @Nullable ThingUID bridgeUID) { if (THING_TYPE_IP_BRIDGE.equals(thingTypeUID)) { ThingUID ipBridgeUID = getIPBridgeThingUID(thingTypeUID, thingUID, configuration); return super.createThing(thingTypeUID, configuration, ipBridgeUID, null); @@ -79,7 +83,7 @@ public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, } @Override - protected ThingHandler createHandler(Thing thing) { + protected @Nullable ThingHandler createHandler(Thing thing) { if (thing.getThingTypeUID().equals(THING_TYPE_IP_BRIDGE)) { return new IPBridgeThingHandler((Bridge) thing, networkAddressService); } else if (thing.getThingTypeUID().equals(THING_TYPE_SERIAL_BRIDGE)) { @@ -90,7 +94,8 @@ protected ThingHandler createHandler(Thing thing) { return null; } - private ThingUID getIPBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) { + private ThingUID getIPBridgeThingUID(ThingTypeUID thingTypeUID, @Nullable ThingUID thingUID, + Configuration configuration) { if (thingUID != null) { return thingUID; } @@ -98,7 +103,7 @@ private ThingUID getIPBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUI return new ThingUID(thingTypeUID, ipAddress); } - private ThingUID getSerialBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, + private ThingUID getSerialBridgeThingUID(ThingTypeUID thingTypeUID, @Nullable ThingUID thingUID, Configuration configuration) { if (thingUID != null) { return thingUID; diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/IPBridgeThingHandler.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/IPBridgeThingHandler.java index c6fa8bdbb6999..d7282a62ecc5b 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/IPBridgeThingHandler.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/IPBridgeThingHandler.java @@ -53,9 +53,9 @@ public class IPBridgeThingHandler extends KNXBridgeBaseThingHandler { private final Logger logger = LoggerFactory.getLogger(IPBridgeThingHandler.class); private @Nullable IPClient client = null; - private final NetworkAddressService networkAddressService; + private @Nullable final NetworkAddressService networkAddressService; - public IPBridgeThingHandler(Bridge bridge, NetworkAddressService networkAddressService) { + public IPBridgeThingHandler(Bridge bridge, @Nullable NetworkAddressService networkAddressService) { super(bridge); this.networkAddressService = networkAddressService; } @@ -171,6 +171,11 @@ public void initializeLater() { if (!config.getLocalIp().isEmpty()) { localEndPoint = new InetSocketAddress(config.getLocalIp(), 0); } else { + if (networkAddressService == null) { + logger.debug("NetworkAddressService not available, cannot create bridge {}", thing.getUID()); + updateStatus(ThingStatus.OFFLINE); + return; + } localEndPoint = new InetSocketAddress(networkAddressService.getPrimaryIpv4HostAddress(), 0); }