| 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 |
| `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.
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:
}
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;"]
}
}
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;
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;
*/
@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);
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));
- }
}
*/
package org.openhab.binding.serial.internal.channel;
+import java.util.List;
+
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* 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
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;
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);
}
/**
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
* @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;
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;
@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
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.
@NonNullByDefault
public class NumberChannel extends DeviceChannel {
- public NumberChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
- super(valueTransformationProvider, config);
+ public NumberChannel(final ChannelConfig config) {
+ super(config);
}
}
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;
@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
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.
@NonNullByDefault
public class StringChannel extends DeviceChannel {
- public StringChannel(final ValueTransformationProvider valueTransformationProvider, final ChannelConfig config) {
- super(valueTransformationProvider, config);
+ public StringChannel(final ChannelConfig config) {
+ super(config);
}
}
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;
@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
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;
@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
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);
}
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.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;
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.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;
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.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 + "'}";
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.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);
-}
+++ /dev/null
-/**
- * Copyright (c) 2010-2024 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.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);
-}
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
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
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 "∩".
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>