From 992f65d8e2b04a470d6acfd2051d89adf7c9e133 Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Wed, 13 Dec 2023 09:17:00 +0100 Subject: [PATCH] [knx] New modifier to set mainGA write-only (#16042) * [knx] New modifier to set mainGA write-only Co-authored-by: Florian Hotze Signed-off-by: Holger Friedrich --- bundles/org.openhab.binding.knx/README.md | 15 +++++--- .../channel/GroupAddressConfiguration.java | 35 ++++++++++++++++--- .../internal/handler/DeviceThingHandler.java | 5 ++- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/bundles/org.openhab.binding.knx/README.md b/bundles/org.openhab.binding.knx/README.md index 87c23942b22..73b021e1527 100644 --- a/bundles/org.openhab.binding.knx/README.md +++ b/bundles/org.openhab.binding.knx/README.md @@ -235,18 +235,23 @@ For UoM support see the explanations of the `number` channel. #### Group Address Notation ```text -="[:][<][[+[<]][+[<]..]]" +="[:][<>][[+[<]][+[<]..]]" ``` where parts in brackets `[]` denote optional information. +**Each configuration parameter has a `mainGA` where commands are written to and optionally several `listeningGA`s.** + +`mainGA` also listens to incoming packets, unless prefixed with a `>` character. +This is recommended if you have a dedicated status group address which is added as `listeningGA`. + The optional `<` sign tells whether the group address of the datapoint accepts read requests on the KNX bus (it does, if the sign is there). -All group addresses marked with `<` are read by openHAB during startup. +The group addresses marked with `<` are read by openHAB during startup. +Future versions might support reading from one GA only. With `*-control` channels, the state is not owned by any device on the KNX bus, therefore no read requests will be sent by the binding, i.e. `<` signs will be ignored for them. -Each configuration parameter has a `mainGA` where commands are written to and optionally several `listeningGA`s. - -The `dpt` element is optional. If omitted, the corresponding default value will be used (see the channel descriptions above). +The element `dpt` is highly recommended and may change to a mandatory element in future versions. +If omitted, the corresponding default value will be used (see the channel descriptions above). ## KNX Secure diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/GroupAddressConfiguration.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/GroupAddressConfiguration.java index a24ff68c540..b8fa9b47603 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/GroupAddressConfiguration.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/GroupAddressConfiguration.java @@ -28,7 +28,7 @@ import tuwien.auto.calimero.KNXFormatException; /** * Data structure representing the content of a channel's group address configuration. * - * @author Simon Kaufmann - initial contribution and API. + * @author Simon Kaufmann - Initial contribution and API * */ @NonNullByDefault @@ -36,7 +36,7 @@ public class GroupAddressConfiguration { public static final Logger LOGGER = LoggerFactory.getLogger(GroupAddressConfiguration.class); private static final Pattern PATTERN_GA_CONFIGURATION = Pattern.compile( - "^((?[1-9][0-9]{0,2}\\.[0-9]{3,5}):)?(?<)?(?[0-9]{1,5}(/[0-9]{1,4}){0,2})(?(\\+([1-9][0-9]{0,2}\\.[0-9]{3,5}):)?(?[<>])?(?[0-9]{1,5}(/[0-9]{1,4}){0,2})(?(\\+(<)?(?[0-9]{1,5}(/[0-9]{1,4}){0,2}))"); @@ -57,14 +57,28 @@ public class GroupAddressConfiguration { return dpt; } + /** + * Returns the main GA, which is the GA to send commands to. + */ public GroupAddress getMainGA() { return mainGA; } + /** + * Returns all GAs to listen to. + * This includes the main GA (unless disabled by '>'), and additional listening GAs + * (those after the "+" symbol). + */ public Set getListenGAs() { return listenGAs; } + /** + * Returns all GAs to read from. + * Those GAs accept read requests to the KNX bus, i.e. they respond to a "GroupValueRead" with a + * "GroupValueResponse". + * The '<' sign sets a GA as read GA. + */ public Set getReadGAs() { return readGAs; } @@ -99,9 +113,20 @@ public class GroupAddressConfiguration { String mainGA = matcher.group("mainGA"); try { GroupAddress groupAddress = new GroupAddress(mainGA); - listenGAs.add(groupAddress); // also listening to main GA - if (matcher.group("read") != null) { - readGAs.add(groupAddress); // also reading main GA + @Nullable + String modifier = matcher.group("modifier"); + if (modifier == null) { + // default: main GA address writes and listens + listenGAs.add(groupAddress); + } else if ("<".equals(modifier)) { + // configured for read at startup + listenGAs.add(groupAddress); + readGAs.add(groupAddress); + } // else (">").equals(modifier) -> write only, no action + if (readGAs.size() > 1) { + LOGGER.info( + "Item with mainGA {} has more than one GA configured for read at startup, check configuration", + groupAddress); } return new GroupAddressConfiguration(matcher.group("dpt"), groupAddress, listenGAs, readGAs); } catch (KNXFormatException e) { diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java index 5c29712c8f1..201b074d6cf 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java @@ -428,12 +428,15 @@ public class DeviceThingHandler extends BaseThingHandler implements GroupAddress } } else { if (value instanceof Command command) { - logger.trace("processDataReceived postCommand new value '{}' for GA '{}'", asdu, address); + logger.trace("processDataReceived postCommand to channel '{}' new value '{}' for GA '{}'", + channelUID, asdu, destination); postCommand(channelUID, command); } } } else { if (value instanceof State state && !(value instanceof UnDefType)) { + logger.trace("processDataReceived updateState to channel '{}' new value '{}' for GA '{}'", + knxChannel.getChannelUID(), value, destination); updateState(knxChannel.getChannelUID(), state); } }