[serial] Support chaining transformations without an intersection symbol (#17313)

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
jimtng 2024-09-01 20:43:19 +10:00 committed by GitHub
parent 6f55f3d2ad
commit 09012cee8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 104 additions and 348 deletions

View File

@ -83,8 +83,8 @@ The configuration for the `serialBridge` channels consists of the following para
| Parameter | Description | Supported Channels |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| `stateTransformation` | One or more transformation (concatenated with `∩`) used to convert device data to channel state, e.g. `REGEX:.*?STATE=(.*?);.*` | string, number, dimmer, switch, rollershutter |
| `commandTransformation` | One or more transformation (concatenated with `∩`) used to convert command to device data, e.g. `JS:device.js` | string, number, dimmer, switch, rollershutter |
| `stateTransformation` | One or more transformation (concatenated with `∩`) used to convert device data to channel state, e.g. `REGEX(.*?STATE=(.*?);.*)` | string, number, dimmer, switch, rollershutter |
| `commandTransformation` | One or more transformation (concatenated with `∩`) used to convert command to device data, e.g. `JS(device.js)` | string, number, dimmer, switch, rollershutter |
| `commandFormat` | Format string applied to the command before transform, e.g. `ID=671;COMMAND=%s` | string, number, dimmer, rollershutter |
| `onValue` | Send this value when receiving an ON command | switch, dimmer |
| `offValue` | Send this value when receiving an OFF command | switch, dimmer |
@ -94,6 +94,11 @@ The configuration for the `serialBridge` channels consists of the following para
| `downValue` | Send this value when receiving a DOWN command | rollershutter |
| `stopValue` | Send this value when receiving a STOP command | rollershutter |
Transformations can be chained in the UI by listing each transformation on a separate line, or by separating them with the mathematical intersection character "∩".
Transformations are defined using this syntax: `TYPE(FUNCTION)`, e.g.: `JSONPATH($.path)`.
The syntax: `TYPE:FUNCTION` is still supported, e.g.: `JSONPATH:$.path`.
Please note that the values will be discarded if one transformation fails (e.g. REGEX did not match).
## Full Example
The following example is for a device connected to a serial port which provides data for many different sensors and we are interested in the temperature from a particular sensor.
@ -106,13 +111,13 @@ demo.things:
Bridge serial:serialBridge:sensors [serialPort="/dev/ttyUSB01", baudRate=57600] {
Thing serialDevice temperatureSensor [patternMatch="20;05;Cresta;ID=2801;.*"] {
Channels:
Type number : temperature [stateTransformation="REGEX:.*?TEMP=(.*?);.*"]
Type number : humidity [stateTransformation="REGEX:.*?HUM=(.*?);.*"]
Type number : temperature [stateTransformation="REGEX(.*?TEMP=(.*?);.*)"]
Type number : humidity [stateTransformation="REGEX(.*?HUM=(.*?);.*)"]
}
Thing serialDevice rollershutter [patternMatch=".*"] {
Channels:
Type rollershutter : serialRollo [stateTransformation="REGEX:Position:([0-9.]*)", upValue="Rollo_UP\n", downValue="Rollo_DOWN\n", stopValue="Rollo_STOP\n"]
Type switch : roloAt100 [stateTransformation="REGEX:s/Position:100/ON/"]
Type rollershutter : serialRollo [stateTransformation="REGEX(Position:([0-9.]*))", upValue="Rollo_UP\n", downValue="Rollo_DOWN\n", stopValue="Rollo_STOP\n"]
Type switch : roloAt100 [stateTransformation="REGEX(s/Position:100/ON/)"]
}
Thing serialDevice relay [patternMatch=".*"] {
Channels:
@ -120,7 +125,7 @@ Bridge serial:serialBridge:sensors [serialPort="/dev/ttyUSB01", baudRate=57600]
}
Thing serialDevice myDevice [patternMatch="ID=2341;.*"] {
Channels:
Type string : control [commandTransformation="JS:addCheckSum.js", commandFormat="ID=2341;COMMAND=%s;"]
Type string : control [commandTransformation="JS(addCheckSum.js)", commandFormat="ID=2341;COMMAND=%s;"]
}
}

View File

@ -21,10 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.serial.internal.handler.SerialBridgeHandler;
import org.openhab.binding.serial.internal.handler.SerialDeviceHandler;
import org.openhab.binding.serial.internal.transform.CascadedValueTransformationImpl;
import org.openhab.binding.serial.internal.transform.NoOpValueTransformation;
import org.openhab.binding.serial.internal.transform.ValueTransformation;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
@ -32,7 +28,6 @@ import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.openhab.core.transform.TransformationHelper;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@ -45,7 +40,7 @@ import org.osgi.service.component.annotations.Reference;
*/
@NonNullByDefault
@Component(configurationPid = "binding.serial", service = ThingHandlerFactory.class)
public class SerialHandlerFactory extends BaseThingHandlerFactory implements ValueTransformationProvider {
public class SerialHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_BRIDGE, THING_TYPE_DEVICE);
@ -68,18 +63,9 @@ public class SerialHandlerFactory extends BaseThingHandlerFactory implements Val
if (THING_TYPE_BRIDGE.equals(thingTypeUID)) {
return new SerialBridgeHandler((Bridge) thing, serialPortManager);
} else if (THING_TYPE_DEVICE.equals(thingTypeUID)) {
return new SerialDeviceHandler(thing, this);
return new SerialDeviceHandler(thing);
}
return null;
}
@Override
public ValueTransformation getValueTransformation(@Nullable final String pattern) {
if (pattern == null) {
return NoOpValueTransformation.getInstance();
}
return new CascadedValueTransformationImpl(pattern,
name -> TransformationHelper.getTransformationService(bundleContext, name));
}
}

View File

@ -12,6 +12,8 @@
*/
package org.openhab.binding.serial.internal.channel;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@ -25,12 +27,12 @@ public class ChannelConfig {
/**
* Transform for received data
*/
public @Nullable String stateTransformation;
public @Nullable List<String> stateTransformation;
/**
* Transform for command
*/
public @Nullable String commandTransformation;
public @Nullable List<String> commandTransformation;
/**
* Format string for command

View File

@ -16,8 +16,7 @@ import java.util.IllegalFormatException;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.serial.internal.transform.ValueTransformation;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
import org.openhab.core.thing.binding.generic.ChannelTransformation;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,13 +33,14 @@ public abstract class DeviceChannel {
protected final ChannelConfig config;
private final ValueTransformation stateTransform;
private final ValueTransformation commandTransform;
private final ChannelTransformation stateTransform;
private final ChannelTransformation commandTransform;
protected DeviceChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
protected DeviceChannel(final ChannelConfig config) {
this.config = config;
stateTransform = valueTransformationProvider.getValueTransformation(config.stateTransformation);
commandTransform = valueTransformationProvider.getValueTransformation(config.commandTransformation);
stateTransform = new ChannelTransformation(config.stateTransformation);
commandTransform = new ChannelTransformation(config.commandTransformation);
}
/**

View File

@ -20,7 +20,6 @@ import static org.openhab.binding.serial.internal.SerialBindingConstants.DEVICE_
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
/**
* A factory to create {@link DeviceChannel} objects
@ -38,26 +37,25 @@ public class DeviceChannelFactory {
* @param channelTypeID the channel type id
* @return the DeviceChannel or null if the channel type is not supported.
*/
public static @Nullable DeviceChannel createDeviceChannel(
final ValueTransformationProvider valueTransformationProvider, final ChannelConfig channelConfig,
public static @Nullable DeviceChannel createDeviceChannel(final ChannelConfig channelConfig,
final String channelTypeID) {
DeviceChannel deviceChannel;
switch (channelTypeID) {
case DEVICE_STRING_CHANNEL:
deviceChannel = new StringChannel(valueTransformationProvider, channelConfig);
deviceChannel = new StringChannel(channelConfig);
break;
case DEVICE_NUMBER_CHANNEL:
deviceChannel = new NumberChannel(valueTransformationProvider, channelConfig);
deviceChannel = new NumberChannel(channelConfig);
break;
case DEVICE_DIMMER_CHANNEL:
deviceChannel = new DimmerChannel(valueTransformationProvider, channelConfig);
deviceChannel = new DimmerChannel(channelConfig);
break;
case DEVICE_SWITCH_CHANNEL:
deviceChannel = new SwitchChannel(valueTransformationProvider, channelConfig);
deviceChannel = new SwitchChannel(channelConfig);
break;
case DEVICE_ROLLERSHUTTER_CHANNEL:
deviceChannel = new RollershutterChannel(valueTransformationProvider, channelConfig);
deviceChannel = new RollershutterChannel(channelConfig);
break;
default:
deviceChannel = null;

View File

@ -15,7 +15,6 @@ package org.openhab.binding.serial.internal.channel;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
import org.openhab.core.library.types.IncreaseDecreaseType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.types.Command;
@ -28,8 +27,8 @@ import org.openhab.core.types.Command;
@NonNullByDefault
public class DimmerChannel extends SwitchChannel {
public DimmerChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
super(valueTransformationProvider, config);
public DimmerChannel(final ChannelConfig config) {
super(config);
}
@Override

View File

@ -13,7 +13,6 @@
package org.openhab.binding.serial.internal.channel;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
/**
* The {@link NumberChannel} channel applies a format followed by a transform.
@ -23,7 +22,7 @@ import org.openhab.binding.serial.internal.transform.ValueTransformationProvider
@NonNullByDefault
public class NumberChannel extends DeviceChannel {
public NumberChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
super(valueTransformationProvider, config);
public NumberChannel(final ChannelConfig config) {
super(config);
}
}

View File

@ -15,7 +15,6 @@ package org.openhab.binding.serial.internal.channel;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
import org.openhab.core.library.types.StopMoveType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.types.Command;
@ -28,9 +27,8 @@ import org.openhab.core.types.Command;
@NonNullByDefault
public class RollershutterChannel extends DeviceChannel {
public RollershutterChannel(final ValueTransformationProvider valueTransformationProvider,
final ChannelConfig config) {
super(valueTransformationProvider, config);
public RollershutterChannel(final ChannelConfig config) {
super(config);
}
@Override

View File

@ -13,7 +13,6 @@
package org.openhab.binding.serial.internal.channel;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
/**
* The {@link StringChannel} channel applies a format followed by a transform.
@ -23,7 +22,7 @@ import org.openhab.binding.serial.internal.transform.ValueTransformationProvider
@NonNullByDefault
public class StringChannel extends DeviceChannel {
public StringChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
super(valueTransformationProvider, config);
public StringChannel(final ChannelConfig config) {
super(config);
}
}

View File

@ -15,7 +15,6 @@ package org.openhab.binding.serial.internal.channel;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.types.Command;
@ -27,8 +26,8 @@ import org.openhab.core.types.Command;
@NonNullByDefault
public class SwitchChannel extends DeviceChannel {
public SwitchChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
super(valueTransformationProvider, config);
public SwitchChannel(final ChannelConfig config) {
super(config);
}
@Override

View File

@ -22,7 +22,6 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.serial.internal.channel.ChannelConfig;
import org.openhab.binding.serial.internal.channel.DeviceChannel;
import org.openhab.binding.serial.internal.channel.DeviceChannelFactory;
import org.openhab.binding.serial.internal.transform.ValueTransformationProvider;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
@ -45,17 +44,14 @@ import org.openhab.core.types.RefreshType;
@NonNullByDefault
public class SerialDeviceHandler extends BaseThingHandler {
private final ValueTransformationProvider valueTransformationProvider;
private @Nullable Pattern devicePattern;
private @Nullable String lastValue;
private final Map<ChannelUID, DeviceChannel> channels = new HashMap<>();
public SerialDeviceHandler(final Thing thing, final ValueTransformationProvider valueTransformationProvider) {
public SerialDeviceHandler(final Thing thing) {
super(thing);
this.valueTransformationProvider = valueTransformationProvider;
}
@Override
@ -100,8 +96,8 @@ public class SerialDeviceHandler extends BaseThingHandler {
if (type != null) {
final ChannelConfig channelConfig = c.getConfiguration().as(ChannelConfig.class);
try {
final DeviceChannel deviceChannel = DeviceChannelFactory
.createDeviceChannel(valueTransformationProvider, channelConfig, type.getId());
final DeviceChannel deviceChannel = DeviceChannelFactory.createDeviceChannel(channelConfig,
type.getId());
if (deviceChannel != null) {
channels.put(c.getUID(), deviceChannel);
}

View File

@ -1,54 +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.serial.internal.transform;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.transform.TransformationService;
/**
* The {@link CascadedValueTransformationImpl} implements {@link ValueTransformation for a cascaded set of
* transformations}
*
* @author Jan N. Klug - Initial contribution
* @author Mike Major - Copied from HTTP binding to provide consistent user experience
*/
@NonNullByDefault
public class CascadedValueTransformationImpl implements ValueTransformation {
private final List<ValueTransformation> transformations;
public CascadedValueTransformationImpl(final String transformationString,
final Function<String, @Nullable TransformationService> transformationServiceSupplier) {
transformations = Arrays.stream(transformationString.split("")).filter(s -> !s.isEmpty())
.map(transformation -> new SingleValueTransformation(transformation, transformationServiceSupplier))
.collect(Collectors.toList());
}
@Override
public Optional<String> apply(final String value) {
Optional<String> valueOptional = Optional.of(value);
// process all transformations
for (final ValueTransformation transformation : transformations) {
valueOptional = valueOptional.flatMap(transformation::apply);
}
return valueOptional;
}
}

View File

@ -1,42 +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.serial.internal.transform;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link NoOpValueTransformation} implements a no-op (identity) transformation
*
* @author Jan N. Klug - Initial contribution
* @author Mike Major - Copied from HTTP binding to provide consistent user experience
*/
@NonNullByDefault
public class NoOpValueTransformation implements ValueTransformation {
private static final NoOpValueTransformation NO_OP_VALUE_TRANSFORMATION = new NoOpValueTransformation();
@Override
public Optional<String> apply(final String value) {
return Optional.of(value);
}
/**
* get the static value transformation for identity
*
* @return
*/
public static ValueTransformation getInstance() {
return NO_OP_VALUE_TRANSFORMATION;
}
}

View File

@ -1,90 +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.serial.internal.transform;
import java.lang.ref.WeakReference;
import java.util.Optional;
import java.util.function.Function;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.transform.TransformationException;
import org.openhab.core.transform.TransformationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A transformation for a value used in {@link org.openhab.binding.serial.internal.channel.DeviceChannel}.
*
* @author David Graeff - Initial contribution
* @author Jan N. Klug - adapted from MQTT binding to HTTP binding
* @author Mike Major - Copied from HTTP binding to provide consistent user experience
*/
@NonNullByDefault
public class SingleValueTransformation implements ValueTransformation {
private final Logger logger = LoggerFactory.getLogger(SingleValueTransformation.class);
private final Function<String, @Nullable TransformationService> transformationServiceSupplier;
private WeakReference<@Nullable TransformationService> transformationService = new WeakReference<>(null);
private final String pattern;
private final String serviceName;
/**
* Creates a new channel state transformer.
*
* @param pattern A transformation pattern, starting with the transformation service
* name, followed by a colon and the transformation itself.
* @param transformationServiceSupplier
*/
public SingleValueTransformation(final String pattern,
final Function<String, @Nullable TransformationService> transformationServiceSupplier) {
this.transformationServiceSupplier = transformationServiceSupplier;
final int index = pattern.indexOf(':');
if (index == -1) {
throw new IllegalArgumentException(
"The transformation pattern must consist of the type and the pattern separated by a colon");
}
this.serviceName = pattern.substring(0, index).toUpperCase();
this.pattern = pattern.substring(index + 1);
}
@Override
public Optional<String> apply(final String value) {
TransformationService transformationService = this.transformationService.get();
if (transformationService == null) {
transformationService = transformationServiceSupplier.apply(serviceName);
if (transformationService == null) {
logger.warn("Transformation service {} for pattern {} not found!", serviceName, pattern);
return Optional.empty();
}
this.transformationService = new WeakReference<>(transformationService);
}
try {
final String result = transformationService.transform(pattern, value);
if (result == null) {
logger.debug("Transformation {} returned empty result when applied to {}.", this, value);
return Optional.empty();
}
return Optional.of(result);
} catch (final TransformationException e) {
logger.warn("Executing transformation {} failed: {}", this, e.getMessage());
}
return Optional.empty();
}
@Override
public String toString() {
return "ChannelStateTransformation{pattern='" + pattern + "', serviceName='" + serviceName + "'}";
}
}

View File

@ -1,35 +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.serial.internal.transform;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link ValueTransformation} applies a set of transformations to a value
*
* @author Jan N. Klug - Initial contribution
* @author Mike Major - Copied from HTTP binding to provide consistent user experience
*/
@NonNullByDefault
public interface ValueTransformation {
/**
* applies the value transformation to a value
*
* @param value The value
* @return Optional of string representing the transformed value (empty if transformation not present or failed)
*/
Optional<String> apply(String value);
}

View File

@ -1,34 +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.serial.internal.transform;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* The {@link ValueTransformationProvider} allows to retrieve a transformation service by name
*
* @author Jan N. Klug - Initial contribution
* @author Mike Major - Copied from HTTP binding to provide consistent user experience
*/
@NonNullByDefault
public interface ValueTransformationProvider {
/**
*
* @param pattern A transformation pattern, starting with the transformation service
* * name, followed by a colon and the transformation itself.
* @return
*/
ValueTransformation getValueTransformation(@Nullable String pattern);
}

View File

@ -68,7 +68,7 @@ channel-type.serial.switch.description = Channel to receive commands from a Swit
channel-type.config.serial.dimmer.commandFormat.label = Percent Format
channel-type.config.serial.dimmer.commandFormat.description = Format string applied to the percent command, e.g. ID=671;VAL=%d
channel-type.config.serial.dimmer.commandTransformation.label = Command Transformation
channel-type.config.serial.dimmer.commandTransformation.description = Transform used to convert command to device data, e.g. JS:device.js
channel-type.config.serial.dimmer.commandTransformation.description = Transformation used to convert command to device data, e.g. <code>JS(device.js)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.dimmer.decreaseValue.label = Decrease Value
channel-type.config.serial.dimmer.decreaseValue.description = Send this value when receiving a DECREASE command
channel-type.config.serial.dimmer.increaseValue.label = Increase Value
@ -78,21 +78,21 @@ channel-type.config.serial.dimmer.offValue.description = Send this value when re
channel-type.config.serial.dimmer.onValue.label = On Value
channel-type.config.serial.dimmer.onValue.description = Send this value when receiving an ON command
channel-type.config.serial.dimmer.stateTransformation.label = State Transformation
channel-type.config.serial.dimmer.stateTransformation.description = Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*
channel-type.config.serial.dimmer.stateTransformation.description = Transformation used to convert device data to channel state, e.g. <code>REGEX(.*?STATE=(.*?);.*)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.number.commandFormat.label = Number Format
channel-type.config.serial.number.commandFormat.description = Format string applied to the command, e.g. ID=671;VAL=%f
channel-type.config.serial.number.commandTransformation.label = Command Transformation
channel-type.config.serial.number.commandTransformation.description = Transform used to convert command to device data, e.g. JS:device.js
channel-type.config.serial.number.commandTransformation.description = Transformation used to convert command to device data, e.g. <code>JS(device.js)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.number.stateTransformation.label = State Transformation
channel-type.config.serial.number.stateTransformation.description = Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*
channel-type.config.serial.number.stateTransformation.description = Transformation used to convert device data to channel state, e.g. <code>REGEX(.*?STATE=(.*?);.*)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.rollershutter.commandFormat.label = Percent Format
channel-type.config.serial.rollershutter.commandFormat.description = Format string applied to the percent command, e.g. ID=671;VAL=%d
channel-type.config.serial.rollershutter.commandTransformation.label = Command Transformation
channel-type.config.serial.rollershutter.commandTransformation.description = Transform used to convert command to device data, e.g. JS:device.js
channel-type.config.serial.rollershutter.commandTransformation.description = Transformation used to convert command to device data, e.g. <code>JS(device.js)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.rollershutter.downValue.label = Down Value
channel-type.config.serial.rollershutter.downValue.description = Send this value when receiving a DOWN command
channel-type.config.serial.rollershutter.stateTransformation.label = State Transformation
channel-type.config.serial.rollershutter.stateTransformation.description = Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*
channel-type.config.serial.rollershutter.stateTransformation.description = Transformation used to convert device data to channel state, e.g. <code>REGEX(.*?STATE=(.*?);.*)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.rollershutter.stopValue.label = Stop Value
channel-type.config.serial.rollershutter.stopValue.description = Send this value when receiving a STOP command
channel-type.config.serial.rollershutter.upValue.label = Up Value
@ -100,14 +100,14 @@ channel-type.config.serial.rollershutter.upValue.description = Send this value w
channel-type.config.serial.string.commandFormat.label = String Format
channel-type.config.serial.string.commandFormat.description = Format string applied to the command, e.g. ID=671;COMMAND=%s
channel-type.config.serial.string.commandTransformation.label = Command Transformation
channel-type.config.serial.string.commandTransformation.description = Transform used to convert command to device data, e.g. JS:device.js
channel-type.config.serial.string.commandTransformation.description = Transformation used to convert command to device data, e.g. <code>JS(device.js)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.string.stateTransformation.label = State Transformation
channel-type.config.serial.string.stateTransformation.description = Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*
channel-type.config.serial.string.stateTransformation.description = Transformation used to convert device data to channel state, e.g. <code>REGEX(.*?STATE=(.*?);.*)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.switch.commandTransformation.label = Command Transformation
channel-type.config.serial.switch.commandTransformation.description = Transform used to convert command to device data, e.g. JS:device.js
channel-type.config.serial.switch.commandTransformation.description = Transformation used to convert command to device data, e.g. <code>JS(device.js)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".
channel-type.config.serial.switch.offValue.label = Off Value
channel-type.config.serial.switch.offValue.description = Send this value when receiving an OFF command
channel-type.config.serial.switch.onValue.label = On Value
channel-type.config.serial.switch.onValue.description = Send this value when receiving an ON command
channel-type.config.serial.switch.stateTransformation.label = State Transformation
channel-type.config.serial.switch.stateTransformation.description = Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*
channel-type.config.serial.switch.stateTransformation.description = Transformation used to convert device data to channel state, e.g. <code>REGEX(.*?STATE=(.*?);.*)</code>. Multiple transformations can be chained by listing each transformation on a separate line, or by concatenating them with "∩".

View File

@ -117,17 +117,23 @@
<label>String</label>
<description>Channel to receive commands as a string</description>
<config-description>
<parameter name="stateTransformation" type="text">
<parameter name="stateTransformation" type="text" multiple="true">
<label>State Transformation</label>
<description>Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*</description>
<description><![CDATA[Transformation used to convert device data to channel state, e.g.
<code>REGEX(.*?STATE=(.*?);.*)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
<parameter name="commandFormat" type="text">
<label>String Format</label>
<description>Format string applied to the command, e.g. ID=671;COMMAND=%s</description>
</parameter>
<parameter name="commandTransformation" type="text">
<parameter name="commandTransformation" type="text" multiple="true">
<label>Command Transformation</label>
<description>Transform used to convert command to device data, e.g. JS:device.js</description>
<description><![CDATA[Transformation used to convert command to device data, e.g.
<code>JS(device.js)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
</config-description>
</channel-type>
@ -137,17 +143,23 @@
<label>Number</label>
<description>Channel to receive commands as a number</description>
<config-description>
<parameter name="stateTransformation" type="text">
<parameter name="stateTransformation" type="text" multiple="true">
<label>State Transformation</label>
<description>Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*</description>
<description><![CDATA[Transformation used to convert device data to channel state, e.g.
<code>REGEX(.*?STATE=(.*?);.*)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
<parameter name="commandFormat" type="text">
<label>Number Format</label>
<description>Format string applied to the command, e.g. ID=671;VAL=%f</description>
</parameter>
<parameter name="commandTransformation" type="text">
<parameter name="commandTransformation" type="text" multiple="true">
<label>Command Transformation</label>
<description>Transform used to convert command to device data, e.g. JS:device.js</description>
<description><![CDATA[Transformation used to convert command to device data, e.g.
<code>JS(device.js)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
</config-description>
</channel-type>
@ -157,9 +169,12 @@
<label>Dimmer</label>
<description>Channel to receive commands from a Dimmer</description>
<config-description>
<parameter name="stateTransformation" type="text">
<parameter name="stateTransformation" type="text" multiple="true">
<label>State Transformation</label>
<description>Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*</description>
<description><![CDATA[Transformation used to convert device data to channel state, e.g.
<code>REGEX(.*?STATE=(.*?);.*)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
<parameter name="onValue" type="text">
<label>On Value</label>
@ -181,9 +196,12 @@
<label>Percent Format</label>
<description>Format string applied to the percent command, e.g. ID=671;VAL=%d</description>
</parameter>
<parameter name="commandTransformation" type="text">
<parameter name="commandTransformation" type="text" multiple="true">
<label>Command Transformation</label>
<description>Transform used to convert command to device data, e.g. JS:device.js</description>
<description><![CDATA[Transformation used to convert command to device data, e.g.
<code>JS(device.js)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
</config-description>
</channel-type>
@ -193,9 +211,12 @@
<label>Switch</label>
<description>Channel to receive commands from a Switch</description>
<config-description>
<parameter name="stateTransformation" type="text">
<parameter name="stateTransformation" type="text" multiple="true">
<label>State Transformation</label>
<description>Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*</description>
<description><![CDATA[Transformation used to convert device data to channel state, e.g.
<code>REGEX(.*?STATE=(.*?);.*)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
<parameter name="onValue" type="text">
<label>On Value</label>
@ -205,9 +226,12 @@
<label>Off Value</label>
<description>Send this value when receiving an OFF command</description>
</parameter>
<parameter name="commandTransformation" type="text">
<parameter name="commandTransformation" type="text" multiple="true">
<label>Command Transformation</label>
<description>Transform used to convert command to device data, e.g. JS:device.js</description>
<description><![CDATA[Transformation used to convert command to device data, e.g.
<code>JS(device.js)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
</config-description>
</channel-type>
@ -217,9 +241,12 @@
<label>Rollershutter</label>
<description>Channel to receive commands from a Rollershutter</description>
<config-description>
<parameter name="stateTransformation" type="text">
<parameter name="stateTransformation" type="text" multiple="true">
<label>State Transformation</label>
<description>Transform used to convert device data to channel state, e.g. REGEX:.*?STATE=(.*?);.*</description>
<description><![CDATA[Transformation used to convert device data to channel state, e.g.
<code>REGEX(.*?STATE=(.*?);.*)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
<parameter name="upValue" type="text">
<label>Up Value</label>
@ -237,9 +264,12 @@
<label>Percent Format</label>
<description>Format string applied to the percent command, e.g. ID=671;VAL=%d</description>
</parameter>
<parameter name="commandTransformation" type="text">
<parameter name="commandTransformation" type="text" multiple="true">
<label>Command Transformation</label>
<description>Transform used to convert command to device data, e.g. JS:device.js</description>
<description><![CDATA[Transformation used to convert command to device data, e.g.
<code>JS(device.js)</code>.
Multiple transformations can be chained by listing each transformation on a separate line,
or by concatenating them with "∩".]]></description>
</parameter>
</config-description>
</channel-type>