[dsmr] Made additional key for smarty meter an option (#13359)

* [dsmr] Made additional key for smarty meter optional

Signed-off-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
This commit is contained in:
Hilbrand Bouwkamp 2022-09-07 11:08:04 +02:00 committed by GitHub
parent c4625992af
commit 18a41dbe84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 72 additions and 40 deletions

View File

@ -72,6 +72,7 @@ The configuration for the `smartyBridge` consists of the following parameters:
|---------------------|-------------------------------------------------------------------------------------------------------------| |---------------------|-------------------------------------------------------------------------------------------------------------|
| serialPort | The serial port where the P1-port is connected to (e.g. Linux: `/dev/ttyUSB1`, Windows: `COM2`) (mandatory) | | serialPort | The serial port where the P1-port is connected to (e.g. Linux: `/dev/ttyUSB1`, Windows: `COM2`) (mandatory) |
| decryptionKey | The meter specific decryption key (mandatory) | | decryptionKey | The meter specific decryption key (mandatory) |
| additionalKey | Additional key for meters that require a secondary key. Some meters in Austria require this |
| receivedTimeout | The time out period in which messages are expected to arrive, default is 120 seconds | | receivedTimeout | The time out period in which messages are expected to arrive, default is 120 seconds |

View File

@ -46,6 +46,8 @@ public final class DSMRBindingConstants {
public static final String CONFIGURATION_DECRYPTION_KEY = "decryptionKey"; public static final String CONFIGURATION_DECRYPTION_KEY = "decryptionKey";
public static final String CONFIGURATION_DECRYPTION_KEY_EMPTY = ""; public static final String CONFIGURATION_DECRYPTION_KEY_EMPTY = "";
public static final String CONFIGURATION_ADDITIONAL_KEY = "additionalKey";
public static final String ADDITIONAL_KEY_DEFAULT = "3000112233445566778899AABBCCDDEEFF";
private DSMRBindingConstants() { private DSMRBindingConstants() {
// Constants class // Constants class

View File

@ -12,6 +12,8 @@
*/ */
package org.openhab.binding.dsmr.internal.device; package org.openhab.binding.dsmr.internal.device;
import org.openhab.binding.dsmr.internal.DSMRBindingConstants;
/** /**
* Class describing the DSMR bridge user configuration * Class describing the DSMR bridge user configuration
* *
@ -19,6 +21,7 @@ package org.openhab.binding.dsmr.internal.device;
* @author Hilbrand Bouwkamp - added receivedTimeout configuration * @author Hilbrand Bouwkamp - added receivedTimeout configuration
*/ */
public class DSMRDeviceConfiguration { public class DSMRDeviceConfiguration {
/** /**
* Serial port name * Serial port name
*/ */
@ -45,10 +48,15 @@ public class DSMRDeviceConfiguration {
public String stopbits; public String stopbits;
/** /**
* The Luxembourgish smart meter decryption key * The Luxembourgish/Austria smart meter decryption key
*/ */
public String decryptionKey; public String decryptionKey;
/**
* Austria smart meter additional decryption key
*/
public String additionalKey = DSMRBindingConstants.ADDITIONAL_KEY_DEFAULT;
/** /**
* When no message was received after the configured number of seconds action will be taken. * When no message was received after the configured number of seconds action will be taken.
*/ */
@ -66,6 +74,6 @@ public class DSMRDeviceConfiguration {
public String toString() { public String toString() {
return "DSMRDeviceConfiguration [serialPort=" + serialPort + ", Baudrate=" + baudrate + ", Databits=" + databits return "DSMRDeviceConfiguration [serialPort=" + serialPort + ", Baudrate=" + baudrate + ", Databits=" + databits
+ ", Parity=" + parity + ", Stopbits=" + stopbits + ", decryptionKey=" + decryptionKey + ", Parity=" + parity + ", Stopbits=" + stopbits + ", decryptionKey=" + decryptionKey
+ ", receivedTimeout=" + receivedTimeout + "]"; + ", additionalKey=" + additionalKey + ", receivedTimeout=" + receivedTimeout + "]";
} }
} }

View File

@ -55,9 +55,10 @@ public class DSMRTelegramListener implements P1TelegramListener, DSMRConnectorLi
* Constructs {@link DSMRTelegramListener} with a Smarty decryptor to first decrypt incoming messages. * Constructs {@link DSMRTelegramListener} with a Smarty decryptor to first decrypt incoming messages.
* *
* @param decryptionKey Smarty decryption key * @param decryptionKey Smarty decryption key
* @param additionalKey Additional optional descryption key
*/ */
public DSMRTelegramListener(String decryptionKey) { public DSMRTelegramListener(final String decryptionKey, final String additionalKey) {
parser = new SmartyDecrypter(new P1TelegramParser(this), this, decryptionKey); parser = new SmartyDecrypter(new P1TelegramParser(this), this, decryptionKey, additionalKey);
} }
/** /**
@ -65,17 +66,17 @@ public class DSMRTelegramListener implements P1TelegramListener, DSMRConnectorLi
* *
* @param eventListener the listener to set * @param eventListener the listener to set
*/ */
public void setDsmrEventListener(DSMREventListener eventListener) { public void setDsmrEventListener(final DSMREventListener eventListener) {
this.dsmrEventListener = eventListener; this.dsmrEventListener = eventListener;
} }
@Override @Override
public void handleData(byte[] data, int length) { public void handleData(final byte[] data, final int length) {
parser.parse(data, length); parser.parse(data, length);
} }
@Override @Override
public void handleErrorEvent(DSMRConnectorErrorEvent portEvent) { public void handleErrorEvent(final DSMRConnectorErrorEvent portEvent) {
dsmrEventListener.handleErrorEvent(portEvent); dsmrEventListener.handleErrorEvent(portEvent);
parser.reset(); parser.reset();
} }
@ -86,7 +87,7 @@ public class DSMRTelegramListener implements P1TelegramListener, DSMRConnectorLi
* @param telegram the received telegram. * @param telegram the received telegram.
*/ */
@Override @Override
public void telegramReceived(P1Telegram telegram) { public void telegramReceived(final P1Telegram telegram) {
final TelegramState telegramState = telegram.getTelegramState(); final TelegramState telegramState = telegram.getTelegramState();
final List<CosemObject> cosemObjects = telegram.getCosemObjects(); final List<CosemObject> cosemObjects = telegram.getCosemObjects();
@ -106,7 +107,7 @@ public class DSMRTelegramListener implements P1TelegramListener, DSMRConnectorLi
/** /**
* @param lenientMode the lenientMode to set * @param lenientMode the lenientMode to set
*/ */
public void setLenientMode(boolean lenientMode) { public void setLenientMode(final boolean lenientMode) {
parser.setLenientMode(lenientMode); parser.setLenientMode(lenientMode);
} }
} }

View File

@ -27,6 +27,7 @@ import javax.crypto.spec.SecretKeySpec;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.dsmr.internal.DSMRBindingConstants;
import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram; import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram;
import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram.TelegramState; import org.openhab.binding.dsmr.internal.device.p1telegram.P1Telegram.TelegramState;
import org.openhab.binding.dsmr.internal.device.p1telegram.P1TelegramListener; import org.openhab.binding.dsmr.internal.device.p1telegram.P1TelegramListener;
@ -60,12 +61,11 @@ public class SmartyDecrypter implements TelegramParser {
private static final byte SEPARATOR_82 = (byte) 0x82; private static final byte SEPARATOR_82 = (byte) 0x82;
private static final byte SEPARATOR_30 = 0x30; private static final byte SEPARATOR_30 = 0x30;
private static final int ADD_LENGTH = 17; private static final int ADD_LENGTH = 17;
private static final String ADD = "3000112233445566778899AABBCCDDEEFF";
private static final byte[] ADD_DECODED = HexUtils.hexToBytes(ADD);
private static final int IV_BUFFER_LENGTH = 40; private static final int IV_BUFFER_LENGTH = 40;
private static final int GCM_TAG_LENGTH = 12; private static final int GCM_TAG_LENGTH = 12;
private static final int GCM_BITS = GCM_TAG_LENGTH * Byte.SIZE; private static final int GCM_BITS = GCM_TAG_LENGTH * Byte.SIZE;
private static final int MESSAGES_BUFFER_SIZE = 4096; private static final int MESSAGES_BUFFER_SIZE = 4096;
private static final String ADDITIONAL_ADD_PREFIX = "30";
private final Logger logger = LoggerFactory.getLogger(SmartyDecrypter.class); private final Logger logger = LoggerFactory.getLogger(SmartyDecrypter.class);
private final ByteBuffer iv = ByteBuffer.allocate(IV_BUFFER_LENGTH); private final ByteBuffer iv = ByteBuffer.allocate(IV_BUFFER_LENGTH);
@ -80,6 +80,7 @@ public class SmartyDecrypter implements TelegramParser {
private int dataLength; private int dataLength;
private boolean lenientMode; private boolean lenientMode;
private final P1TelegramListener telegramListener; private final P1TelegramListener telegramListener;
private final byte[] addKey;
/** /**
* Constructor. * Constructor.
@ -87,12 +88,15 @@ public class SmartyDecrypter implements TelegramParser {
* @param parser parser of the Cosem messages * @param parser parser of the Cosem messages
* @param telegramListener * @param telegramListener
* @param decryptionKey The key to decrypt the messages * @param decryptionKey The key to decrypt the messages
* @param additionalKey Additional optional key to decrypt the message
*/ */
public SmartyDecrypter(final TelegramParser parser, final P1TelegramListener telegramListener, public SmartyDecrypter(final TelegramParser parser, final P1TelegramListener telegramListener,
final String decryptionKey) { final String decryptionKey, final String additionalKey) {
this.parser = parser; this.parser = parser;
this.telegramListener = telegramListener; this.telegramListener = telegramListener;
secretKeySpec = decryptionKey.isEmpty() ? null : new SecretKeySpec(HexUtils.hexToBytes(decryptionKey), "AES"); secretKeySpec = decryptionKey.isEmpty() ? null : new SecretKeySpec(HexUtils.hexToBytes(decryptionKey), "AES");
addKey = HexUtils.hexToBytes(additionalKey.isBlank() ? DSMRBindingConstants.ADDITIONAL_KEY_DEFAULT
: ((additionalKey.length() == 32 ? (ADDITIONAL_ADD_PREFIX) : "") + additionalKey));
} }
@Override @Override
@ -209,7 +213,7 @@ public class SmartyDecrypter implements TelegramParser {
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, cipher.init(Cipher.DECRYPT_MODE, secretKeySpec,
new GCMParameterSpec(GCM_BITS, iv.array(), 0, ivLength)); new GCMParameterSpec(GCM_BITS, iv.array(), 0, ivLength));
cipher.updateAAD(ADD_DECODED); cipher.updateAAD(addKey);
return cipher.doFinal(cipherText.array(), 0, cipherText.position()); return cipher.doFinal(cipherText.array(), 0, cipherText.position());
} }
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException

View File

@ -12,7 +12,13 @@
*/ */
package org.openhab.binding.dsmr.internal.discovery; package org.openhab.binding.dsmr.internal.discovery;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.*; import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.CONFIGURATION_ADDITIONAL_KEY;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.CONFIGURATION_DECRYPTION_KEY;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.CONFIGURATION_DECRYPTION_KEY_EMPTY;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.CONFIGURATION_SERIAL_PORT;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.DSMR_PORT_NAME;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.THING_TYPE_DSMR_BRIDGE;
import static org.openhab.binding.dsmr.internal.DSMRBindingConstants.THING_TYPE_SMARTY_BRIDGE;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -109,7 +115,7 @@ public class DSMRBridgeDiscoveryService extends DSMRDiscoveryService implements
protected void startScan() { protected void startScan() {
logger.debug("Started DSMR discovery scan"); logger.debug("Started DSMR discovery scan");
scanning = true; scanning = true;
Stream<SerialPortIdentifier> portEnum = serialPortManager.getIdentifiers(); final Stream<SerialPortIdentifier> portEnum = serialPortManager.getIdentifiers();
// Traverse each available serial port // Traverse each available serial port
portEnum.forEach(portIdentifier -> { portEnum.forEach(portIdentifier -> {
@ -126,7 +132,8 @@ public class DSMRBridgeDiscoveryService extends DSMRDiscoveryService implements
} else { } else {
logger.debug("Start discovery on serial port: {}", currentScannedPortName); logger.debug("Start discovery on serial port: {}", currentScannedPortName);
// //
final DSMRTelegramListener telegramListener = new DSMRTelegramListener(""); final DSMRTelegramListener telegramListener = new DSMRTelegramListener("",
CONFIGURATION_ADDITIONAL_KEY);
final DSMRSerialAutoDevice device = new DSMRSerialAutoDevice(serialPortManager, final DSMRSerialAutoDevice device = new DSMRSerialAutoDevice(serialPortManager,
portIdentifier.getName(), this, telegramListener, scheduler, portIdentifier.getName(), this, telegramListener, scheduler,
BAUDRATE_SWITCH_TIMEOUT_SECONDS); BAUDRATE_SWITCH_TIMEOUT_SECONDS);
@ -166,8 +173,8 @@ public class DSMRBridgeDiscoveryService extends DSMRDiscoveryService implements
* @param telegram the received telegram * @param telegram the received telegram
*/ */
@Override @Override
public void handleTelegramReceived(P1Telegram telegram) { public void handleTelegramReceived(final P1Telegram telegram) {
List<CosemObject> cosemObjects = telegram.getCosemObjects(); final List<CosemObject> cosemObjects = telegram.getCosemObjects();
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("[{}] Received {} cosemObjects", currentScannedPortName, cosemObjects.size()); logger.debug("[{}] Received {} cosemObjects", currentScannedPortName, cosemObjects.size());
@ -176,7 +183,7 @@ public class DSMRBridgeDiscoveryService extends DSMRDiscoveryService implements
bridgeDiscovered(THING_TYPE_SMARTY_BRIDGE); bridgeDiscovered(THING_TYPE_SMARTY_BRIDGE);
stopSerialPortScan(); stopSerialPortScan();
} else if (!cosemObjects.isEmpty()) { } else if (!cosemObjects.isEmpty()) {
ThingUID bridgeThingUID = bridgeDiscovered(THING_TYPE_DSMR_BRIDGE); final ThingUID bridgeThingUID = bridgeDiscovered(THING_TYPE_DSMR_BRIDGE);
meterDetector.detectMeters(telegram).getKey().forEach(m -> meterDiscovered(m, bridgeThingUID)); meterDetector.detectMeters(telegram).getKey().forEach(m -> meterDiscovered(m, bridgeThingUID));
stopSerialPortScan(); stopSerialPortScan();
} }
@ -187,19 +194,21 @@ public class DSMRBridgeDiscoveryService extends DSMRDiscoveryService implements
* *
* @return The {@link ThingUID} of the newly created bridge * @return The {@link ThingUID} of the newly created bridge
*/ */
private ThingUID bridgeDiscovered(ThingTypeUID bridgeThingTypeUID) { private ThingUID bridgeDiscovered(final ThingTypeUID bridgeThingTypeUID) {
ThingUID thingUID = new ThingUID(bridgeThingTypeUID, Integer.toHexString(currentScannedPortName.hashCode())); final ThingUID thingUID = new ThingUID(bridgeThingTypeUID,
Integer.toHexString(currentScannedPortName.hashCode()));
final boolean smarty = THING_TYPE_SMARTY_BRIDGE.equals(bridgeThingTypeUID); final boolean smarty = THING_TYPE_SMARTY_BRIDGE.equals(bridgeThingTypeUID);
final String label = String.format("@text/thing-type.dsmr.%s.label", smarty ? "smartyBridge" : "dsmrBridge"); final String label = String.format("@text/thing-type.dsmr.%s.label", smarty ? "smartyBridge" : "dsmrBridge");
// Construct the configuration for this meter // Construct the configuration for this meter
Map<String, Object> properties = new HashMap<>(); final Map<String, Object> properties = new HashMap<>();
properties.put(CONFIGURATION_SERIAL_PORT, currentScannedPortName); properties.put(CONFIGURATION_SERIAL_PORT, currentScannedPortName);
if (smarty) { if (smarty) {
properties.put(CONFIGURATION_DECRYPTION_KEY, CONFIGURATION_DECRYPTION_KEY_EMPTY); properties.put(CONFIGURATION_DECRYPTION_KEY, CONFIGURATION_DECRYPTION_KEY_EMPTY);
properties.put(CONFIGURATION_ADDITIONAL_KEY, CONFIGURATION_ADDITIONAL_KEY);
} }
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(bridgeThingTypeUID) final DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID)
.withProperties(properties).withLabel(label).build(); .withThingType(bridgeThingTypeUID).withProperties(properties).withLabel(label).build();
logger.debug("[{}] discovery result:{}", currentScannedPortName, discoveryResult); logger.debug("[{}] discovery result:{}", currentScannedPortName, discoveryResult);
@ -208,7 +217,7 @@ public class DSMRBridgeDiscoveryService extends DSMRDiscoveryService implements
} }
@Override @Override
public void handleErrorEvent(DSMRConnectorErrorEvent portEvent) { public void handleErrorEvent(final DSMRConnectorErrorEvent portEvent) {
logger.debug("[{}] Error on port during discovery: {}", currentScannedPortName, portEvent); logger.debug("[{}] Error on port during discovery: {}", currentScannedPortName, portEvent);
stopSerialPortScan(); stopSerialPortScan();
} }

View File

@ -111,7 +111,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* @param bridge the Bridge ThingType * @param bridge the Bridge ThingType
* @param serialPortManager The Serial port manager * @param serialPortManager The Serial port manager
*/ */
public DSMRBridgeHandler(Bridge bridge, SerialPortManager serialPortManager) { public DSMRBridgeHandler(final Bridge bridge, final SerialPortManager serialPortManager) {
super(bridge); super(bridge);
this.serialPortManager = serialPortManager; this.serialPortManager = serialPortManager;
smartyMeter = THING_TYPE_SMARTY_BRIDGE.equals(bridge.getThingTypeUID()); smartyMeter = THING_TYPE_SMARTY_BRIDGE.equals(bridge.getThingTypeUID());
@ -129,7 +129,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* @param command the {@link Command} * @param command the {@link Command}
*/ */
@Override @Override
public void handleCommand(ChannelUID channelUID, Command command) { public void handleCommand(final ChannelUID channelUID, final Command command) {
// DSMRBridgeHandler does not support commands // DSMRBridgeHandler does not support commands
} }
@ -170,12 +170,13 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* @param deviceConfig device configuration * @param deviceConfig device configuration
* @return Specific {@link DSMRDevice} instance * @return Specific {@link DSMRDevice} instance
*/ */
private DSMRDevice createDevice(DSMRDeviceConfiguration deviceConfig) { private DSMRDevice createDevice(final DSMRDeviceConfiguration deviceConfig) {
final DSMRDevice dsmrDevice; final DSMRDevice dsmrDevice;
if (smartyMeter) { if (smartyMeter) {
dsmrDevice = new DSMRFixedConfigDevice(serialPortManager, deviceConfig.serialPort, dsmrDevice = new DSMRFixedConfigDevice(serialPortManager, deviceConfig.serialPort,
DSMRSerialSettings.HIGH_SPEED_SETTINGS, this, new DSMRTelegramListener(deviceConfig.decryptionKey)); DSMRSerialSettings.HIGH_SPEED_SETTINGS, this,
new DSMRTelegramListener(deviceConfig.decryptionKey, deviceConfig.additionalKey));
} else { } else {
final DSMRTelegramListener telegramListener = new DSMRTelegramListener(); final DSMRTelegramListener telegramListener = new DSMRTelegramListener();
@ -196,7 +197,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* @param meterListener the meter discovery listener to add * @param meterListener the meter discovery listener to add
* @return true if listener is added, false otherwise * @return true if listener is added, false otherwise
*/ */
public boolean registerDSMRMeterListener(P1TelegramListener meterListener) { public boolean registerDSMRMeterListener(final P1TelegramListener meterListener) {
logger.trace("Register DSMRMeterListener"); logger.trace("Register DSMRMeterListener");
return meterListeners.add(meterListener); return meterListeners.add(meterListener);
} }
@ -207,7 +208,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* @param meterListener the meter discovery listener to remove * @param meterListener the meter discovery listener to remove
* @return true is listener is removed, false otherwise * @return true is listener is removed, false otherwise
*/ */
public boolean unregisterDSMRMeterListener(P1TelegramListener meterListener) { public boolean unregisterDSMRMeterListener(final P1TelegramListener meterListener) {
logger.trace("Unregister DSMRMeterListener"); logger.trace("Unregister DSMRMeterListener");
return meterListeners.remove(meterListener); return meterListeners.remove(meterListener);
} }
@ -247,7 +248,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
} }
@Override @Override
public synchronized void handleTelegramReceived(P1Telegram telegram) { public synchronized void handleTelegramReceived(final P1Telegram telegram) {
if (telegram.getCosemObjects().isEmpty()) { if (telegram.getCosemObjects().isEmpty()) {
logger.debug("Parsing worked but something went wrong, so there were no CosemObjects:{}", logger.debug("Parsing worked but something went wrong, so there were no CosemObjects:{}",
telegram.getTelegramState().stateDetails); telegram.getTelegramState().stateDetails);
@ -259,7 +260,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
} }
@Override @Override
public void handleErrorEvent(DSMRConnectorErrorEvent portEvent) { public void handleErrorEvent(final DSMRConnectorErrorEvent portEvent) {
if (portEvent != DSMRConnectorErrorEvent.READ_ERROR) { if (portEvent != DSMRConnectorErrorEvent.READ_ERROR) {
deviceOffline(ThingStatusDetail.CONFIGURATION_ERROR, portEvent.getEventDetails()); deviceOffline(ThingStatusDetail.CONFIGURATION_ERROR, portEvent.getEventDetails());
} }
@ -270,7 +271,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* *
* @param telegram received meter values. * @param telegram received meter values.
*/ */
private void meterValueReceived(P1Telegram telegram) { private void meterValueReceived(final P1Telegram telegram) {
if (isInitialized() && getThing().getStatus() != ThingStatus.ONLINE) { if (isInitialized() && getThing().getStatus() != ThingStatus.ONLINE) {
updateStatus(ThingStatus.ONLINE); updateStatus(ThingStatus.ONLINE);
} }
@ -302,7 +303,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
/** /**
* @param lenientMode the lenientMode to set * @param lenientMode the lenientMode to set
*/ */
public void setLenientMode(boolean lenientMode) { public void setLenientMode(final boolean lenientMode) {
logger.trace("SetLenientMode: {}", lenientMode); logger.trace("SetLenientMode: {}", lenientMode);
if (dsmrDevice != null) { if (dsmrDevice != null) {
dsmrDevice.setLenientMode(lenientMode); dsmrDevice.setLenientMode(lenientMode);
@ -315,7 +316,7 @@ public class DSMRBridgeHandler extends BaseBridgeHandler implements DSMREventLis
* @param status off line status * @param status off line status
* @param details off line detailed message * @param details off line detailed message
*/ */
private void deviceOffline(ThingStatusDetail status, String details) { private void deviceOffline(final ThingStatusDetail status, final String details) {
updateStatus(ThingStatus.OFFLINE, status, details); updateStatus(ThingStatus.OFFLINE, status, details);
} }
} }

View File

@ -73,8 +73,12 @@
</parameter> </parameter>
<parameter name="decryptionKey" type="text" required="true"> <parameter name="decryptionKey" type="text" required="true">
<label>Decryption Key</label> <label>Decryption Key</label>
<description>The Luxembourgian Smart meter decryption key. Ask for your energy grid operator for your Smart meter P1 <description>Smart meter decryption key. Ask your energy grid operator for your smart meter P1 key.</description>
key.</description> </parameter>
<parameter name="additionalKey" type="text">
<label>Additional Decryption Key</label>
<description>Additional decryption key. Ask your energy grid operator for your smart meter P1 key.</description>
<default>3000112233445566778899AABBCCDDEEFF</default>
</parameter> </parameter>
<parameter name="receivedTimeout" type="integer" min="1" unit="s"> <parameter name="receivedTimeout" type="integer" min="1" unit="s">
<default>30</default> <default>30</default>

View File

@ -118,8 +118,10 @@ thing-type.config.dsmr.meterdescriptor.channel.label = Channel
thing-type.config.dsmr.meterdescriptor.channel.description = The DSMR-device channel for this meter (M-Bus channel). The binding will auto detect this value. In normal situations it is not necessary to adapt this value. If the auto detection failed or if physical changes are made to the meter setup (changed water, gas, heating) meters it can be necessary to update the M-Bus channel. thing-type.config.dsmr.meterdescriptor.channel.description = The DSMR-device channel for this meter (M-Bus channel). The binding will auto detect this value. In normal situations it is not necessary to adapt this value. If the auto detection failed or if physical changes are made to the meter setup (changed water, gas, heating) meters it can be necessary to update the M-Bus channel.
thing-type.config.dsmr.meterdescriptor.refresh.label = Refresh thing-type.config.dsmr.meterdescriptor.refresh.label = Refresh
thing-type.config.dsmr.meterdescriptor.refresh.description = The time interval the data is refreshed in seconds thing-type.config.dsmr.meterdescriptor.refresh.description = The time interval the data is refreshed in seconds
thing-type.config.dsmr.smartybridgesettings.additionalKey.label = Additional Decryption Key
thing-type.config.dsmr.smartybridgesettings.additionalKey.description = Additional decryption key. Ask your energy grid operator for your smart meter P1 key.
thing-type.config.dsmr.smartybridgesettings.decryptionKey.label = Decryption Key thing-type.config.dsmr.smartybridgesettings.decryptionKey.label = Decryption Key
thing-type.config.dsmr.smartybridgesettings.decryptionKey.description = The Luxembourgian Smart meter decryption key. Ask for your energy grid operator for your Smart meter P1 key. thing-type.config.dsmr.smartybridgesettings.decryptionKey.description = Smart meter decryption key. Ask your energy grid operator for your smart meter P1 key.
thing-type.config.dsmr.smartybridgesettings.receivedTimeout.label = Received Timeout thing-type.config.dsmr.smartybridgesettings.receivedTimeout.label = Received Timeout
thing-type.config.dsmr.smartybridgesettings.receivedTimeout.description = The time period within results are expected in seconds thing-type.config.dsmr.smartybridgesettings.receivedTimeout.description = The time period within results are expected in seconds
thing-type.config.dsmr.smartybridgesettings.serialPort.label = Serial Port thing-type.config.dsmr.smartybridgesettings.serialPort.label = Serial Port

View File

@ -99,7 +99,7 @@ public class SmartyDecrypterTest {
final AtomicReference<String> telegramResult = new AtomicReference<>(""); final AtomicReference<String> telegramResult = new AtomicReference<>("");
final P1TelegramListener telegramListener = telegram -> telegramResult.set(telegram.getRawTelegram()); final P1TelegramListener telegramListener = telegram -> telegramResult.set(telegram.getRawTelegram());
final SmartyDecrypter decoder = new SmartyDecrypter(new P1TelegramParser(telegramListener), final SmartyDecrypter decoder = new SmartyDecrypter(new P1TelegramParser(telegramListener),
new DSMRTelegramListener(KEY), KEY); new DSMRTelegramListener(KEY, ""), KEY, "");
decoder.setLenientMode(true); decoder.setLenientMode(true);
final byte[] data = new byte[TELEGRAM.length]; final byte[] data = new byte[TELEGRAM.length];