return new WriteSpecImpl(entry.getValue(), dpt, command);
}
}
- // if we didn't find a match, check if we find a sub-type match
+ // if we didn't find a match, check if we find a subtype match
for (Map.Entry<String, GroupAddressConfiguration> entry : groupAddressConfigurations.entrySet()) {
String dpt = Objects.requireNonNullElse(entry.getValue().getDPT(), getDefaultDPT(entry.getKey()));
Set<Class<? extends Type>> expectedTypeClasses = DPTUtil.getAllowedTypes(dpt);
.map(Map.Entry::getValue).findFirst()
.orElseThrow(() -> new IllegalArgumentException(channelTypeUID + " is not a valid channel type ID"));
- // typecast to avoid warning about unsafe return type; we know that the lookup returns non null values
+ // typecast to avoid warning about unsafe return type; we know that the lookup returns non-null values
return (KNXChannel) supplier.apply(channel);
}
}
@Override
protected String getDefaultDPT(String gaConfigKey) {
- if (gaConfigKey.equals(HSB_GA)) {
- return DPTXlatorRGB.DPT_RGB.getID();
- }
- if (gaConfigKey.equals(INCREASE_DECREASE_GA)) {
- return DPTXlator3BitControlled.DPT_CONTROL_DIMMING.getID();
- }
- if (gaConfigKey.equals(SWITCH_GA)) {
- return DPTXlatorBoolean.DPT_SWITCH.getID();
- }
- if (gaConfigKey.equals(POSITION_GA)) {
- return DPTXlator8BitUnsigned.DPT_SCALING.getID();
- }
- throw new IllegalArgumentException("GA configuration '" + gaConfigKey + "' is not supported");
+ return switch (gaConfigKey) {
+ case HSB_GA -> DPTXlatorRGB.DPT_RGB.getID();
+ case INCREASE_DECREASE_GA -> DPTXlator3BitControlled.DPT_CONTROL_DIMMING.getID();
+ case SWITCH_GA -> DPTXlatorBoolean.DPT_SWITCH.getID();
+ case POSITION_GA -> DPTXlator8BitUnsigned.DPT_SCALING.getID();
+ default -> throw new IllegalArgumentException("GA configuration '" + gaConfigKey + "' is not supported");
+ };
}
}
import static org.openhab.binding.knx.internal.KNXBindingConstants.*;
import java.util.List;
-import java.util.Objects;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
@Override
protected String getDefaultDPT(String gaConfigKey) {
- if (Objects.equals(gaConfigKey, INCREASE_DECREASE_GA)) {
- return DPTXlator3BitControlled.DPT_CONTROL_DIMMING.getID();
- }
- if (Objects.equals(gaConfigKey, SWITCH_GA)) {
- return DPTXlatorBoolean.DPT_SWITCH.getID();
- }
- if (Objects.equals(gaConfigKey, POSITION_GA)) {
- return DPTXlator8BitUnsigned.DPT_SCALING.getID();
- }
- throw new IllegalArgumentException("GA configuration '" + gaConfigKey + "' is not supported");
+ return switch (gaConfigKey) {
+ case INCREASE_DECREASE_GA -> DPTXlator3BitControlled.DPT_CONTROL_DIMMING.getID();
+ case SWITCH_GA -> DPTXlatorBoolean.DPT_SWITCH.getID();
+ case POSITION_GA -> DPTXlator8BitUnsigned.DPT_SCALING.getID();
+ default -> throw new IllegalArgumentException("GA configuration '" + gaConfigKey + "' is not supported");
+ };
}
}
import static org.openhab.binding.knx.internal.KNXBindingConstants.*;
import java.util.List;
-import java.util.Objects;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault;
@Override
protected String getDefaultDPT(String gaConfigKey) {
- if (Objects.equals(gaConfigKey, UP_DOWN_GA)) {
- return DPTXlatorBoolean.DPT_UPDOWN.getID();
- }
- if (Objects.equals(gaConfigKey, STOP_MOVE_GA)) {
- return DPTXlatorBoolean.DPT_START.getID();
- }
- if (Objects.equals(gaConfigKey, POSITION_GA)) {
- return DPTXlator8BitUnsigned.DPT_SCALING.getID();
- }
- throw new IllegalArgumentException("GA configuration '" + gaConfigKey + "' is not supported");
+ return switch (gaConfigKey) {
+ case UP_DOWN_GA -> DPTXlatorBoolean.DPT_UPDOWN.getID();
+ case STOP_MOVE_GA -> DPTXlatorBoolean.DPT_START.getID();
+ case POSITION_GA -> DPTXlator8BitUnsigned.DPT_SCALING.getID();
+ default -> throw new IllegalArgumentException("GA configuration '" + gaConfigKey + "' is not supported");
+ };
}
}
// Protected ctor using given ManagementClientImpl is available (custom class to be inherited)
managementProcedures = new CustomManagementProceduresImpl(managementClient, tl);
- // OH helper for reading device info, based on managementClient above
+ // OpenHab helper for reading device info, based on managementClient above
deviceInfoClient = new DeviceInfoClientImpl(managementClient);
// ProcessCommunicator provides main KNX communication (Calimero).
private final DeviceInfoClient client;
private final IndividualAddress address;
- public static class Result {
- private final Map<String, String> properties;
- private final Set<GroupAddress> groupAddresses;
-
- public Result(Map<String, String> properties, Set<GroupAddress> groupAddresses) {
- super();
- this.properties = properties;
- this.groupAddresses = groupAddresses;
- }
-
- public Map<String, String> getProperties() {
- return properties;
- }
-
- public Set<GroupAddress> getGroupAddresses() {
- return groupAddresses;
- }
+ public record Result(Map<String, String> properties, Set<GroupAddress> groupAddresses) {
}
public DeviceInspector(DeviceInfoClient client, IndividualAddress address) {
* task immediately on connection loss or thing deconstruction.
*
* @param address Individual address of KNX device
- * @return List of device properties
+ * @return Map of device properties
* @throws InterruptedException
*/
private Map<String, String> readDeviceProperties(IndividualAddress address) throws InterruptedException {
if (!maxApdu.isEmpty()) {
logger.trace("Max APDU of device {} is {} bytes (routing)", address, maxApdu);
} else {
- // fallback: MAX_APDU_LENGTH; if availble set the default is 14 according to spec
+ // fallback: MAX_APDU_LENGTH; if available set the default is 14 according to spec
Thread.sleep(OPERATION_INTERVAL);
try {
byte[] result = getClient().readDeviceProperties(address, ADDRESS_TABLE_OBJECT,
logger.debug("Identified device {} as \"{}\"", address, result);
ret.put(FRIENDLY_NAME, result);
} else {
- // this is due to devices which have a buggy implememtation (and show a broken string also
+ // this is due to devices which have a buggy implementation (and show a broken string also
// in ETS tool)
logger.debug("Ignoring FRIENDLY_NAME of device {} as it contains non-printable characters",
address);
* Currently only data from DD0 is returned; DD2 is just logged in debug mode.
*
* @param address Individual address of KNX device
- * @return List of device properties
+ * @return Map of device properties
* @throws InterruptedException
*/
private Map<String, String> readDeviceDescription(IndividualAddress address) throws InterruptedException {
if (data != null) {
try {
final DD2 dd = DeviceDescriptor.DD2.from(data);
- logger.debug("The device with address {} is has DD2 {}", address, dd.toString());
+ logger.debug("The device with address {} is has DD2 {}", address, dd);
} catch (KNXIllegalArgumentException e) {
logger.warn("Can not parse device descriptor 2 of device with address {}: {}", address,
e.getMessage());
}
private static String getMediumType(int type) {
- switch (type) {
- case 0:
- return "TP";
- case 1:
- return "PL";
- case 2:
- return "RF";
- case 3:
- return "TP0 (deprecated)";
- case 4:
- return "PL123 (deprecated)";
- case 5:
- return "IP";
- default:
- return "unknown (" + type + ")";
- }
+ return switch (type) {
+ case 0 -> "TP";
+ case 1 -> "PL";
+ case 2 -> "RF";
+ case 3 -> "TP0 (deprecated)";
+ case 4 -> "PL123 (deprecated)";
+ case 5 -> "IP";
+ default -> "unknown (" + type + ")";
+ };
}
}
/**
* Get the affected group addresses.
*
- * @return a list of group addresses.
+ * @return a Set of group addresses.
*/
Set<GroupAddress> getGroupAddresses();
}
/**
* try automatic detection of cEMI devices via the PEI identification frame
*
- * @implNote This is based on an vendor specific extension and may not work for other devices.
+ * @implNote This is based on a vendor specific extension and may not work for other devices.
*/
protected boolean detectCemi() throws InterruptedException {
final byte[] peiIdentifyReqFrame = { (byte) 0xa7 };
* {@literal @}ServiceProvider annotation (biz.aQute.bnd.annotation) automatically creates the file
* /META-INF/services/tuwien.auto.calimero.serial.spi.SerialCom
* to register SerialTransportAdapter to the service loader.
- * Additional attributes for SerialTansportAdapter can be specified as well, e.g.
+ * Additional attributes for SerialTransportAdapter can be specified as well, e.g.
* attribute = { "position=1" }
* and will be part of MANIFEST.MF
*
if (args.length == 1 && CMD_LIST_UNKNOWN_GA.equalsIgnoreCase(args[0])) {
for (KNXBridgeBaseThingHandler bridgeHandler : knxHandlerFactory.getBridges()) {
console.println("KNX bridge \"" + bridgeHandler.getThing().getLabel()
- + "\": group address, type, number of bytes, and number of occurence since last reload of binding:");
+ + "\": group address, type, number of bytes, and number of occurrence since last reload of binding:");
for (Entry<String, Long> entry : bridgeHandler.getCommandExtensionData().unknownGA().entrySet()) {
console.println(entry.getKey() + " " + entry.getValue());
}
DPT_UNIT_MAP.put(DPTXlator4ByteFloat.DPT_ELECTROMAGNETIC_MOMENT.getID(),
Units.AMPERE.multiply(SIUnits.SQUARE_METRE).toString());
- // 64 bit signed (DPT 29)
+ // 64-bit signed (DPT 29)
DPT_UNIT_MAP.put(DPTXlator64BitSigned.DPT_REACTIVE_ENERGY.getID(), Units.VAR_HOUR.toString());
}
}
public class DPTUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(DPTUtil.class);
- // DPT: "123.001", 1-3 digits main type (no leading zero), optional sub-type 3-4 digits (leading zeros allowed)
+ // DPT: "123.001", 1-3 digits main type (no leading zero), optional subtype 3-4 digits (leading zeros allowed)
public static final Pattern DPT_PATTERN = Pattern.compile("^(?<main>[1-9][0-9]{0,2})(?:\\.(?<sub>\\d{3,5}))?$");
// used to map vendor-specific data to standard DPT
private static Type handleDpt1(String subType, DPTXlator translator, Class<? extends Type> preferredType) {
DPTXlatorBoolean translatorBoolean = (DPTXlatorBoolean) translator;
- switch (subType) {
- case "008":
- return translatorBoolean.getValueBoolean() ? UpDownType.DOWN : UpDownType.UP;
- case "009":
- case "019":
+ return switch (subType) {
+ case "008" -> translatorBoolean.getValueBoolean() ? UpDownType.DOWN : UpDownType.UP;
+ case "009", "019" -> {
// default is OpenClosedType (Contact), but it may be mapped to OnOffType as well
if (OnOffType.class.equals(preferredType)) {
- return OnOffType.from(translatorBoolean.getValueBoolean());
+ yield OnOffType.from(translatorBoolean.getValueBoolean());
}
// This is wrong for DPT 1.009. It should be true -> CLOSE, false -> OPEN, but unfortunately
// can't be fixed without breaking a lot of working installations.
// The documentation has been updated to reflect that. / @J-N-K
- return translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
- case "010":
- return translatorBoolean.getValueBoolean() ? StopMoveType.MOVE : StopMoveType.STOP;
- case "022":
- return DecimalType.valueOf(translatorBoolean.getValueBoolean() ? "1" : "0");
- default:
+ yield translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
+
+ // This is wrong for DPT 1.009. It should be true -> CLOSE, false -> OPEN, but unfortunately
+ // can't be fixed without breaking a lot of working installations.
+ // The documentation has been updated to reflect that. / @J-N-K
+ }
+ case "010" -> translatorBoolean.getValueBoolean() ? StopMoveType.MOVE : StopMoveType.STOP;
+ case "022" -> DecimalType.valueOf(translatorBoolean.getValueBoolean() ? "1" : "0");
+ default -> {
// default is OnOffType (Switch), but it may be mapped to OpenClosedType as well
if (OpenClosedType.class.equals(preferredType)) {
- return translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
+ yield translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
}
- return OnOffType.from(translatorBoolean.getValueBoolean());
- }
+ yield OnOffType.from(translatorBoolean.getValueBoolean());
+ }
+ };
}
private static @Nullable Type handleDpt3(String subType, DPTXlator translator) {
LOGGER.debug("convertRawDataToType: KNX DPT_Control_Dimming: break received.");
return UnDefType.NULL;
}
- switch (subType) {
- case "007":
- return translator3BitControlled.getControlBit() ? IncreaseDecreaseType.INCREASE
- : IncreaseDecreaseType.DECREASE;
- case "008":
- return translator3BitControlled.getControlBit() ? UpDownType.DOWN : UpDownType.UP;
- default:
+ return switch (subType) {
+ case "007" -> translator3BitControlled.getControlBit() ? IncreaseDecreaseType.INCREASE
+ : IncreaseDecreaseType.DECREASE;
+ case "008" -> translator3BitControlled.getControlBit() ? UpDownType.DOWN : UpDownType.UP;
+ default -> {
// should never happen unless Calimero introduces new subtypes
LOGGER.warn("DPT3, subtype '{}' is unknown. Please open an issue.", subType);
- return null;
- }
+ yield null;
+ }
+ };
}
private static Type handleDpt10(String value) throws ParseException {
if (DPTXlator2ByteFloat.DPT_TEMPERATURE_DIFFERENCE.getID().equals(dptId)
|| DPTXlator2ByteFloat.DPT_TEMPERATURE_GRADIENT.getID().equals(dptId)
|| DPTXlator2ByteFloat.DPT_KELVIN_PER_PERCENT.getID().equals(dptId)) {
- // match unicode character or °C
+ // match Unicode character or °C
if (value.toString().contains(SIUnits.CELSIUS.getSymbol()) || value.toString().contains("°C")) {
if (unit != null) {
unit = unit.replace("K", "°C");
}
} else if (value.toString().contains("°F")) {
- // an new approach to handle temperature differences was introduced to core
- // after 4.0, stripping the unit and and creating a new QuantityType works
+ // A new approach to handle temperature differences was introduced to core
+ // after 4.0, stripping the unit and creating a new QuantityType works
// both with core release 4.0 and current snapshot
boolean perPercent = value.toString().contains("/%");
value = new QuantityType<>(((QuantityType<?>) value).doubleValue() * 5.0 / 9.0, Units.KELVIN);
return bigDecimal.stripTrailingZeros().toPlainString();
case "2":
DPT valueDPT = ((DPTXlator1BitControlled.DPT1BitControlled) dpt).getValueDPT();
- switch (bigDecimal.intValue()) {
- case 0:
- return "0 " + valueDPT.getLowerValue();
- case 1:
- return "0 " + valueDPT.getUpperValue();
- case 2:
- return "1 " + valueDPT.getLowerValue();
- default:
- return "1 " + valueDPT.getUpperValue();
- }
+ return switch (bigDecimal.intValue()) {
+ case 0 -> "0 " + valueDPT.getLowerValue();
+ case 1 -> "0 " + valueDPT.getUpperValue();
+ case 2 -> "1 " + valueDPT.getLowerValue();
+ default -> "1 " + valueDPT.getUpperValue();
+ };
case "18":
int intVal = bigDecimal.intValue();
if (intVal > 63) {
/**
* convert 0...100% to 1 byte 0..255
*
- * @param percent
+ * @param percent percentage 0..1
* @return int 0..255
*/
private static int convertPercentToByte(PercentType percent) {
logger.trace(
"onGroupWrite Thing '{}' processes a GroupValueWrite telegram for destination '{}' for channel '{}'",
getThing().getUID(), destination, knxChannel.getChannelUID());
- /**
- * Remember current KNXIO outboundSpec only if it is a control channel.
- */
+
+ // Remember current KNXIO outboundSpec only if it is a control channel
if (knxChannel.isControl()) {
logger.trace("onGroupWrite isControl");
Type value = ValueDecoder.decode(listenSpec.getDPT(), asdu, knxChannel.preferredType());
DeviceInspector.Result result = inspector.readDeviceInfo();
if (result != null) {
Map<String, String> properties = editProperties();
- properties.putAll(result.getProperties());
+ properties.putAll(result.properties());
updateProperties(properties);
return true;
}
/***
* Show all secure group addresses and surrogates. A surrogate is the device which is asked to carry out an indirect
* read/write request.
- * Simpler approach w/o surrogates: Security.defaultInstallation().groupSenders().toString());
+ * Simpler approach w/o surrogates: Security.defaultInstallation().groupSenders().toString();
*/
public static String secHelperGetSecureGroupAddresses(final Security openhabSecurity) {
Map<GroupAddress, Set<String>> groupSendersWithSurrogate = new HashMap<GroupAddress, Set<String>>();
IndividualAddress surrogate = null;
try {
surrogate = senders.getOrDefault(ga, Set.of()).stream().findAny().get();
- } catch (NoSuchElementException e) {
+ } catch (NoSuchElementException ignored) {
}
Set<String> devices = new HashSet<String>();
for (var device : entry.getValue()) {
* This class provides translations. It is a helper class for i18n / localization efforts.
*
* @implNote It is implemented as a static singleton, enforced by the single-element enum pattern.
- * @apiNote {@link #setProvider(LocaleProvider, TranslationProvider)} must be called to provide tanslation service,
+ * @apiNote {@link #setProvider(LocaleProvider, TranslationProvider)} must be called to provide translation service,
* otherwise all functions will return untranslated text.
* Thread safety is ensured.
* @author Holger Friedrich - Initial contribution
private @Nullable LocaleProvider localeProvider;
private @Nullable TranslationProvider translationProvider;
- private Bundle bundle;
+ private final Bundle bundle;
- private KNXTranslationProvider() {
+ KNXTranslationProvider() {
localeProvider = null;
translationProvider = null;
bundle = FrameworkUtil.getBundle(this.getClass());
final TranslationProvider translationProvider = this.translationProvider;
final LocaleProvider localeProvider = this.localeProvider;
if (translationProvider != null) {
- // localeProvider might be null, but if not, getLocale will return NonNull Locale
+ // localeProvider might be null, but if not, getLocale will return NonNull Locale;
// locale cannot be cached, as getLocale() will return different result once locale is changed by user
final Locale locale = (localeProvider != null) ? localeProvider.getLocale() : Locale.getDefault();
final String res = translationProvider.getText(bundle, text, text, locale, arguments);
return res;
}
}
- // translating not possible, we still have the original text without any subsititutions
+ // translating not possible, we still have the original text without any substitutions
if (arguments == null || arguments.length == 0) {
return text;
}
*
* @param e any exception
* @return localized message in form [description (translated)] [class name], [e.getLocalizedMessage (not
- * translated)]), empty string for null. May possibly change in further releases.
+ * translated)], empty string for null. May change in further releases.
*/
public String getLocalizedException(final Throwable e) {
StringBuilder res = new StringBuilder();
final String exName = e.getClass().getSimpleName();
final String key = "exception." + exName;
final String translatedDescription = KNXTranslationProvider.I18N.get(key);
- Boolean foundTranslation = !key.equals(translatedDescription);
+ boolean foundTranslation = !key.equals(translatedDescription);
// detailed message cannot be translated, e.getLocalizedMessage will likely return English
String detail = e.getLocalizedMessage();
if (detail == null) {
public void testNullChannelUidFails() {
Channel channel = Objects.requireNonNull(mock(Channel.class));
- assertThrows(IllegalArgumentException.class, () -> {
- KNXChannelFactory.createKnxChannel(channel);
- });
+ assertThrows(IllegalArgumentException.class, () -> KNXChannelFactory.createKnxChannel(channel));
}
@Test
Channel channel = Objects.requireNonNull(mock(Channel.class));
when(channel.getChannelTypeUID()).thenReturn(new ChannelTypeUID("a:b:c"));
- assertThrows(IllegalArgumentException.class, () -> {
- KNXChannelFactory.createKnxChannel(channel);
- });
+ assertThrows(IllegalArgumentException.class, () -> KNXChannelFactory.createKnxChannel(channel));
}
@ParameterizedTest
CHANNEL_DATETIME, CHANNEL_DATETIME_CONTROL, CHANNEL_DIMMER, CHANNEL_DIMMER_CONTROL, CHANNEL_NUMBER,
CHANNEL_NUMBER_CONTROL, CHANNEL_ROLLERSHUTTER, CHANNEL_ROLLERSHUTTER_CONTROL, CHANNEL_STRING,
CHANNEL_STRING_CONTROL, CHANNEL_SWITCH, CHANNEL_SWITCH_CONTROL })
- public void testSuccess(String channeltype) {
+ public void testSuccess(String channelType) {
Channel channel = Objects.requireNonNull(mock(Channel.class));
Configuration configuration = new Configuration(
Map.of("key1", "5.001:<1/2/3+4/5/6+1/5/6", "key2", "1.001:7/1/9+1/1/2"));
- when(channel.getChannelTypeUID()).thenReturn(new ChannelTypeUID("knx:" + channeltype));
+ when(channel.getChannelTypeUID()).thenReturn(new ChannelTypeUID("knx:" + channelType));
when(channel.getConfiguration()).thenReturn(configuration);
when(channel.getAcceptedItemType()).thenReturn("none");
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.knx.internal.client;
-
-import java.util.Collections;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.knx.internal.handler.KNXBridgeBaseThingHandler.CommandExtensionData;
-import org.openhab.core.thing.ThingUID;
-
-import tuwien.auto.calimero.KNXException;
-import tuwien.auto.calimero.link.KNXNetworkLink;
-
-/**
- * {@link AbstractKNXClient} implementation for test, using {@link DummyKNXNetworkLink}.
- *
- * @author Holger Friedrich - initial contribution and API.
- *
- */
-@NonNullByDefault
-public class DummyClient extends AbstractKNXClient {
-
- public DummyClient() {
- super(0, new ThingUID("dummy connection"), 0, 0, 0, null, new CommandExtensionData(Collections.emptyMap()),
- null, null);
- }
-
- @Override
- protected KNXNetworkLink establishConnection() throws KNXException, InterruptedException {
- return new DummyKNXNetworkLink();
- }
-}
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-import org.openhab.binding.knx.internal.itests.Back2BackTest;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
import org.openhab.core.util.ColorUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import tuwien.auto.calimero.dptxlator.DPTXlator2ByteUnsigned;
import tuwien.auto.calimero.dptxlator.DPTXlator4ByteFloat;
*/
@NonNullByDefault
class DPTTest {
- public static final Logger LOGGER = LoggerFactory.getLogger(Back2BackTest.class);
-
@Test
void testDptBroken() {
assertNull(ValueEncoder.encode(new DecimalType(), "9.042.1"));
assertNotEquals(DPTXlator4ByteFloat.DPT_ELECTROMAGNETIC_MOMENT.getUnit(),
Units.AMPERE.multiply(SIUnits.SQUARE_METRE).toString());
- // 64 bit signed (DPT 29)
+ // 64-bit signed (DPT 29)
assertNotEquals(DPTXlator64BitSigned.DPT_REACTIVE_ENERGY.getUnit(), Units.VAR_HOUR.toString());
}
// router password configured, length must be 16 bytes in hex notation
assertTrue(handler.initializeSecurity("", "", "D947B12DDECAD528B1D5A88FD347F284", "", "", "", ""));
assertTrue(handler.initializeSecurity("", "", "0xD947B12DDECAD528B1D5A88FD347F284", "", "", "", ""));
- assertThrows(KnxSecureException.class, () -> {
- handler.initializeSecurity("", "", "wrongLength", "", "", "", "");
- });
+ assertThrows(KnxSecureException.class, () -> handler.initializeSecurity("", "", "wrongLength", "", "", "", ""));
// tunnel configuration
assertTrue(handler.initializeSecurity("", "", "", "da", "1", "pw", ""));
// cTunnelUser is restricted to a number >0
- assertThrows(KnxSecureException.class, () -> {
- handler.initializeSecurity("", "", "", "da", "0", "pw", "");
- });
- assertThrows(KnxSecureException.class, () -> {
- handler.initializeSecurity("", "", "", "da", "eins", "pw", "");
- });
+ assertThrows(KnxSecureException.class, () -> handler.initializeSecurity("", "", "", "da", "0", "pw", ""));
+ assertThrows(KnxSecureException.class, () -> handler.initializeSecurity("", "", "", "da", "eins", "pw", ""));
// at least one setting for tunnel is given, count as try to configure secure tunnel
// plausibility is checked during initialize()
assertTrue(handler.initializeSecurity("", "", "", "da", "", "", ""));
assertTrue(handler.initializeSecurity("", "", "", "", "1", "", ""));
assertTrue(handler.initializeSecurity("", "", "", "", "", "pw", ""));
- assertThrows(KnxSecureException.class, () -> {
- handler.initializeSecurity("nonExistingFile.xml", "", "", "", "", "", "");
- });
+ assertThrows(KnxSecureException.class,
+ () -> handler.initializeSecurity("nonExistingFile.xml", "", "", "", "", "", ""));
Properties pBackup = new Properties(System.getProperties());
try {
p.put(OpenHAB.CONFIG_DIR_PROG_ARGUMENT, testFile.getParent().replaceAll("misc$", ""));
System.setProperties(p);
- assertTrue(handler.initializeSecurity(testFile.getName().toString(), passwordString, "", "", "", "pw", ""));
+ assertTrue(handler.initializeSecurity(testFile.getName(), passwordString, "", "", "", "pw", ""));
- assertThrows(KnxSecureException.class, () -> {
- assertTrue(handler.initializeSecurity(testFile.getName().toString(), "wrong", "", "", "", "pw", ""));
- });
+ assertThrows(KnxSecureException.class,
+ () -> assertTrue(handler.initializeSecurity(testFile.getName(), "wrong", "", "", "", "pw", "")));
} catch (URISyntaxException e) {
+ fail("should never happen");
} finally {
// properties are not persistent, but change may interference with other tests -> restore
System.setProperties(pBackup);
*/
package org.openhab.binding.knx.internal.itests;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;
import java.util.HashSet;
* handled by this test. However, new subtypes are not detected.
*
* @see DummyKNXNetworkLink
- * @see DummyClient
* @author Holger Friedrich - Initial contribution
*
*/
public static final Logger LOGGER = LoggerFactory.getLogger(Back2BackTest.class);
static Set<Integer> dptTested = new HashSet<>();
static final byte[] F32_MINUS_ONE = new byte[] { (byte) 0xbf, (byte) 0x80, 0, 0 };
- boolean testsMissing = false;
/**
* helper method for integration tests
* @param ohReferenceData OpenHAB data type, initialized to known good value
* @param maxDistance byte array containing maximal deviations when comparing byte arrays (rawData against created
* KNX frame), may be empty if no deviation is considered
- * @param bitmask to mask certain bits in the raw to raw comparison, required for multi-valued KNX frames
+ * @param bitmask to mask certain bits in the raw to raw comparison, required for multivalued KNX frames
*/
void helper(String dpt, byte[] rawData, Type ohReferenceData, byte[] maxDistance, byte[] bitmask) {
try {
DPTUtil.NORMALIZED_DPT.getOrDefault(dpt, dpt));
// 0) check usage of helper()
- assertEquals(true, rawData.length > 0);
+ assertTrue(rawData.length > 0);
if (maxDistance.length == 0) {
maxDistance = new byte[rawData.length];
}
}
assertEquals(rawData.length, bitmask.length, "incorrect length of bitmask array");
int mainType = Integer.parseUnsignedInt(dpt.substring(0, dpt.indexOf('.')));
- dptTested.add(Integer.valueOf(mainType));
+ dptTested.add(mainType);
// check if OH would be able to send out a frame, given the type
Set<Integer> knownWorking = Set.of(1, 3, 5);
if (!knownWorking.contains(mainType)) {
// 2) check the encoding (ohData to raw data)
//
- // Test approach is to a) encode the value into String format using ValueEncoder.encode(),
+ // Test approach is to
+ // a) encode the value into String format using ValueEncoder.encode(),
// b) pass it to Calimero for conversion into a raw representation, and
// c) finally grab raw data bytes from a custom KNXNetworkLink implementation
String enc = ValueEncoder.encode(ohData, dpt);
pc.close();
} catch (KNXException e) {
- LOGGER.warn("exception occurred", e.toString());
+ LOGGER.warn("exception occurred: {}", e.toString());
assertEquals("", e.toString());
}
}
};
TranslatorTypes.getAllMainTypes().forEach((i, t) -> {
if (!dptTested.contains(i)) {
- LOGGER.warn("missing tests for main DPT type " + i);
+ LOGGER.warn("missing tests for main DPT type {}", i);
wrapper.testsMissing = true;
}
});
- assertEquals(false, wrapper.testsMissing, "add tests for new DPT main types");
+ assertFalse(wrapper.testsMissing, "add tests for new DPT main types");
}
}
Security openhabSecurity = Security.newSecurity();
openhabSecurity.useKeyring(keys, password);
- assertThrows(KnxSecureException.class, () -> {
- KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.empty(), passwordString);
- });
+ assertThrows(KnxSecureException.class,
+ () -> KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.empty(), passwordString));
assertTrue(KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.ofNullable(keys), passwordString)
.isPresent());
// now check tunnel (expected to fail, not included)
IndividualAddress secureTunnelSourceAddr = new IndividualAddress(2, 8, 20);
- assertThrows(KnxSecureException.class, () -> {
- KNXBridgeBaseThingHandler.secHelperReadTunnelConfig(Optional.empty(), passwordString,
- secureTunnelSourceAddr);
- });
+ assertThrows(KnxSecureException.class, () -> KNXBridgeBaseThingHandler
+ .secHelperReadTunnelConfig(Optional.empty(), passwordString, secureTunnelSourceAddr));
assertTrue(KNXBridgeBaseThingHandler
.secHelperReadTunnelConfig(Optional.ofNullable(keys), passwordString, secureTunnelSourceAddr)
.isEmpty());
Security openhabSecurity = Security.newSecurity();
openhabSecurity.useKeyring(keys, password);
- assertThrows(KnxSecureException.class, () -> {
- KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.empty(), passwordString);
- });
+ assertThrows(KnxSecureException.class,
+ () -> KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.empty(), passwordString));
assertTrue(KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.ofNullable(keys), passwordString)
.isEmpty());
// now check tunnel
IndividualAddress secureTunnelSourceAddr = new IndividualAddress(1, 1, 2);
- assertThrows(KnxSecureException.class, () -> {
- KNXBridgeBaseThingHandler.secHelperReadTunnelConfig(Optional.empty(), passwordString,
- secureTunnelSourceAddr);
- });
+ assertThrows(KnxSecureException.class, () -> KNXBridgeBaseThingHandler
+ .secHelperReadTunnelConfig(Optional.empty(), passwordString, secureTunnelSourceAddr));
assertTrue(KNXBridgeBaseThingHandler
.secHelperReadTunnelConfig(Optional.ofNullable(keys), passwordString, secureTunnelSourceAddr)
.isPresent());
openhabSecurity.useKeyring(keys, password);
// now check router settings:
- assertThrows(KnxSecureException.class, () -> {
- KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.empty(), passwordString);
- });
+ assertThrows(KnxSecureException.class,
+ () -> KNXBridgeBaseThingHandler.secHelperReadBackboneKey(Optional.empty(), passwordString));
String bbKeyHex = "D947B12DDECAD528B1D5A88FD347F284";
byte[] bbKeyParsedLower = KNXBridgeBaseThingHandler.secHelperParseBackboneKey(bbKeyHex.toLowerCase());
byte[] bbKeyParsedUpper = KNXBridgeBaseThingHandler.secHelperParseBackboneKey(bbKeyHex);
// now check tunnel settings:
IndividualAddress secureTunnelSourceAddr = new IndividualAddress(1, 1, 2);
IndividualAddress noSecureTunnelSourceAddr = new IndividualAddress(2, 8, 20);
- assertThrows(KnxSecureException.class, () -> {
- KNXBridgeBaseThingHandler.secHelperReadTunnelConfig(Optional.empty(), passwordString,
- secureTunnelSourceAddr);
- });
+ assertThrows(KnxSecureException.class, () -> KNXBridgeBaseThingHandler
+ .secHelperReadTunnelConfig(Optional.empty(), passwordString, secureTunnelSourceAddr));
assertTrue(KNXBridgeBaseThingHandler
.secHelperReadTunnelConfig(Optional.ofNullable(keys), passwordString, noSecureTunnelSourceAddr)
.isEmpty());