mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[knx] Add support for RGBW represented by HSBType (#16078)
Allow lossy conversion from RGBW to HSBType and back instead of using separate items for RGB and W. Select via DPT 251.60600. Signed-off-by: Holger Friedrich <mail@holger-friedrich.de> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
543721aa1b
commit
1e9d41442e
@ -6,7 +6,7 @@ Switching lights on and off, activating your roller shutters, or changing room t
|
||||
To access your KNX bus, you either need a gateway device which is connected to the KNX bus and allows computers to access the bus communication.
|
||||
This can be either an Ethernet (as a Router or a Tunnel type) or a serial gateway.
|
||||
The KNX binding then can communicate directly with this gateway.
|
||||
Alternatively, a PC running [KNXD](https://github.com/knxd/knxd) (free open source component software) can be put in between which then acts as a broker allowing multiple client to connect to the same gateway.
|
||||
Alternatively, a PC running [KNXD](https://github.com/knxd/knxd) (free open source component software) can be put in between which then acts as a broker allowing multiple clients to connect to the same gateway.
|
||||
Since the protocol is identical, the KNX binding can also communicate with it transparently.
|
||||
|
||||
***Attention:*** With the introduction of Unit of Measurement (UoM) support, some data types have changed (see `number` channel below):
|
||||
@ -121,11 +121,17 @@ When a `GroupValueRead` telegram is sent from the KNX bus to a *-control Channel
|
||||
| position | Group address brightness | 5.001 |
|
||||
| increaseDecrease | Group address for relative brightness | 3.007 |
|
||||
|
||||
The `hsb` address supports DPT 242.600 and 251.600.
|
||||
The `hsb` address supports DPT 232.600 (RGB), 242.600 (xyY), and 251.600 (RGBW).
|
||||
|
||||
Some RGB/RGBW products (e.g. MDT) support HSB values for DPT 232.600 instead of RGB.
|
||||
Some RGB/RGBW products (e.g. MDT) use HSB values for DPT 232.600 instead of RGB.
|
||||
This is supported as "vendor-specific DPT" with a value of 232.60000.
|
||||
|
||||
RGBW (DPT 251.600) can either be converted to HSBType, or be represented two items: a HSBType for RGB and an additional PercentType for W channel.
|
||||
Default handling for RGBW is to use separate items.
|
||||
Note that this also requires two frames being sent out separately when these elements are sent to the bus, as the binary representation uses a partially populated KNX frame.
|
||||
Alternatively, a single HSB item can be used. Conversion to a single HSBType will loose the exact setting for W, and will reconstruct it when a conversion to RGBW is required.
|
||||
This option can be selected using the special DPT 251.60600.
|
||||
|
||||
##### Channel Type `contact`, `contact-control`
|
||||
|
||||
| Parameter | Description | Default DPT |
|
||||
|
@ -55,7 +55,7 @@ public class DPTUtil {
|
||||
|
||||
// used to map vendor-specific data to standard DPT
|
||||
public static final Map<String, String> NORMALIZED_DPT = Map.of(//
|
||||
"232.60000", "232.600");
|
||||
"232.60000", "232.600", "251.60600", "251.600");
|
||||
|
||||
// fall back if no specific type is defined in DPT_TYPE_MAP
|
||||
private static final Map<String, Set<Class<? extends Type>>> DPT_MAIN_TYPE_MAP = Map.ofEntries( //
|
||||
|
@ -208,7 +208,7 @@ public class ValueDecoder {
|
||||
case "242":
|
||||
return handleDpt242(value);
|
||||
case "251":
|
||||
return handleDpt251(value, preferredType);
|
||||
return handleDpt251(value, subType, preferredType);
|
||||
default:
|
||||
return handleNumericDpt(id, translator, preferredType);
|
||||
// TODO 6.001 is mapped to PercentType, which can only cover 0-100%, not -128..127%
|
||||
@ -418,7 +418,7 @@ public class ValueDecoder {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static @Nullable Type handleDpt251(String value, Class<? extends Type> preferredType) {
|
||||
private static @Nullable Type handleDpt251(String value, String subType, Class<? extends Type> preferredType) {
|
||||
Matcher rgbw = RGBW_PATTERN.matcher(value);
|
||||
if (rgbw.matches()) {
|
||||
String rString = rgbw.group("r");
|
||||
@ -426,19 +426,39 @@ public class ValueDecoder {
|
||||
String bString = rgbw.group("b");
|
||||
String wString = rgbw.group("w");
|
||||
|
||||
if (rString != null && gString != null && bString != null && HSBType.class.equals(preferredType)) {
|
||||
// does not support PercentType and r,g,b valid -> HSBType
|
||||
int r = coerceToRange((int) (Double.parseDouble(rString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int g = coerceToRange((int) (Double.parseDouble(gString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int b = coerceToRange((int) (Double.parseDouble(bString.replace(",", ".")) * 2.55), 0, 255);
|
||||
switch (subType) {
|
||||
case "600":
|
||||
if (rString != null && gString != null && bString != null && HSBType.class.equals(preferredType)) {
|
||||
// does not support PercentType and r,g,b valid -> HSBType
|
||||
int r = coerceToRange((int) (Double.parseDouble(rString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int g = coerceToRange((int) (Double.parseDouble(gString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int b = coerceToRange((int) (Double.parseDouble(bString.replace(",", ".")) * 2.55), 0, 255);
|
||||
|
||||
return HSBType.fromRGB(r, g, b);
|
||||
} else if (wString != null && PercentType.class.equals(preferredType)) {
|
||||
// does support PercentType and w valid -> PercentType
|
||||
BigDecimal w = new BigDecimal(wString.replace(",", "."));
|
||||
return HSBType.fromRGB(r, g, b);
|
||||
} else if (wString != null && PercentType.class.equals(preferredType)) {
|
||||
// does support PercentType and w valid -> PercentType
|
||||
BigDecimal w = new BigDecimal(wString.replace(",", "."));
|
||||
|
||||
return new PercentType(w);
|
||||
return new PercentType(w);
|
||||
}
|
||||
case "60600":
|
||||
// special type used by OH for .600 indicating that RGBW should be handled with a single HSBType,
|
||||
// typically we use HSBType for RGB and PercentType for W.
|
||||
if (rString != null && gString != null && bString != null && wString != null
|
||||
&& HSBType.class.equals(preferredType)) {
|
||||
// does support PercentType and w valid -> PercentType
|
||||
int r = coerceToRange((int) (Double.parseDouble(rString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int g = coerceToRange((int) (Double.parseDouble(gString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int b = coerceToRange((int) (Double.parseDouble(bString.replace(",", ".")) * 2.55), 0, 255);
|
||||
int w = coerceToRange((int) (Double.parseDouble(wString.replace(",", ".")) * 2.55), 0, 255);
|
||||
|
||||
return ColorUtil.rgbToHsb(new int[] { r, g, b, w });
|
||||
}
|
||||
default:
|
||||
LOGGER.warn("Unknown subtype '251.{}', no conversion possible.", subType);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
LOGGER.warn("Failed to convert '{}' (DPT 251): Pattern does not match or invalid content", value);
|
||||
return null;
|
||||
|
@ -171,6 +171,10 @@ public class ValueEncoder {
|
||||
PercentType[] rgbw = ColorUtil.hsbToRgbPercent(hsb);
|
||||
return String.format("%,.1f %,.1f %,.1f - %%", rgbw[0].doubleValue(), rgbw[1].doubleValue(),
|
||||
rgbw[2].doubleValue());
|
||||
case "251.60600":
|
||||
PercentType[] rgbw2 = ColorUtil.hsbToRgbwPercent(hsb);
|
||||
return String.format("%,.1f %,.1f %,.1f %,.1f %%", rgbw2[0].doubleValue(), rgbw2[1].doubleValue(),
|
||||
rgbw2[2].doubleValue(), rgbw2[3].doubleValue());
|
||||
case "5.003":
|
||||
return hsb.getHue().toString();
|
||||
default:
|
||||
|
@ -582,6 +582,16 @@ public class Back2BackTest {
|
||||
// RGBW, only RGB part
|
||||
helper("251.600", new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x0e },
|
||||
new HSBType("0, 0, 100"), new byte[] { 1, 1, 1, 0, 0, 0 }, new byte[0]);
|
||||
// RGBW, only W part
|
||||
helper("251.600", new byte[] { 0x0, 0x0, 0x0, 0x1A, 0x00, 0x01 }, new PercentType("10.2"));
|
||||
// RGBW, all
|
||||
helper("251.60600", new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0xff, 0x00, 0x0f },
|
||||
new HSBType("0, 0, 100"), new byte[] { 1, 1, 1, 2, 0, 0 }, new byte[0]);
|
||||
// RGBW, mixed
|
||||
int[] rgbw = new int[] { 240, 0x0, 0x0, 0x0f };
|
||||
HSBType hsb = ColorUtil.rgbToHsb(rgbw);
|
||||
helper("251.60600", new byte[] { (byte) rgbw[0], (byte) rgbw[1], (byte) rgbw[2], (byte) rgbw[3], 0x00, 0x0f },
|
||||
hsb, new byte[] { 2, 2, 2, 2, 0, 0 }, new byte[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user