From 2b353efdc29cca10bf7054f4c897c7f9848fc875 Mon Sep 17 00:00:00 2001 From: Ciprian Pascu Date: Thu, 2 Jan 2025 09:45:46 +0200 Subject: [PATCH] final implementation for switch, temperature & rgbw things Signed-off-by: Ciprian Pascu --- bundles/org.openhab.binding.sbus/README.md | 57 ++++++------ bundles/org.openhab.binding.sbus/pom.xml | 2 +- .../binding/sbus/handler/SbusRgbwHandler.java | 87 ++++++++++++++----- .../resources/OH-INF/thing/thing-types.xml | 6 ++ 4 files changed, 97 insertions(+), 55 deletions(-) diff --git a/bundles/org.openhab.binding.sbus/README.md b/bundles/org.openhab.binding.sbus/README.md index ed5981f6f20..9fa222e6bcd 100644 --- a/bundles/org.openhab.binding.sbus/README.md +++ b/bundles/org.openhab.binding.sbus/README.md @@ -39,15 +39,21 @@ Please note the broadcast address. This is how Sbus devices communicate with eac #### RGBW Controller ``` -Thing sbus:rgbw:mybridge:light1 [ address=1 ] +Thing rgbw colorctrl [ id=72, refresh=30 ] { + Channels: + Type color-channel : color [ channelNumber=1 ] // HSB color picker, RGBW values stored at channel 1 + Type switch-channel : power [ channelNumber=1 ] // On/Off control for the RGBW output. +} ``` Supported channels: -* `red` - Red component (0-100%) -* `green` - Green component (0-100%) -* `blue` - Blue component (0-100%) -* `white` - White component (0-100%) +* `color` - HSB color picker that controls: + * Red component (0-100%) + * Green component (0-100%) + * Blue component (0-100%) + * White component (0-100%) +* `power` - On/Off control for the RGBW output with optional timer #### Temperature Sensor @@ -84,11 +90,24 @@ Supported channels: items/sbus.items: ``` -Color Light_RGB "RGB Light" { channel="sbus:rgbw:mybridge:light1:color" } Number:Temperature Temp_Sensor "Temperature [%.1f °C]" { channel="sbus:temperature:mybridge:temp1:temperature" } Switch Light_Switch "Switch" { channel="sbus:switch:mybridge:switch1:switch" } ``` +Example: RGBW Controller with Power Control + +``` +// Light Group +Group gLight "RGBW Light" ["Lighting"] + +// Color Control +Color rgbwColor "Color" (gLight) ["Control", "Light"] { channel="sbus:rgbw:mybridge:colorctrl:color" } + +// Power Control +Switch rgbwPower "Power" (gLight) ["Switch", "Light"] { channel="sbus:rgbw:mybridge:colorctrl:power" } +``` + + sitemap/sbus.sitemap: ``` @@ -101,29 +120,3 @@ sitemap sbus label="SBUS Demo" } } ``` - -## Special Case: RGBW Controller with Power Control - -Here's how to configure an RGBW controller with both color and power control: - -``` -// RGBW controller for color -Thing rgbw colorctrl [ id=72, refresh=30 ] { - Channels: - Type color-channel : color [ channelNumber=1 ] // HSB color picker, RGBW values stored at channel 1 -} - -// Switch for power control -Thing switch powerctrl [ id=72, refresh=30 ] { - Channels: - Type switch-channel : power [ channelNumber=5, timer=-1 ] // On/Off control for the RGBW output. Disable the timer functionality. The device doesn't support it. -} - -// Light Group -Group gLight "RGBW Light" ["Lighting"] - -// Color Control -Color rgbwColor "Color" (gLight) ["Control", "Light"] { channel="sbus:rgbw:mybridge:colorctrl:color" } - -// Power Control -Switch rgbwPower "Power" (gLight) ["Switch", "Light"] { channel="sbus:switch:mybridge:powerctrl:power" } diff --git a/bundles/org.openhab.binding.sbus/pom.xml b/bundles/org.openhab.binding.sbus/pom.xml index 924ba2249e9..f74ee881db7 100644 --- a/bundles/org.openhab.binding.sbus/pom.xml +++ b/bundles/org.openhab.binding.sbus/pom.xml @@ -18,7 +18,7 @@ ro.ciprianpascu j2sbus - 1.5.3-SNAPSHOT + 1.5.4 compile diff --git a/bundles/org.openhab.binding.sbus/src/main/java/org/openhab/binding/sbus/handler/SbusRgbwHandler.java b/bundles/org.openhab.binding.sbus/src/main/java/org/openhab/binding/sbus/handler/SbusRgbwHandler.java index b99003734db..c3af88f0d5e 100644 --- a/bundles/org.openhab.binding.sbus/src/main/java/org/openhab/binding/sbus/handler/SbusRgbwHandler.java +++ b/bundles/org.openhab.binding.sbus/src/main/java/org/openhab/binding/sbus/handler/SbusRgbwHandler.java @@ -12,12 +12,11 @@ */ package org.openhab.binding.sbus.handler; -import static org.openhab.binding.sbus.BindingConstants.*; - import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.sbus.internal.config.SbusChannelConfig; import org.openhab.binding.sbus.internal.config.SbusDeviceConfig; import org.openhab.core.library.types.HSBType; +import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelUID; @@ -56,7 +55,7 @@ public class SbusRgbwHandler extends AbstractSbusHandler { * @param hsbType the openHAB HSBType (hue [0..360], sat [0..100], bri [0..100]) * @return an int array [R, G, B, W] each in [0..255] */ - public static int[] hsbToRgbw(HSBType hsbType) { + private int[] hsbToRgbw(HSBType hsbType) { if (hsbType == null) { throw new IllegalArgumentException("HSBType cannot be null."); } @@ -88,7 +87,7 @@ public class SbusRgbwHandler extends AbstractSbusHandler { * @param rgbw an int array [R, G, B, W] each in [0..255] * @return an HSBType (hue [0..360], saturation/brightness [0..100]) */ - public static HSBType rgbwToHsb(int[] rgbw) { + private HSBType rgbwToHsb(int[] rgbw) { if (rgbw == null || rgbw.length < 4) { throw new IllegalArgumentException("rgbw must be non-null and have 4 elements: [R, G, B, W]."); } @@ -114,16 +113,49 @@ public class SbusRgbwHandler extends AbstractSbusHandler { return hsbType; } + /** + * Checks if any RGBW value is greater than 0. + * + * @param rgbw an int array [R, G, B, W] each in [0..255] + * @return true if any value is greater than 0, false otherwise + */ + private boolean isAnyRgbwValueActive(int[] rgbw) { + if (rgbw == null || rgbw.length < 4) { + return false; + } + for (int value : rgbw) { + if (value > 0) { + return true; + } + } + return false; + } + @Override protected void initializeChannels() { - // Validate all color channel configurations + int switchChannelCount = 0; + + // Validate all channel configurations for (Channel channel : getThing().getChannels()) { - if ("color-channel".equals(channel.getChannelTypeUID().getId())) { - SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class); + SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class); + String channelTypeId = channel.getChannelTypeUID().getId(); + if ("color-channel".equals(channelTypeId)) { if (channelConfig.channelNumber <= 0) { logger.warn("Channel {} has invalid channel number configuration", channel.getUID()); } } + if ("switch-channel".equals(channelTypeId)) { + switchChannelCount++; + if (channelConfig.channelNumber <= 0) { + logger.warn("Channel {} has invalid channel number configuration", channel.getUID()); + } + } + } + if (switchChannelCount > 1) { + logger.error("Only one switch channel is allowed for RGBW thing {}", getThing().getUID()); + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "Only one switch channel is allowed"); + return; } } @@ -139,19 +171,26 @@ public class SbusRgbwHandler extends AbstractSbusHandler { try { SbusDeviceConfig config = getConfigAs(SbusDeviceConfig.class); - // Update all color channels + // Update all channels for (Channel channel : getThing().getChannels()) { - if ("color-channel".equals(channel.getChannelTypeUID().getId())) { - SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class); + String channelTypeId = channel.getChannelTypeUID().getId(); + SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class); + if ("color-channel".equals(channelTypeId)) { // Read RGBW values for this channel int[] rgbwValues = adapter.readRgbw(config.subnetId, config.id, channelConfig.channelNumber); if (rgbwValues != null && rgbwValues.length >= 4) { // Convert RGBW to HSB using our custom conversion HSBType hsbType = rgbwToHsb(rgbwValues); - updateState(channel.getUID(), hsbType); } + } else if ("switch-channel".equals(channelTypeId)) { + // Read status channels for switch states + int[] statuses = adapter.readStatusChannels(config.subnetId, config.id); + + // Update switch state + boolean isActive = isAnyRgbwValueActive(statuses); + updateState(channel.getUID(), isActive ? OnOffType.ON : OnOffType.OFF); } } @@ -173,20 +212,24 @@ public class SbusRgbwHandler extends AbstractSbusHandler { try { Channel channel = getThing().getChannel(channelUID.getId()); - if (channel != null && "color-channel".equals(channel.getChannelTypeUID().getId()) - && command instanceof HSBType hsbCommand) { + if (channel != null) { + String channelTypeId = channel.getChannelTypeUID().getId(); SbusDeviceConfig config = getConfigAs(SbusDeviceConfig.class); SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class); - // Convert HSB to RGBW - int[] rgbw = hsbToRgbw(hsbCommand); - - // Write all RGBW values at once using the dedicated method - adapter.writeRgbw(config.subnetId, config.id, channelConfig.channelNumber, rgbw[0], rgbw[1], rgbw[2], - rgbw[3]); - - // Update state - updateState(channelUID, hsbCommand); + if ("color-channel".equals(channelTypeId) && command instanceof HSBType hsbCommand) { + // Handle color command + int[] rgbw = hsbToRgbw(hsbCommand); + adapter.writeRgbw(config.subnetId, config.id, channelConfig.channelNumber, rgbw[0], rgbw[1], + rgbw[2], rgbw[3]); + updateState(channelUID, hsbCommand); + } else if ("switch-channel".equals(channelTypeId) && command instanceof OnOffType onOffCommand) { + // Handle switch command + boolean isOn = onOffCommand == OnOffType.ON; + adapter.writeSingleChannel(config.subnetId, config.id, channelConfig.channelNumber, isOn ? 100 : 0, + -1); + updateState(channelUID, isOn ? OnOffType.ON : OnOffType.OFF); + } } } catch (Exception e) { logger.error("Error handling command", e); diff --git a/bundles/org.openhab.binding.sbus/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.sbus/src/main/resources/OH-INF/thing/thing-types.xml index b8d4748a139..e0b438f5001 100644 --- a/bundles/org.openhab.binding.sbus/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.sbus/src/main/resources/OH-INF/thing/thing-types.xml @@ -149,6 +149,12 @@ Color control ColorLight + + + + The physical channel number on the SBUS device + +