]> git.basschouten.com Git - openhab-addons.git/commitdiff
[smartmeter] Fix Undelivered IOException (#17133)
authorlsiepel <leosiepel@gmail.com>
Sat, 7 Sep 2024 08:06:56 +0000 (10:06 +0200)
committerGitHub <noreply@github.com>
Sat, 7 Sep 2024 08:06:56 +0000 (10:06 +0200)
Signed-off-by: Leo Siepel <leosiepel@gmail.com>
20 files changed:
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/SmartMeterConfiguration.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/MeterDevice.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/MeterDeviceFactory.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/MeterValue.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/ObisCode.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/SmartMeterChannelTypeProvider.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/SmartMeterHandler.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/conformity/Conformity.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/conformity/negate/NegateHandler.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21MeterReader.java [deleted file]
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21SerialConnector.java [deleted file]
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21UnitConversion.java [deleted file]
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/MeterReader.java [new file with mode: 0644]
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/SerialConnector.java [new file with mode: 0644]
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/UnitConversion.java [new file with mode: 0644]
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/sml/SmlFileDebugOutput.java
bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/sml/SmlSerialConnector.java
bundles/org.openhab.binding.smartmeter/src/test/java/org/openhab/binding/smartmeter/MockMeterReaderConnector.java
bundles/org.openhab.binding.smartmeter/src/test/java/org/openhab/binding/smartmeter/TestMeterReading.java
bundles/org.openhab.binding.smartmeter/src/test/java/org/openhab/binding/smartmeter/TestNegateBit.java

index aefa13513e61bd953d9f063239695f4b4e0b3d40..70fa7201819f264523d9d236b2df3a602804d9ee 100644 (file)
  */
 package org.openhab.binding.smartmeter;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
 /**
  * The {@link SmartMeterConfiguration} is the class used to match the
  * thing configuration.
  *
  * @author Matthias Steigenberger - Initial contribution
  */
+@NonNullByDefault
 public class SmartMeterConfiguration {
 
+    @Nullable
     public String port;
-    public Integer refresh;
-    public Integer baudrateChangeDelay;
+    public Integer refresh = 10;
+    public Integer baudrateChangeDelay = 0;
+    @Nullable
     public String initMessage;
-    public String baudrate;
-    public String mode;
-    public String conformity;
+    public String baudrate = "AUTO";
+    public String mode = "SML";
+    public String conformity = "NONE";
 }
index 3333f87b945cd63b6fd25bfa0b95e60f4b9a5f45..f69c32c72bc06902bffd10d4ff75e2ba9ea925c1 100644 (file)
@@ -12,6 +12,7 @@
  */
 package org.openhab.binding.smartmeter.internal;
 
+import java.io.IOException;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory;
 
 import io.reactivex.Flowable;
 import io.reactivex.disposables.Disposable;
+import io.reactivex.exceptions.UndeliverableException;
 import io.reactivex.plugins.RxJavaPlugins;
 import io.reactivex.schedulers.Schedulers;
 
@@ -83,7 +85,18 @@ public abstract class MeterDevice<T> {
         this.connector = createConnector(serialPortManagerSupplier, serialPort, baudrate, baudrateChangeDelay,
                 protocolMode);
         RxJavaPlugins.setErrorHandler(error -> {
-            logger.error("Fatal error occured", error);
+            if (error == null) {
+                logger.warn("Fatal but unknown error occurred");
+                return;
+            }
+            if (error instanceof UndeliverableException) {
+                error = error.getCause();
+            }
+            if (error instanceof IOException) {
+                logger.warn("Connection related issue occurred: {}", error.getMessage());
+                return;
+            }
+            logger.warn("Fatal error occurred", error);
         });
     }
 
index 255d59094f4264225f00248f028cc9b20e58b25f..51e8f2d5fad6dadfad1c17b78194a7f1cad5f8ca 100644 (file)
@@ -17,7 +17,7 @@ import java.util.function.Supplier;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.smartmeter.internal.helper.ProtocolMode;
-import org.openhab.binding.smartmeter.internal.iec62056.Iec62056_21MeterReader;
+import org.openhab.binding.smartmeter.internal.iec62056.MeterReader;
 import org.openhab.binding.smartmeter.internal.sml.SmlMeterReader;
 import org.openhab.core.io.transport.serial.SerialPortManager;
 
@@ -49,8 +49,8 @@ public class MeterDeviceFactory {
         switch (protocolMode) {
             case D:
             case ABC:
-                return new Iec62056_21MeterReader(serialPortManagerSupplier, deviceId, serialPort, initMessage,
-                        baudrate, baudrateChangeDelay, protocolMode);
+                return new MeterReader(serialPortManagerSupplier, deviceId, serialPort, initMessage, baudrate,
+                        baudrateChangeDelay, protocolMode);
             case SML:
                 return SmlMeterReader.createInstance(serialPortManagerSupplier, deviceId, serialPort, initMessage,
                         baudrate, baudrateChangeDelay);
index c93e939e28e62e615f602d87fc9f3c4790412a2d..9c9dac6e5391500eea41ab9673aef4ea385cbc40 100644 (file)
@@ -66,11 +66,15 @@ public class MeterValue<Q extends Quantity<Q>> {
     @Override
     public int hashCode() {
         final int prime = 31;
+        final String status = this.status;
+        final Unit<? extends Q> unit = this.unit;
+        final String value = this.value;
+
         int result = 1;
-        result = prime * result + ((obis == null) ? 0 : obis.hashCode());
-        result = prime * result + ((status == null) ? 0 : status.hashCode());
-        result = prime * result + ((unit == null) ? 0 : unit.hashCode());
-        result = prime * result + ((value == null) ? 0 : value.hashCode());
+        result = prime * result + obis.hashCode();
+        result = prime * result + (status == null ? 0 : status.hashCode());
+        result = prime * result + (unit == null ? 0 : unit.hashCode());
+        result = prime * result + value.hashCode();
         return result;
     }
 
@@ -90,6 +94,7 @@ public class MeterValue<Q extends Quantity<Q>> {
         if (!obis.equals(other.obis)) {
             return false;
         }
+        String status = this.status;
         if (status == null) {
             if (other.status != null) {
                 return false;
@@ -97,6 +102,7 @@ public class MeterValue<Q extends Quantity<Q>> {
         } else if (!status.equals(other.status)) {
             return false;
         }
+        Unit<? extends Q> unit = this.unit;
         if (unit == null) {
             if (other.unit != null) {
                 return false;
index c35e0f0498fce6d6bbb695ed80ca7b6b1ab7db9c..1e3a70a4c1052d2c09e26571ef0b9f21f73e0daa 100644 (file)
@@ -82,6 +82,10 @@ public class ObisCode {
      * @return the obis as string.
      */
     public String asDecimalString() {
+        Byte a = this.a;
+        Byte b = this.b;
+        Byte c = this.c;
+        Byte f = this.f;
         try (Formatter format = new Formatter()) {
             format.format(SmartMeterBindingConstants.OBIS_FORMAT, a != null ? a & 0xFF : 0, b != null ? b & 0xFF : 0,
                     c & 0xFF, d & 0xFF, e & 0xFF, f != null ? f & 0xFF : 0);
@@ -118,10 +122,15 @@ public class ObisCode {
         return asDecimalString();
     }
 
-    public boolean matches(@Nullable Byte a, @Nullable Byte b, Byte c, Byte d, Byte e, @Nullable Byte f) {
-        return (this.a == null || a == null || this.a.equals(a)) && (this.b == null || b == null || this.b.equals(b))
-                && this.c.equals(c) && this.d.equals(d) && this.e.equals(e)
-                && (this.f == null || f == null || this.f.equals(f));
+    public boolean matches(@Nullable Byte otherA, @Nullable Byte otherB, Byte otherC, Byte d, Byte e,
+            @Nullable Byte otherF) {
+        Byte a = this.a;
+        Byte b = this.b;
+        Byte c = this.c;
+        Byte f = this.f;
+        return (a == null || otherA == null || a.equals(otherA)) && (b == null || otherB == null || b.equals(otherB))
+                && c.equals(otherC) && this.d.equals(d) && this.e.equals(e)
+                && (f == null || otherF == null || f.equals(otherF));
     }
 
     public boolean matches(Byte c, Byte d, Byte e) {
index 0ce8d4667bad9aff5ee69cb4ec118f4486d74575..7ec6381dd0279204147094df6ef0324da14a2f27 100644 (file)
@@ -21,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import javax.measure.Quantity;
 import javax.measure.Unit;
 
-import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.smartmeter.SmartMeterBindingConstants;
 import org.openhab.core.library.CoreItemFactory;
@@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
  * @author Matthias Steigenberger - Initial contribution
  *
  */
+@NonNullByDefault
 @Component(service = { ChannelTypeProvider.class, SmartMeterChannelTypeProvider.class })
 public class SmartMeterChannelTypeProvider implements ChannelTypeProvider, MeterValueListener {
 
@@ -68,14 +69,14 @@ public class SmartMeterChannelTypeProvider implements ChannelTypeProvider, Meter
     }
 
     @Override
-    public <Q extends @NonNull Quantity<Q>> void valueChanged(MeterValue<Q> value) {
+    public <Q extends Quantity<Q>> void valueChanged(MeterValue<Q> value) {
         if (!obisChannelMap.containsKey(value.getObisCode())) {
             logger.debug("Creating ChannelType for OBIS {}", value.getObisCode());
             obisChannelMap.put(value.getObisCode(), getChannelType(value.getUnit(), value.getObisCode()));
         }
     }
 
-    private ChannelType getChannelType(Unit<?> unit, String obis) {
+    private ChannelType getChannelType(@Nullable Unit<?> unit, String obis) {
         String obisChannelId = SmartMeterBindingConstants.getObisChannelId(obis);
         StateChannelTypeBuilder stateDescriptionBuilder;
         if (unit != null) {
@@ -96,7 +97,7 @@ public class SmartMeterChannelTypeProvider implements ChannelTypeProvider, Meter
     }
 
     @Override
-    public <Q extends @NonNull Quantity<Q>> void valueRemoved(MeterValue<Q> value) {
+    public <Q extends Quantity<Q>> void valueRemoved(MeterValue<Q> value) {
         obisChannelMap.remove(value.getObisCode());
     }
 
@@ -106,7 +107,7 @@ public class SmartMeterChannelTypeProvider implements ChannelTypeProvider, Meter
      * @param obis The obis code.
      * @return The {@link ChannelTypeUID} or null.
      */
-    public ChannelTypeUID getChannelTypeIdForObis(String obis) {
+    public @Nullable ChannelTypeUID getChannelTypeIdForObis(String obis) {
         ChannelType channeltype = obisChannelMap.get(obis);
         return channeltype != null ? channeltype.getUID() : null;
     }
index 22f5efc5aa9944a0d833271bcb26be3c27920450..d7aab5aafb70d21b4b43f99278f141d603d61c42 100644 (file)
@@ -68,14 +68,13 @@ import io.reactivex.disposables.Disposable;
 public class SmartMeterHandler extends BaseThingHandler {
 
     private static final long DEFAULT_TIMEOUT = 30000;
-    private static final int DEFAULT_REFRESH_PERIOD = 30;
     private Logger logger = LoggerFactory.getLogger(SmartMeterHandler.class);
     private MeterDevice<?> smlDevice;
     private Disposable valueReader;
     private Conformity conformity;
     private MeterValueListener valueChangeListener;
     private SmartMeterChannelTypeProvider channelTypeProvider;
-    private @NonNull Supplier<SerialPortManager> serialPortManagerSupplier;
+    private Supplier<SerialPortManager> serialPortManagerSupplier;
 
     public SmartMeterHandler(Thing thing, SmartMeterChannelTypeProvider channelProvider,
             Supplier<SerialPortManager> serialPortManagerSupplier) {
@@ -99,11 +98,10 @@ public class SmartMeterHandler extends BaseThingHandler {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
                     "Parameter 'port' is mandatory and must be configured");
         } else {
-            byte[] pullSequence = config.initMessage == null ? null
-                    : HexUtils.hexToBytes(config.initMessage.replaceAll("\\s+", ""));
-            int baudrate = config.baudrate == null ? Baudrate.AUTO.getBaudrate()
-                    : Baudrate.fromString(config.baudrate).getBaudrate();
-            this.conformity = config.conformity == null ? Conformity.NONE : Conformity.valueOf(config.conformity);
+            String initMessage = config.initMessage;
+            byte[] pullSequence = initMessage == null ? null : HexUtils.hexToBytes(initMessage.replaceAll("\\s+", ""));
+            int baudrate = Baudrate.fromString(config.baudrate).getBaudrate();
+            this.conformity = Conformity.valueOf(config.conformity);
             this.smlDevice = MeterDeviceFactory.getDevice(serialPortManagerSupplier, config.mode,
                     this.thing.getUID().getAsString(), port, pullSequence, baudrate, config.baudrateChangeDelay);
             updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.HANDLER_CONFIGURATION_PENDING,
@@ -158,53 +156,58 @@ public class SmartMeterHandler extends BaseThingHandler {
 
                 String obisChannelString = SmartMeterBindingConstants.getObisChannelId(obis);
                 Channel channel = thing.getChannel(obisChannelString);
+
                 ChannelTypeUID channelTypeId = channelTypeProvider.getChannelTypeIdForObis(obis);
+                if (channelTypeId == null) {
+                    logger.warn("No ChannelTypeId found for OBIS {}", obis);
+                    return;
+                }
 
                 ChannelType channelType = channelTypeProvider.getChannelType(channelTypeId, null);
-                if (channelType != null) {
-                    String itemType = channelType.getItemType();
-
-                    State state = getStateForObisValue(value, channel);
-                    if (channel == null) {
-                        logger.debug("Adding channel: {} with item type: {}", obisChannelString, itemType);
-
-                        // channel has not been created yet
-                        ChannelBuilder channelBuilder = ChannelBuilder
-                                .create(new ChannelUID(thing.getUID(), obisChannelString), itemType)
-                                .withType(channelTypeId);
-
-                        Configuration configuration = new Configuration();
-                        configuration.put(SmartMeterBindingConstants.CONFIGURATION_CONVERSION, 1);
-                        channelBuilder.withConfiguration(configuration);
-                        channelBuilder.withLabel(obis);
-                        Map<String, String> channelProps = new HashMap<>();
-                        channelProps.put(SmartMeterBindingConstants.CHANNEL_PROPERTY_OBIS, obis);
-                        channelBuilder.withProperties(channelProps);
-                        channelBuilder.withDescription(
-                                MessageFormat.format("Value for OBIS code: {0} with Unit: {1}", obis, value.getUnit()));
-                        channel = channelBuilder.build();
-                        ChannelUID channelId = channel.getUID();
-
-                        // add all valid channels to the thing builder
-                        List<Channel> channels = new ArrayList<>(getThing().getChannels());
-                        if (channels.stream().filter((element) -> element.getUID().equals(channelId)).count() == 0) {
-                            channels.add(channel);
-                            thingBuilder.withChannels(channels);
-                            updateThing(thingBuilder.build());
-                        }
-                    }
-
-                    if (!channel.getProperties().containsKey(SmartMeterBindingConstants.CHANNEL_PROPERTY_OBIS)) {
-                        addObisPropertyToChannel(obis, channel);
-                    }
-                    if (state != null) {
-                        updateState(channel.getUID(), state);
+                if (channelType == null) {
+                    logger.warn("No ChannelType found for OBIS {}", obis);
+                    return;
+                }
+                String itemType = channelType.getItemType();
+
+                State state = getStateForObisValue(value, channel);
+                if (channel == null) {
+                    logger.debug("Adding channel: {} with item type: {}", obisChannelString, itemType);
+
+                    // channel has not been created yet
+                    ChannelBuilder channelBuilder = ChannelBuilder
+                            .create(new ChannelUID(thing.getUID(), obisChannelString), itemType)
+                            .withType(channelTypeId);
+
+                    Configuration configuration = new Configuration();
+                    configuration.put(SmartMeterBindingConstants.CONFIGURATION_CONVERSION, 1);
+                    channelBuilder.withConfiguration(configuration);
+                    channelBuilder.withLabel(obis);
+                    Map<String, String> channelProps = new HashMap<>();
+                    channelProps.put(SmartMeterBindingConstants.CHANNEL_PROPERTY_OBIS, obis);
+                    channelBuilder.withProperties(channelProps);
+                    channelBuilder.withDescription(
+                            MessageFormat.format("Value for OBIS code: {0} with Unit: {1}", obis, value.getUnit()));
+                    channel = channelBuilder.build();
+                    ChannelUID channelId = channel.getUID();
+
+                    // add all valid channels to the thing builder
+                    List<Channel> channels = new ArrayList<>(getThing().getChannels());
+                    if (channels.stream().filter((element) -> element.getUID().equals(channelId)).count() == 0) {
+                        channels.add(channel);
+                        thingBuilder.withChannels(channels);
+                        updateThing(thingBuilder.build());
                     }
+                }
 
-                    updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
-                } else {
-                    logger.warn("No ChannelType found for OBIS {}", obis);
+                if (!channel.getProperties().containsKey(SmartMeterBindingConstants.CHANNEL_PROPERTY_OBIS)) {
+                    addObisPropertyToChannel(obis, channel);
+                }
+                if (state != null) {
+                    updateState(channel.getUID(), state);
                 }
+
+                updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
             }
 
             private void addObisPropertyToChannel(String obis, Channel channel) {
@@ -238,8 +241,7 @@ public class SmartMeterHandler extends BaseThingHandler {
         this.smlDevice.addValueChangeListener(valueChangeListener);
 
         SmartMeterConfiguration config = getConfigAs(SmartMeterConfiguration.class);
-        int delay = config.refresh != null ? config.refresh : DEFAULT_REFRESH_PERIOD;
-        valueReader = this.smlDevice.readValues(DEFAULT_TIMEOUT, this.scheduler, Duration.ofSeconds(delay));
+        valueReader = this.smlDevice.readValues(DEFAULT_TIMEOUT, this.scheduler, Duration.ofSeconds(config.refresh));
     }
 
     private void updateOBISChannel(ChannelUID channelId) {
index 2ebf6b4e4a3ef1cf73567ae15617f8d7bfd29cd5..f707ae7baed6a077f23bd83b6c2d4946e816da86 100644 (file)
@@ -28,7 +28,6 @@ import org.openhab.core.library.unit.Units;
 import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.types.State;
-import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
@@ -89,7 +88,8 @@ public enum Conformity {
                                     }
                                 }
                             } catch (Exception e) {
-                                logger.warn("Failed to check negate status for obis {}", obis, e);
+                                LoggerFactory.getLogger(Conformity.class)
+                                        .warn("Failed to check negate status for obis {}", obis, e);
                             }
                         }
                     }
@@ -99,8 +99,6 @@ public enum Conformity {
         }
     };
 
-    private static final Logger logger = LoggerFactory.getLogger(Conformity.class);
-
     /**
      * Applies the overwritten negation setting for the channel.
      *
index 64393645f1b34645f729735e84b3f20f25d04ecd..a96fd1064a6313af9387860650d4ec769141a6ab 100644 (file)
@@ -17,7 +17,6 @@ import java.util.function.Function;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.smartmeter.internal.MeterValue;
-import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
@@ -28,7 +27,6 @@ import org.slf4j.LoggerFactory;
  */
 @NonNullByDefault
 public class NegateHandler {
-    private static final Logger LOGGER = LoggerFactory.getLogger(NegateHandler.class);
 
     /**
      * Gets whether negation should be applied for the given <code>negateProperty</code> and the {@link MeterValue}
@@ -71,7 +69,8 @@ public class NegateHandler {
         try {
             longValue = (long) Double.parseDouble(value);
         } catch (NumberFormatException e) {
-            LOGGER.warn("Failed to parse value: {} when determining isNegateSet, assuming false", value);
+            LoggerFactory.getLogger(NegateHandler.class)
+                    .warn("Failed to parse value: {} when determining isNegateSet, assuming false", value);
             return false;
         }
         return (longValue & (1L << negatePosition)) != 0;
diff --git a/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21MeterReader.java b/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21MeterReader.java
deleted file mode 100644 (file)
index a49aa6f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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.smartmeter.internal.iec62056;
-
-import java.util.function.Supplier;
-
-import javax.measure.Quantity;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.smartmeter.connectors.IMeterReaderConnector;
-import org.openhab.binding.smartmeter.internal.MeterDevice;
-import org.openhab.binding.smartmeter.internal.MeterValue;
-import org.openhab.binding.smartmeter.internal.helper.ProtocolMode;
-import org.openhab.core.io.transport.serial.SerialPortManager;
-import org.openmuc.j62056.DataMessage;
-import org.openmuc.j62056.DataSet;
-
-/**
- * Reads meter values from an IEC 62056-21 compatible device with mode A,B,C or D.
- *
- * @author Matthias Steigenberger - Initial contribution
- *
- */
-@NonNullByDefault
-public class Iec62056_21MeterReader extends MeterDevice<DataMessage> {
-
-    public Iec62056_21MeterReader(Supplier<SerialPortManager> serialPortManagerSupplier, String deviceId,
-            String serialPort, byte @Nullable [] initMessage, int baudrate, int baudrateChangeDelay,
-            ProtocolMode protocolMode) {
-        super(serialPortManagerSupplier, deviceId, serialPort, initMessage, baudrate, baudrateChangeDelay,
-                protocolMode);
-    }
-
-    @Override
-    protected IMeterReaderConnector<DataMessage> createConnector(Supplier<SerialPortManager> serialPortManagerSupplier,
-            String serialPort, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
-        return new Iec62056_21SerialConnector(serialPortManagerSupplier, serialPort, baudrate, baudrateChangeDelay,
-                protocolMode);
-    }
-
-    @Override
-    protected <Q extends @NonNull Quantity<Q>> void populateValueCache(DataMessage smlFile) {
-        for (DataSet dataSet : smlFile.getDataSets()) {
-            String address = dataSet.getAddress();
-            if (address != null && !address.isEmpty()) {
-                addObisCache(new MeterValue<Q>(address, dataSet.getValue(),
-                        Iec62056_21UnitConversion.getUnit(dataSet.getUnit())));
-            }
-        }
-    }
-}
diff --git a/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21SerialConnector.java b/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21SerialConnector.java
deleted file mode 100644 (file)
index 654a2e8..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * 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.smartmeter.internal.iec62056;
-
-import java.io.IOException;
-import java.time.Duration;
-import java.util.function.Supplier;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.smartmeter.connectors.ConnectorBase;
-import org.openhab.binding.smartmeter.internal.helper.Baudrate;
-import org.openhab.binding.smartmeter.internal.helper.ProtocolMode;
-import org.openhab.core.io.transport.serial.SerialPortManager;
-import org.openmuc.j62056.DataMessage;
-import org.openmuc.j62056.Iec21Port;
-import org.openmuc.j62056.Iec21Port.Builder;
-import org.openmuc.j62056.ModeDListener;
-import org.reactivestreams.Publisher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.reactivex.Flowable;
-import io.reactivex.FlowableEmitter;
-
-/**
- * This connector reads meter values with IEC62056-21 protocol.
- *
- * @author Matthias Steigenberger - Initial contribution
- *
- */
-@NonNullByDefault
-public class Iec62056_21SerialConnector extends ConnectorBase<DataMessage> {
-
-    private final Logger logger = LoggerFactory.getLogger(Iec62056_21SerialConnector.class);
-    private int baudrate;
-    private int baudrateChangeDelay;
-    private ProtocolMode protocolMode;
-    @Nullable
-    private Iec21Port iec21Port;
-
-    public Iec62056_21SerialConnector(Supplier<SerialPortManager> serialPortManagerSupplier, String portName,
-            int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
-        super(portName);
-        this.baudrate = baudrate;
-        this.baudrateChangeDelay = baudrateChangeDelay;
-        this.protocolMode = protocolMode;
-    }
-
-    @Override
-    protected boolean applyPeriod() {
-        return protocolMode != ProtocolMode.D;
-    }
-
-    @Override
-    protected boolean applyRetryHandling() {
-        return protocolMode != ProtocolMode.D;
-    }
-
-    @Override
-    protected Publisher<?> getRetryPublisher(Duration period, Publisher<Throwable> attempts) {
-        if (protocolMode == ProtocolMode.D) {
-            return Flowable.empty();
-        } else {
-            return super.getRetryPublisher(period, attempts);
-        }
-    }
-
-    @Override
-    protected DataMessage readNext(byte @Nullable [] initMessage) throws IOException {
-        if (iec21Port != null) {
-            DataMessage dataMessage = iec21Port.read();
-            logger.debug("Datamessage read: {}", dataMessage);
-            return dataMessage;
-        }
-        throw new IOException("SerialPort was not yet created!");
-    }
-
-    @Override
-    protected void emitValues(byte @Nullable [] initMessage, FlowableEmitter<@Nullable DataMessage> emitter)
-            throws IOException {
-        switch (protocolMode) {
-            case ABC:
-                super.emitValues(initMessage, emitter);
-                break;
-            case D:
-                if (iec21Port != null) {
-                    iec21Port.listen(new ModeDListener() {
-
-                        @Override
-                        public void newDataMessage(@Nullable DataMessage dataMessage) {
-                            logger.debug("Datamessage read: {}", dataMessage);
-                            emitter.onNext(dataMessage);
-                        }
-
-                        @Override
-                        public void exceptionWhileListening(@Nullable Exception e) {
-                            logger.warn("Exception while listening for mode D data message", e);
-                        }
-                    });
-                }
-                break;
-            case SML:
-                throw new IOException("SML mode not supported");
-        }
-    }
-
-    @Override
-    public void openConnection() throws IOException {
-        Builder iec21Builder = new Iec21Port.Builder(getPortName());
-        if (Baudrate.fromBaudrate(this.baudrate) != Baudrate.AUTO) {
-            iec21Builder.setInitialBaudrate(this.baudrate);
-        }
-        iec21Builder.setBaudRateChangeDelay(baudrateChangeDelay);
-        iec21Builder.enableVerboseMode(true);
-        iec21Port = iec21Builder.buildAndOpen();
-    }
-
-    @Override
-    public void closeConnection() {
-        if (iec21Port != null) {
-            iec21Port.close();
-        }
-    }
-}
diff --git a/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21UnitConversion.java b/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/Iec62056_21UnitConversion.java
deleted file mode 100644 (file)
index 059f9ef..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * 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.smartmeter.internal.iec62056;
-
-import javax.measure.Quantity;
-import javax.measure.Unit;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.types.util.UnitUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Converts a unit from IEC62056-21 protocol to a {@link Unit}
- *
- * @author Matthias Steigenberger - Initial contribution
- *
- */
-@NonNullByDefault
-public class Iec62056_21UnitConversion {
-
-    private static final Logger logger = LoggerFactory.getLogger(Iec62056_21UnitConversion.class);
-
-    @SuppressWarnings("unchecked")
-    public static @Nullable <Q extends Quantity<Q>> Unit<Q> getUnit(String unit) {
-        if (!unit.isEmpty()) {
-            try {
-                return (Unit<Q>) UnitUtils.parseUnit(" " + unit);
-            } catch (Exception e) {
-                logger.warn("Failed to parse unit {}: {}", unit, e.getMessage());
-                return null;
-            }
-        }
-        return null;
-    }
-}
diff --git a/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/MeterReader.java b/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/MeterReader.java
new file mode 100644 (file)
index 0000000..38520b7
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * 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.smartmeter.internal.iec62056;
+
+import java.util.function.Supplier;
+
+import javax.measure.Quantity;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.smartmeter.connectors.IMeterReaderConnector;
+import org.openhab.binding.smartmeter.internal.MeterDevice;
+import org.openhab.binding.smartmeter.internal.MeterValue;
+import org.openhab.binding.smartmeter.internal.helper.ProtocolMode;
+import org.openhab.core.io.transport.serial.SerialPortManager;
+import org.openmuc.j62056.DataMessage;
+import org.openmuc.j62056.DataSet;
+
+/**
+ * Reads meter values from an IEC 62056-21 compatible device with mode A,B,C or D.
+ *
+ * @author Matthias Steigenberger - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class MeterReader extends MeterDevice<DataMessage> {
+
+    public MeterReader(Supplier<SerialPortManager> serialPortManagerSupplier, String deviceId, String serialPort,
+            byte @Nullable [] initMessage, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
+        super(serialPortManagerSupplier, deviceId, serialPort, initMessage, baudrate, baudrateChangeDelay,
+                protocolMode);
+    }
+
+    @Override
+    protected IMeterReaderConnector<DataMessage> createConnector(Supplier<SerialPortManager> serialPortManagerSupplier,
+            String serialPort, int baudrate, int baudrateChangeDelay, ProtocolMode protocolMode) {
+        return new SerialConnector(serialPortManagerSupplier, serialPort, baudrate, baudrateChangeDelay, protocolMode);
+    }
+
+    @Override
+    protected <Q extends Quantity<Q>> void populateValueCache(DataMessage smlFile) {
+        for (DataSet dataSet : smlFile.getDataSets()) {
+            String address = dataSet.getAddress();
+            if (address != null && !address.isEmpty()) {
+                addObisCache(new MeterValue<Q>(address, dataSet.getValue(), UnitConversion.getUnit(dataSet.getUnit())));
+            }
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/SerialConnector.java b/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/SerialConnector.java
new file mode 100644 (file)
index 0000000..3ec4131
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * 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.smartmeter.internal.iec62056;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.function.Supplier;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.smartmeter.connectors.ConnectorBase;
+import org.openhab.binding.smartmeter.internal.helper.Baudrate;
+import org.openhab.binding.smartmeter.internal.helper.ProtocolMode;
+import org.openhab.core.io.transport.serial.SerialPortManager;
+import org.openmuc.j62056.DataMessage;
+import org.openmuc.j62056.Iec21Port;
+import org.openmuc.j62056.Iec21Port.Builder;
+import org.openmuc.j62056.ModeDListener;
+import org.reactivestreams.Publisher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.reactivex.Flowable;
+import io.reactivex.FlowableEmitter;
+
+/**
+ * This connector reads meter values with IEC62056-21 protocol.
+ *
+ * @author Matthias Steigenberger - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class SerialConnector extends ConnectorBase<DataMessage> {
+
+    private final Logger logger = LoggerFactory.getLogger(SerialConnector.class);
+    private int baudrate;
+    private int baudrateChangeDelay;
+    private ProtocolMode protocolMode;
+    @Nullable
+    private Iec21Port iec21Port;
+
+    public SerialConnector(Supplier<SerialPortManager> serialPortManagerSupplier, String portName, int baudrate,
+            int baudrateChangeDelay, ProtocolMode protocolMode) {
+        super(portName);
+        this.baudrate = baudrate;
+        this.baudrateChangeDelay = baudrateChangeDelay;
+        this.protocolMode = protocolMode;
+    }
+
+    @Override
+    protected boolean applyPeriod() {
+        return protocolMode != ProtocolMode.D;
+    }
+
+    @Override
+    protected boolean applyRetryHandling() {
+        return protocolMode != ProtocolMode.D;
+    }
+
+    @Override
+    protected Publisher<?> getRetryPublisher(Duration period, Publisher<Throwable> attempts) {
+        if (protocolMode == ProtocolMode.D) {
+            return Flowable.empty();
+        } else {
+            return super.getRetryPublisher(period, attempts);
+        }
+    }
+
+    @Override
+    protected DataMessage readNext(byte @Nullable [] initMessage) throws IOException {
+        Iec21Port iec21Port = this.iec21Port;
+        if (iec21Port != null) {
+            DataMessage dataMessage = iec21Port.read();
+            logger.debug("Datamessage read: {}", dataMessage);
+            return dataMessage;
+        }
+        throw new IOException("SerialPort was not yet created!");
+    }
+
+    @Override
+    protected void emitValues(byte @Nullable [] initMessage, FlowableEmitter<@Nullable DataMessage> emitter)
+            throws IOException {
+        switch (protocolMode) {
+            case ABC:
+                super.emitValues(initMessage, emitter);
+                break;
+            case D:
+                Iec21Port iec21Port = this.iec21Port;
+                if (iec21Port != null) {
+                    iec21Port.listen(new ModeDListener() {
+
+                        @Override
+                        public void newDataMessage(@Nullable DataMessage dataMessage) {
+                            logger.debug("Datamessage read: {}", dataMessage);
+                            emitter.onNext(dataMessage);
+                        }
+
+                        @Override
+                        public void exceptionWhileListening(@Nullable Exception e) {
+                            logger.warn("Exception while listening for mode D data message", e);
+                        }
+                    });
+                    this.iec21Port = iec21Port;
+                }
+                break;
+            case SML:
+                throw new IOException("SML mode not supported");
+        }
+    }
+
+    @Override
+    public void openConnection() throws IOException {
+        Builder iec21Builder = new Iec21Port.Builder(getPortName());
+        if (Baudrate.fromBaudrate(this.baudrate) != Baudrate.AUTO) {
+            iec21Builder.setInitialBaudrate(this.baudrate);
+        }
+        iec21Builder.setBaudRateChangeDelay(baudrateChangeDelay);
+        iec21Builder.enableVerboseMode(true);
+        iec21Port = iec21Builder.buildAndOpen();
+    }
+
+    @Override
+    public void closeConnection() {
+        Iec21Port iec21Port = this.iec21Port;
+        if (iec21Port != null) {
+            iec21Port.close();
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/UnitConversion.java b/bundles/org.openhab.binding.smartmeter/src/main/java/org/openhab/binding/smartmeter/internal/iec62056/UnitConversion.java
new file mode 100644 (file)
index 0000000..a43cfe0
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * 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.smartmeter.internal.iec62056;
+
+import javax.measure.Quantity;
+import javax.measure.Unit;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.types.util.UnitUtils;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Converts a unit from IEC62056-21 protocol to a {@link Unit}
+ *
+ * @author Matthias Steigenberger - Initial contribution
+ *
+ */
+@NonNullByDefault
+public class UnitConversion {
+
+    @SuppressWarnings("unchecked")
+    public static @Nullable <Q extends Quantity<Q>> Unit<Q> getUnit(String unit) {
+        if (!unit.isEmpty()) {
+            try {
+                return (Unit<Q>) UnitUtils.parseUnit(" " + unit);
+            } catch (Exception e) {
+                LoggerFactory.getLogger(UnitConversion.class).warn("Failed to parse unit {}: {}", unit, e.getMessage());
+                return null;
+            }
+        }
+        return null;
+    }
+}
index 480256675ebd1a45dcf1a535562c35e97c548674..ae33730db29e8ee5d7272f8500b3f67252211ae8 100644 (file)
@@ -105,48 +105,48 @@ public class SmlFileDebugOutput {
 
     private static void parseGetListResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got GetListResponse");
-        SmlGetListRes sml_listRes = (SmlGetListRes) smlMessage.getMessageBody().getChoice();
+        SmlGetListRes smlListRes = (SmlGetListRes) smlMessage.getMessageBody().getChoice();
 
         // consumer.accept(sml_listRes.toString());
 
-        consumer.accept(sml_listRes.toStringIndent(" "));
+        consumer.accept(smlListRes.toStringIndent(" "));
     }
 
     private static void parseAttentionResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got AttentionResponse");
-        SmlAttentionRes sml_attentionRes = (SmlAttentionRes) smlMessage.getMessageBody().getChoice();
-        consumer.accept(sml_attentionRes.toString());
+        SmlAttentionRes smlAttentionRes = (SmlAttentionRes) smlMessage.getMessageBody().getChoice();
+        consumer.accept(smlAttentionRes.toString());
     }
 
     private static void parseGetProcParameterResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got GetProcParameterResponse");
-        SmlGetProcParameterRes sml_getProcParameterRes = (SmlGetProcParameterRes) smlMessage.getMessageBody()
+        SmlGetProcParameterRes smlGetProcParameterRes = (SmlGetProcParameterRes) smlMessage.getMessageBody()
                 .getChoice();
-        consumer.accept(sml_getProcParameterRes.toString());
+        consumer.accept(smlGetProcParameterRes.toString());
     }
 
     private static void parseGetProfileListResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got GetProfileListResponse");
-        SmlGetProfileListRes sml_getProfileListRes = (SmlGetProfileListRes) smlMessage.getMessageBody().getChoice();
-        consumer.accept(sml_getProfileListRes.toString());
+        SmlGetProfileListRes smlGetProfileListRes = (SmlGetProfileListRes) smlMessage.getMessageBody().getChoice();
+        consumer.accept(smlGetProfileListRes.toString());
     }
 
     private static void parseOpenResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got OpenResponse");
-        SmlPublicOpenRes sml_PublicOpenRes = (SmlPublicOpenRes) smlMessage.getMessageBody().getChoice();
-        consumer.accept(sml_PublicOpenRes.toString());
+        SmlPublicOpenRes smlPublicOpenRes = (SmlPublicOpenRes) smlMessage.getMessageBody().getChoice();
+        consumer.accept(smlPublicOpenRes.toString());
     }
 
     private static void parseCloseResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got CloseResponse");
-        SmlPublicCloseRes sml_PublicCloseRes = (SmlPublicCloseRes) smlMessage.getMessageBody().getChoice();
-        consumer.accept(sml_PublicCloseRes.toString());
+        SmlPublicCloseRes smlPublicCloseRes = (SmlPublicCloseRes) smlMessage.getMessageBody().getChoice();
+        consumer.accept(smlPublicCloseRes.toString());
     }
 
     private static void parseGetProfilePackResponse(SmlMessage smlMessage, Consumer<String> consumer) {
         consumer.accept("Got GetProfilePackResponse");
-        SmlGetProfilePackRes sml_getProfilePackRes = (SmlGetProfilePackRes) smlMessage.getMessageBody().getChoice();
-        consumer.accept(sml_getProfilePackRes.toString());
+        SmlGetProfilePackRes smlGetProfilePackRes = (SmlGetProfilePackRes) smlMessage.getMessageBody().getChoice();
+        consumer.accept(smlGetProfilePackRes.toString());
     }
 
     // ========================= Requests =================================
index 8e1959fadb3ab25b2a5ba38655ecff9b6cf5b410..c1004f25639d560dae21254dc9511e7d43feb48b 100644 (file)
@@ -81,6 +81,7 @@ public final class SmlSerialConnector extends ConnectorBase<SmlFile> {
     protected SmlFile readNext(byte @Nullable [] initMessage) throws IOException {
         if (initMessage != null) {
             logger.debug("Writing init message: {}", HexUtils.bytesToHex(initMessage, " "));
+            DataOutputStream os = this.os;
             if (os != null) {
                 os.write(initMessage);
                 os.flush();
@@ -89,6 +90,7 @@ public final class SmlSerialConnector extends ConnectorBase<SmlFile> {
 
         // read out the whole buffer. We are only interested in the most recent SML file.
         Stack<SmlFile> smlFiles = new Stack<>();
+        DataInputStream is = this.is;
         do {
             logger.trace("Reading {}. SML message", smlFiles.size() + 1);
             smlFiles.push(TRANSPORT.getSMLFile(is));
@@ -137,12 +139,10 @@ public final class SmlSerialConnector extends ConnectorBase<SmlFile> {
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void closeConnection() {
         try {
+            DataInputStream is = this.is;
             if (is != null) {
                 is.close();
                 is = null;
@@ -151,6 +151,7 @@ public final class SmlSerialConnector extends ConnectorBase<SmlFile> {
             logger.error("Failed to close serial input stream", e);
         }
         try {
+            DataOutputStream os = this.os;
             if (os != null) {
                 os.close();
                 os = null;
index 25b41dd91f04816651ad8c75c68f3cd6d58672ae..81f601902bcd4bf662c12ca79351c3e46f884629 100644 (file)
@@ -15,6 +15,8 @@ package org.openhab.binding.smartmeter;
 import java.io.IOException;
 import java.util.function.Supplier;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.smartmeter.connectors.ConnectorBase;
 
 /**
@@ -22,6 +24,7 @@ import org.openhab.binding.smartmeter.connectors.ConnectorBase;
  * @author Matthias Steigenberger - Initial contribution
  *
  */
+@NonNullByDefault
 public class MockMeterReaderConnector extends ConnectorBase<Object> {
 
     private boolean applyRetry;
@@ -42,12 +45,12 @@ public class MockMeterReaderConnector extends ConnectorBase<Object> {
     }
 
     @Override
-    protected Object readNext(byte[] initMessage) throws IOException {
+    protected Object readNext(byte @Nullable [] initMessage) throws IOException {
         try {
             return readNextSupplier.get();
         } catch (RuntimeException e) {
-            if (e.getCause() instanceof IOException) {
-                throw (IOException) e.getCause();
+            if (e.getCause() instanceof IOException cause) {
+                throw cause;
             }
             throw e;
         }
index 5f3acee95886e7d24cbc84e01337851e3b6219d7..54ad89ffc0bb29812c0f86a6ea9a82c3842fdb80 100644 (file)
@@ -23,7 +23,7 @@ import java.util.function.Supplier;
 
 import javax.measure.Quantity;
 
-import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mockito;
@@ -44,6 +44,7 @@ import io.reactivex.plugins.RxJavaPlugins;
  * @author Matthias Steigenberger - Initial contribution
  *
  */
+@NonNullByDefault
 public class TestMeterReading {
 
     @Test
@@ -118,6 +119,7 @@ public class TestMeterReading {
             throw new RuntimeException(new IOException("fucked up"));
         }));
         MeterDevice<Object> meter = getMeterDevice(connector);
+        @SuppressWarnings("unchecked")
         Consumer<Throwable> errorHandler = mock(Consumer.class);
         RxJavaPlugins.setErrorHandler(errorHandler);
         MeterValueListener changeListener = Mockito.mock(MeterValueListener.class);
@@ -139,14 +141,15 @@ public class TestMeterReading {
         return new MeterDevice<>(() -> mock(SerialPortManager.class), "id", "port", null, 9600, 0, ProtocolMode.SML) {
 
             @Override
-            protected @NonNull IMeterReaderConnector<Object> createConnector(
-                    @NonNull Supplier<@NonNull SerialPortManager> serialPortManagerSupplier, @NonNull String serialPort,
-                    int baudrate, int baudrateChangeDelay, @NonNull ProtocolMode protocolMode) {
+            protected IMeterReaderConnector<Object> createConnector(
+                    Supplier<SerialPortManager> serialPortManagerSupplier, String serialPort, int baudrate,
+                    int baudrateChangeDelay, ProtocolMode protocolMode) {
                 return connector;
             }
 
+            @SuppressWarnings({ "rawtypes", "unchecked" })
             @Override
-            protected <Q extends @NonNull Quantity<Q>> void populateValueCache(Object smlFile) {
+            protected <Q extends Quantity<Q>> void populateValueCache(Object smlFile) {
                 addObisCache(new MeterValue("123", "333", null));
             }
         };
index 4b6de5643c5cbbe65b557cd8df96909607a6dda6..dc919d10738f88a585e0390f6671a70620d0d50b 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.smartmeter;
 
 import static org.junit.jupiter.api.Assertions.*;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.junit.jupiter.api.Test;
 import org.openhab.binding.smartmeter.internal.MeterValue;
 import org.openhab.binding.smartmeter.internal.conformity.negate.NegateBitModel;
@@ -25,6 +26,7 @@ import org.openhab.binding.smartmeter.internal.conformity.negate.NegateHandler;
  * @author Matthias Steigenberger - Initial contribution
  *
  */
+@NonNullByDefault
 public class TestNegateBit {
 
     @Test