[sbus] fix required changes to become compliant

Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Ciprian Pascu 2025-01-07 16:03:38 +02:00
parent a129162950
commit 04f0cea871
23 changed files with 396 additions and 390 deletions

View File

@ -331,6 +331,7 @@
/bundles/org.openhab.binding.salus/ @magx2
/bundles/org.openhab.binding.samsungtv/ @NickWaterton
/bundles/org.openhab.binding.satel/ @druciak
/bundles/org.openhab.binding.sbus/ @cipianpascu
/bundles/org.openhab.binding.semsportal/ @itb3
/bundles/org.openhab.binding.senechome/ @vctender @KorbinianP @eguib
/bundles/org.openhab.binding.seneye/ @nikotanghe

View File

@ -1,98 +0,0 @@
# SBUS Binding Development
This document provides information for developers who want to contribute to the OpenHAB SBUS binding.
## Development Setup
1. Clone the OpenHAB addons repository:
```bash
git clone https://github.com/openhab/openhab-addons.git
cd openhab-addons
```
2. Build the binding:
```bash
cd bundles/org.openhab.binding.sbus
mvn clean install
```
## Project Structure
```
org.openhab.binding.sbus/
├── src/main/java/org/openhab/binding/sbus/
│ ├── handler/ # Thing handlers
│ │ ├── SbusRgbwHandler.java
│ │ ├── SbusSwitchHandler.java
│ │ └── SbusTemperatureHandler.java
│ └── internal/ # Internal implementation
│ └── SbusBridgeHandler.java
└── src/main/resources/
└── OH-INF/ # OpenHAB configuration files
├── binding/ # Binding definitions
├── thing/ # Thing type definitions
└── i18n/ # Internationalization
```
## Key Components
* `SbusBridgeHandler`: Manages the UDP connection to SBUS devices
* `SbusRgbwHandler`: Handles RGBW light control
* `SbusSwitchHandler`: Handles switch control
* `SbusTemperatureHandler`: Handles temperature sensor readings
## Testing
1. Unit Tests
* Run unit tests with: `mvn test`
* Add new tests in `src/test/java/`
2. Integration Testing
* Test with real SBUS devices
* Verify all supported channels work correctly
* Test error handling and recovery
## Debugging
1. Enable debug logging in OpenHAB:
```
log:set DEBUG org.openhab.binding.sbus
```
2. Monitor SBUS communication:
```
openhab> sbus:monitor start
```
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
* Follow OpenHAB coding guidelines
* Add appropriate unit tests
* Update documentation
4. Submit a pull request
### Code Style
* Follow OpenHAB's code style guidelines
* Use the provided code formatter
* Run `mvn spotless:apply` before committing
### Documentation
When adding new features:
1. Update README.md with user-facing changes
2. Update thing-types.xml for new channels/configurations
3. Add appropriate JavaDoc comments
4. Update this DEVELOPERS.md if needed
## Building from Source
```bash
cd openhab-addons/bundles/org.openhab.binding.sbus
mvn clean install
```
The built JAR will be in `target/org.openhab.binding.sbus-[version].jar`

View File

@ -1,122 +1,132 @@
# OpenHAB SBUS Binding
# Sbus Binding
This binding integrates SBUS devices with OpenHAB, allowing control and monitoring of SBUS-compatible devices over UDP.
This binding integrates Sbus devices with openHAB, allowing control and monitoring of Sbus-compatible devices over UDP.
Sbus is a protocol used for home automation devices that communicate over UDP networks.
The binding supports various device types including RGB/RGBW controllers, temperature sensors, and switch controllers.
## Supported Things
* SBUS Bridge (Thing Type: `bridge-udp`)
* RGB/RGBW Controllers
* Temperature Sensors
* Switch Controllers
* `udp` - Sbus Bridge for UDP communication
* `rgbw` - RGB/RGBW Controllers for color and brightness control
* `temperature` - Temperature Sensors for monitoring environmental conditions
* `switch` - Switch Controllers for basic on/off and dimming control
## Installation
## Discovery
Install this binding through the OpenHAB console:
Sbus devices communicate via UDP broadcast, but manual configuration is required to set up the devices in openHAB.
Auto-discovery is not supported at this moment.
```
bundle:install org.openhab.binding.sbus
```
## Binding Configuration
## Configuration
The binding itself does not require any special configuration.
## Thing Configuration
### Bridge Configuration
The SBUS Bridge requires the following configuration parameters:
The Sbus Bridge requires the following configuration parameters:
* `host` - IP address of the SBUS device
* `port` - UDP port number (default: 5000)
| Name | Type | Description | Default | Required | Advanced |
|---------|---------|------------------------------------------------------|---------|----------|-----------|
| host | text | IP address of the Sbus device (typically broadcast) | N/A | yes | no |
| port | integer | UDP port number | 6000 | no | no |
Example:
### RGBW Controller Configuration
```
Bridge sbus:udp:mybridge [ host="192.168.1.255", port=5000 ]
```
| Name | Type | Description | Default | Required | Advanced |
|---------|---------|------------------------------------------------------|---------|----------|-----------|
| subnetId| integer | Subnet ID the RGBW controller is part of | N/A | yes | no |
| id | integer | Device ID of the RGBW controller | N/A | yes | no |
| refresh | integer | Refresh interval in seconds | 30 | no | yes |
Please note the broadcast address. This is how Sbus devices communicate with each other.
### Temperature Sensor Configuration
| Name | Type | Description | Default | Required | Advanced |
|---------|---------|------------------------------------------------------|---------|----------|-----------|
| subnetId| integer | Subnet ID the temperature sensor is part of | N/A | yes | no |
| id | integer | Device ID of the temperature sensor | N/A | yes | no |
| refresh | integer | Refresh interval in seconds | 30 | no | yes |
### Switch Controller Configuration
| Name | Type | Description | Default | Required | Advanced |
|---------|---------|------------------------------------------------------|---------|----------|-----------|
| subnetId| integer | Subnet ID the switch controller is part of | N/A | yes | no |
| id | integer | Device ID of the switch controller | N/A | yes | no |
| refresh | integer | Refresh interval in seconds | 30 | no | yes |
## Channels
### RGBW Controller Channels
| Channel | Type | Read/Write | Description |
|---------|--------|------------|------------------------------------------------------------|
| color | Color | RW | HSB color picker that controls RGBW components (0-100%) |
| switch | Switch | RW | On/Off control for the RGBW output with optional timer |
### Temperature Sensor Channels
| Channel | Type | Read/Write | Description |
|-------------|---------------------|------------|--------------------------------|
| temperature | Number:Temperature | R | Current temperature reading. Can be configured to use Celsius (default) or Fahrenheit units |
### Switch Controller Channels
| Channel | Type | Read/Write | Description |
|---------|--------|------------|-----------------------------------------------------------|
| switch | Switch | RW | Basic ON/OFF state control |
| dimmer | Dimmer | RW | ON/OFF state with timer transition |
| paired | Paired | RW | ON/OFF state for two paired channels (e.g., curtains) |
## Full Example
### Thing Configuration
#### RGBW Controller
```
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.
Bridge sbus:udp:mybridge [ host="192.168.1.255", port=5000 ] {
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 For complex scenes, one Sbus color controller can keep up to 40 color states. The switch channelNumber has to fall into this range.
}
Thing temperature temp1 [ id=62, refresh=30 ] {
Channels:
Type temperature-channel : temperature [ channelNumber=1 ]
}
Thing switch switch1 [ id=75, refresh=30 ] {
Channels:
Type switch-channel : first_switch [ channelNumber=1 ]
Type dimmer-channel : second_switch [ channelNumber=2 ]
Type paired-channel : third_switch [ channelNumber=3 ]
}
}
```
Supported channels:
* `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
```
Thing temperature temp1 [ id=62, refresh=30 ] {
Channels:
Type temperature-channel : temperature [ channelNumber=1 ]
}
```
Supported channels:
* `temperature` - Current temperature reading
#### Switch Controller
```
Thing switch switch1 [ id=75, refresh=30 ] {
Channels:
Type switch-channel : first_switch [ channelNumber=1 ]
Type dimmer-channel : second_switch [ channelNumber=2 ]
Type paired-channel : third_switch [ channelNumber=3 ]
}
```
Supported channels:
* `switch` - ON/OFF state
* `dimmer` - ON/OFF state with timer transition
* `paired` - ON/OFF state for two paired channels. This feature is used for curtains and other devices that require two actuator channels.
## Example Usage
items/sbus.items:
### Item Configuration
```
// Temperature Sensor
Number:Temperature Temp_Sensor "Temperature [%.1f °C]" { channel="sbus:temperature:mybridge:temp1:temperature" }
// Basic Switch
Switch Light_Switch "Switch" { channel="sbus:switch:mybridge:switch1:switch" }
```
Example: RGBW Controller with Power Control
```
// Light Group
// RGBW Controller with Power Control
Group gLight "RGBW Light" <light> ["Lighting"]
// Color Control
Color rgbwColor "Color" <colorwheel> (gLight) ["Control", "Light"] { channel="sbus:rgbw:mybridge:colorctrl:color" }
// Power Control
Switch rgbwPower "Power" <switch> (gLight) ["Switch", "Light"] { channel="sbus:rgbw:mybridge:colorctrl:power" }
```
sitemap/sbus.sitemap:
### Sitemap Configuration
```
sitemap sbus label="SBUS Demo"
sitemap sbus label="Sbus Demo"
{
Frame label="SBUS Controls" {
Frame label="Sbus Controls" {
Colorpicker item=Light_RGB
Text item=Temp_Sensor
Switch item=Light_Switch
}
}
```

View File

@ -12,64 +12,15 @@
<artifactId>org.openhab.binding.sbus</artifactId>
<name>openHAB Add-ons :: Bundles :: SBUS Binding</name>
<name>openHAB Add-ons :: Bundles :: Sbus Binding</name>
<dependencies>
<dependency>
<groupId>ro.ciprianpascu</groupId>
<artifactId>j2sbus</artifactId>
<version>1.5.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>embed-dependencies</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>j2sbus</includeArtifactIds>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<configuration>
<bnd><![CDATA[
Bundle-SymbolicName: ${project.artifactId}
Bundle-Version: ${project.version}
Import-Package: \
!ro.ciprianpascu.*, \
org.openhab.core.*, \
org.eclipse.jdt.annotation;resolution:=optional, \
*
Private-Package: \
ro.ciprianpascu.sbus.*
-exportcontents: org.openhab.binding.sbus.*
-dsannotations: *
-dsannotations-options: norequirements
-noimportjava: true
]]></bnd>
</configuration>
<executions>
<execution>
<goals>
<goal>bnd-process</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -16,7 +16,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link BindingConstants} class defines common constants used across the SBUS binding.
* The {@link BindingConstants} class defines common constants used across the Sbus binding.
*
* @author Ciprian Pascu - Initial contribution
*/

View File

@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory;
import ro.ciprianpascu.sbus.facade.SbusAdapter;
/**
* The {@link AbstractSbusHandler} is the base class for all SBUS device handlers.
* The {@link AbstractSbusHandler} is the base class for all Sbus device handlers.
* It provides common functionality for device initialization, channel management, and polling.
*
* @author Ciprian Pascu - Initial contribution
@ -56,7 +56,7 @@ public abstract class AbstractSbusHandler extends BaseThingHandler {
@Override
public final void initialize() {
logger.debug("Initializing SBUS handler for thing {}", getThing().getUID());
logger.debug("Initializing Sbus handler for thing {}", getThing().getUID());
initializeChannels();
@ -68,18 +68,18 @@ public abstract class AbstractSbusHandler extends BaseThingHandler {
SbusBridgeHandler bridgeHandler = (SbusBridgeHandler) bridge.getHandler();
if (bridgeHandler == null || bridgeHandler.getThing().getStatus() != ThingStatus.ONLINE) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "Bridge is not online");
updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.BRIDGE_OFFLINE, "Bridge is not online");
return;
}
try {
sbusAdapter = bridgeHandler.getSbusConnection();
updateStatus(ThingStatus.ONLINE);
startPolling();
} catch (Exception e) {
logger.error("Error initializing SBUS connection", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
sbusAdapter = bridgeHandler.getSbusConnection();
if (sbusAdapter == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED,
"Bridge connection not initialized");
return;
}
startPolling();
}
/**
@ -125,7 +125,7 @@ public abstract class AbstractSbusHandler extends BaseThingHandler {
try {
pollDevice();
} catch (Exception e) {
logger.error("Error polling SBUS device", e);
logger.error("Error polling Sbus device", e);
}
}, 0, config.refresh, TimeUnit.SECONDS);
}
@ -139,13 +139,16 @@ public abstract class AbstractSbusHandler extends BaseThingHandler {
@Override
public void dispose() {
if (pollingJob != null) {
pollingJob.cancel(true);
ScheduledFuture<?> job = pollingJob;
if (job != null) {
job.cancel(true);
}
final SbusAdapter adapter = sbusAdapter;
if (adapter != null) {
adapter.close();
}
pollingJob = null;
sbusAdapter = null;
super.dispose();
}
}

View File

@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
import ro.ciprianpascu.sbus.facade.SbusAdapter;
/**
* The {@link SbusRgbwHandler} is responsible for handling commands for SBUS RGBW devices.
* The {@link SbusRgbwHandler} is responsible for handling commands for Sbus RGBW devices.
* It supports reading and controlling red, green, blue, and white color channels.
*
* @author Ciprian Pascu - Initial contribution
@ -56,10 +56,6 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
* @return an int array [R, G, B, W] each in [0..255]
*/
private int[] hsbToRgbw(HSBType hsbType) {
if (hsbType == null) {
throw new IllegalArgumentException("HSBType cannot be null.");
}
// Convert HSBType to standard RGB [0..255]
PercentType[] rgb = ColorUtil.hsbToRgbPercent(hsbType);
// Convert each channel from 0..100 to 0..255
@ -88,8 +84,8 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
* @return an HSBType (hue [0..360], saturation/brightness [0..100])
*/
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].");
if (rgbw.length < 4) {
throw new IllegalArgumentException("rgbw must have 4 elements: [R, G, B, W].");
}
int r = rgbw[0];
@ -120,7 +116,7 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
* @return true if any value is greater than 0, false otherwise
*/
private boolean isAnyRgbwValueActive(int[] rgbw) {
if (rgbw == null || rgbw.length < 4) {
if (rgbw.length < 4) {
return false;
}
for (int value : rgbw) {
@ -138,7 +134,12 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
// Validate all channel configurations
for (Channel channel : getThing().getChannels()) {
SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class);
String channelTypeId = channel.getChannelTypeUID().getId();
var channelTypeUID = channel.getChannelTypeUID();
if (channelTypeUID == null) {
logger.warn("Channel {} has no channel type", channel.getUID());
continue;
}
String channelTypeId = channelTypeUID.getId();
if ("color-channel".equals(channelTypeId)) {
if (channelConfig.channelNumber <= 0) {
logger.warn("Channel {} has invalid channel number configuration", channel.getUID());
@ -163,8 +164,7 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
protected void pollDevice() {
final SbusAdapter adapter = super.sbusAdapter;
if (adapter == null) {
logger.warn("SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Sbus adapter not initialized");
return;
}
@ -173,7 +173,12 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
// Update all channels
for (Channel channel : getThing().getChannels()) {
String channelTypeId = channel.getChannelTypeUID().getId();
var channelTypeUID = channel.getChannelTypeUID();
if (channelTypeUID == null) {
logger.warn("Channel {} has no channel type", channel.getUID());
continue;
}
String channelTypeId = channelTypeUID.getId();
SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class);
if ("color-channel".equals(channelTypeId)) {
@ -196,7 +201,6 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
updateStatus(ThingStatus.ONLINE);
} catch (Exception e) {
logger.error("Error reading device state", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Error reading device state");
}
}
@ -205,15 +209,20 @@ public class SbusRgbwHandler extends AbstractSbusHandler {
public void handleCommand(ChannelUID channelUID, Command command) {
final SbusAdapter adapter = super.sbusAdapter;
if (adapter == null) {
logger.warn("SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "SBUS adapter not initialized");
logger.warn("Sbus adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Sbus adapter not initialized");
return;
}
try {
Channel channel = getThing().getChannel(channelUID.getId());
if (channel != null) {
String channelTypeId = channel.getChannelTypeUID().getId();
var channelTypeUID = channel.getChannelTypeUID();
if (channelTypeUID == null) {
logger.warn("Channel {} has no channel type", channel.getUID());
return;
}
String channelTypeId = channelTypeUID.getId();
SbusDeviceConfig config = getConfigAs(SbusDeviceConfig.class);
SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class);

View File

@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
import ro.ciprianpascu.sbus.facade.SbusAdapter;
/**
* The {@link SbusSwitchHandler} is responsible for handling commands for SBUS switch devices.
* The {@link SbusSwitchHandler} is responsible for handling commands for Sbus switch devices.
* It supports reading the current state and switching the device on/off.
*
* @author Ciprian Pascu - Initial contribution
@ -58,14 +58,9 @@ public class SbusSwitchHandler extends AbstractSbusHandler {
@Override
protected void pollDevice() {
handleReadStatusChannels();
}
private void handleReadStatusChannels() {
final SbusAdapter adapter = super.sbusAdapter;
if (adapter == null) {
logger.warn("SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Sbus adapter not initialized");
return;
}
@ -73,7 +68,7 @@ public class SbusSwitchHandler extends AbstractSbusHandler {
SbusDeviceConfig config = getConfigAs(SbusDeviceConfig.class);
int[] statuses = adapter.readStatusChannels(config.subnetId, config.id);
if (statuses == null) {
logger.warn("Received null status channels from SBUS device");
logger.warn("Received null status channels from Sbus device");
return;
}
@ -81,9 +76,14 @@ public class SbusSwitchHandler extends AbstractSbusHandler {
for (Channel channel : getThing().getChannels()) {
SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class);
if (channelConfig.channelNumber > 0 && channelConfig.channelNumber <= statuses.length) {
String channelTypeId = channel.getChannelTypeUID().getId();
boolean isActive = statuses[channelConfig.channelNumber - 1] == 0x64; // 100 when on, something else
// when off
var channelTypeUID = channel.getChannelTypeUID();
if (channelTypeUID == null) {
logger.warn("Channel {} has no channel type", channel.getUID());
continue;
}
String channelTypeId = channelTypeUID.getId();
// 100 when on, something else when off
boolean isActive = statuses[channelConfig.channelNumber - 1] == 0x64;
if ("switch-channel".equals(channelTypeId)) {
updateState(channel.getUID(), isActive ? OnOffType.ON : OnOffType.OFF);
@ -95,7 +95,7 @@ public class SbusSwitchHandler extends AbstractSbusHandler {
}
}
} catch (Exception e) {
logger.error("Error reading status channels", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Error reading device state");
}
}
@ -103,8 +103,8 @@ public class SbusSwitchHandler extends AbstractSbusHandler {
public void handleCommand(ChannelUID channelUID, Command command) {
final SbusAdapter adapter = super.sbusAdapter;
if (adapter == null) {
logger.warn("SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "SBUS adapter not initialized");
logger.warn("Sbus adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Sbus adapter not initialized");
return;
}

View File

@ -13,9 +13,10 @@
package org.openhab.binding.sbus.handler;
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.binding.sbus.internal.config.TemperatureChannelConfig;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.ImperialUnits;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
@ -29,7 +30,7 @@ import org.slf4j.LoggerFactory;
import ro.ciprianpascu.sbus.facade.SbusAdapter;
/**
* The {@link SbusTemperatureHandler} is responsible for handling commands for SBUS temperature sensors.
* The {@link SbusTemperatureHandler} is responsible for handling commands for Sbus temperature sensors.
* It supports reading temperature values in Celsius.
*
* @author Ciprian Pascu - Initial contribution
@ -48,44 +49,52 @@ public class SbusTemperatureHandler extends AbstractSbusHandler {
// Get all channel configurations from the thing
for (Channel channel : getThing().getChannels()) {
// Channels are already defined in thing-types.xml, just validate their configuration
SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class);
if (channelConfig.channelNumber <= 0) {
logger.warn("Channel {} has invalid channel number configuration", channel.getUID());
TemperatureChannelConfig channelConfig = channel.getConfiguration().as(TemperatureChannelConfig.class);
if (!channelConfig.isValid()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"Invalid channel configuration: " + channel.getUID());
return;
}
}
}
@Override
protected void pollDevice() {
handleReadTemperature();
}
private void handleReadTemperature() {
final SbusAdapter adapter = super.sbusAdapter;
if (adapter == null) {
logger.warn("SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "SBUS adapter not initialized");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Sbus adapter not initialized");
return;
}
try {
SbusDeviceConfig config = getConfigAs(SbusDeviceConfig.class);
// Read temperatures in Celsius from device
float[] temperatures = adapter.readTemperatures(config.subnetId, config.id);
if (temperatures == null) {
logger.warn("Received null temperatures from SBUS device");
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Received null temperatures");
return;
}
// Iterate over all channels and update their states with corresponding temperatures
for (Channel channel : getThing().getChannels()) {
SbusChannelConfig channelConfig = channel.getConfiguration().as(SbusChannelConfig.class);
TemperatureChannelConfig channelConfig = channel.getConfiguration().as(TemperatureChannelConfig.class);
if (channelConfig.channelNumber > 0 && channelConfig.channelNumber <= temperatures.length) {
float temperature = temperatures[channelConfig.channelNumber - 1];
updateState(channel.getUID(), new QuantityType<>(temperature, SIUnits.CELSIUS));
float temperatureCelsius = temperatures[channelConfig.channelNumber - 1];
if (channelConfig.isFahrenheit()) {
// Convert Celsius to Fahrenheit
float temperatureFahrenheit = (temperatureCelsius * 9 / 5) + 32;
updateState(channel.getUID(),
new QuantityType<>(temperatureFahrenheit, ImperialUnits.FAHRENHEIT));
} else {
updateState(channel.getUID(), new QuantityType<>(temperatureCelsius, SIUnits.CELSIUS));
}
}
}
updateStatus(ThingStatus.ONLINE);
} catch (Exception e) {
logger.error("Error reading temperature", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Error reading device state");
}
}

View File

@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
import ro.ciprianpascu.sbus.facade.SbusAdapter;
/**
* The {@link SbusBridgeHandler} is responsible for handling communication with the SBUS bridge.
* The {@link SbusBridgeHandler} is responsible for handling communication with the Sbus bridge.
*
* @author Ciprian Pascu - Initial contribution
*/
@ -39,7 +39,7 @@ public class SbusBridgeHandler extends BaseBridgeHandler {
private @Nullable SbusAdapter sbusConnection;
/**
* Constructs a new SBUSBridgeHandler.
* Constructs a new SbusBridgeHandler.
*
* @param bridge the bridge
*/
@ -48,51 +48,49 @@ public class SbusBridgeHandler extends BaseBridgeHandler {
}
/**
* Initializes the SBUS bridge handler by establishing a connection to the SBUS network.
* Initializes the Sbus bridge handler by establishing a connection to the Sbus network.
*/
@Override
public void initialize() {
logger.debug("Initializing SBUS bridge handler for bridge {}", getThing().getUID());
logger.debug("Initializing Sbus bridge handler for bridge {}", getThing().getUID());
// Get configuration using the config class
SbusBridgeConfig config = getConfigAs(SbusBridgeConfig.class);
if (config.host.isBlank()) {
updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.CONFIGURATION_ERROR, "Host address not configured");
return;
}
try {
// Get configuration using the config class
SbusBridgeConfig config = getConfigAs(SbusBridgeConfig.class);
if (config.host.isEmpty()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Host address not configured");
return;
}
// Initialize SBUS connection with the configuration parameters
// Initialize Sbus connection with the configuration parameters
sbusConnection = new SbusAdapter(config.host, config.port);
updateStatus(ThingStatus.ONLINE);
logger.debug("SBUS bridge handler initialized successfully");
} catch (Exception e) {
logger.error("Error initializing SBUS bridge", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
}
}
/**
* Gets the SBUS adapter connection.
* Gets the Sbus adapter connection.
*
* @return the SBUS adapter
* @return the Sbus adapter
*/
public @Nullable SbusAdapter getSbusConnection() {
return sbusConnection;
}
/**
* Disposes the handler by closing the SBUS connection.
* Disposes the handler by closing the Sbus connection.
*/
@Override
public void dispose() {
logger.debug("Disposing SBUS bridge handler");
logger.debug("Disposing Sbus bridge handler");
final SbusAdapter connection = sbusConnection;
if (connection != null) {
connection.close();
}
sbusConnection = null;
super.dispose();
}

View File

@ -55,18 +55,18 @@ public class SbusHandlerFactory extends BaseThingHandlerFactory {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(THING_TYPE_UDP_BRIDGE)) {
logger.debug("Creating SBUS UDP bridge handler for thing {}", thing.getUID());
logger.debug("Creating Sbus UDP bridge handler for thing {}", thing.getUID());
return new SbusBridgeHandler((Bridge) thing);
}
if (thingTypeUID.equals(THING_TYPE_SWITCH)) {
logger.debug("Creating SBUS switch handler for thing {}", thing.getUID());
logger.debug("Creating Sbus switch handler for thing {}", thing.getUID());
return new SbusSwitchHandler(thing);
} else if (thingTypeUID.equals(THING_TYPE_TEMPERATURE)) {
logger.debug("Creating SBUS temperature handler for thing {}", thing.getUID());
logger.debug("Creating Sbus temperature handler for thing {}", thing.getUID());
return new SbusTemperatureHandler(thing);
} else if (thingTypeUID.equals(THING_TYPE_RGBW)) {
logger.debug("Creating SBUS RGBW handler for thing {}", thing.getUID());
logger.debug("Creating Sbus RGBW handler for thing {}", thing.getUID());
return new SbusRgbwHandler(thing);
}

View File

@ -24,12 +24,12 @@ import ro.ciprianpascu.sbus.Sbus;
@NonNullByDefault
public class SbusBridgeConfig {
/**
* The host address of the SBUS bridge
* The host address of the Sbus bridge
*/
public String host = "";
public String host = "localhost";
/**
* The port number for SBUS communication
* The port number for Sbus communication
*/
public int port = Sbus.DEFAULT_PORT;
}

View File

@ -22,7 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
@NonNullByDefault
public class SbusChannelConfig {
/**
* The physical channel number on the SBUS device.
* The physical channel number on the Sbus device.
*/
public int channelNumber;

View File

@ -24,12 +24,12 @@ import ro.ciprianpascu.sbus.Sbus;
@NonNullByDefault
public class SbusDeviceConfig {
/**
* The ID of the SBUS device
* The ID of the Sbus device
*/
public int id = Sbus.DEFAULT_UNIT_ID;
/**
* The subnet ID for SBUS communication
* The subnet ID for Sbus communication
*/
public int subnetId = Sbus.DEFAULT_SUBNET_ID;

View File

@ -0,0 +1,52 @@
/**
* Copyright (c) 2010-2025 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.sbus.internal.config;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* Configuration class for the temperature channel.
*
* @author Ciprian Pascu - Initial contribution
*/
@NonNullByDefault
public class TemperatureChannelConfig {
/**
* The physical channel number on the Sbus device
*/
public int channelNumber = 1;
/**
* The unit to use for temperature readings (CELSIUS or FAHRENHEIT)
*/
public String unit = "CELSIUS";
/**
* Validates the configuration parameters.
*
* @return true if the configuration is valid
*/
public boolean isValid() {
return channelNumber > 0 && ("CELSIUS".equals(unit) || "FAHRENHEIT".equals(unit));
}
/**
* Checks if the configured unit is Fahrenheit
*
* @return true if Fahrenheit is configured, false otherwise
*/
public boolean isFahrenheit() {
return "FAHRENHEIT".equals(unit);
}
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="sbus" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
<name>SBUS Binding</name>
<description>Binding for SBUS communication protocol</description>
<author>Ciprian Pascu</author>
</binding:binding>

View File

@ -1,6 +0,0 @@
# add-on
addon.sbus.name = S-Bus Binding
addon.sbus.description = Binding for S-Bus

View File

@ -0,0 +1,95 @@
# add-on
addon.sbus.name = Sbus Binding
addon.sbus.description = Binding for Sbus
# thing types
thing-type.sbus.rgbw.label = Sbus RGBW Controller
thing-type.sbus.rgbw.description = Sbus RGBW lighting controller
thing-type.sbus.switch.label = Sbus Switch
thing-type.sbus.switch.description = Sbus switch device
thing-type.sbus.temperature.label = Sbus Temperature Sensor
thing-type.sbus.temperature.description = Sbus temperature sensor device
thing-type.sbus.udp.label = Sbus UDP Slave
thing-type.sbus.udp.description = Endpoint for Sbus UDP slaves
# thing types config
thing-type.config.sbus.rgbw.id.label = Device ID
thing-type.config.sbus.rgbw.id.description = The ID of the Sbus device
thing-type.config.sbus.rgbw.refresh.label = Refresh Interval
thing-type.config.sbus.rgbw.refresh.description = Refresh interval in seconds
thing-type.config.sbus.rgbw.subnetId.label = SubnetId
thing-type.config.sbus.rgbw.subnetId.description = Slave subnet id. Can take any value between 0 and 255.
thing-type.config.sbus.switch.id.label = Device ID
thing-type.config.sbus.switch.id.description = The ID of the Sbus device
thing-type.config.sbus.switch.refresh.label = Refresh Interval
thing-type.config.sbus.switch.refresh.description = Refresh interval in seconds
thing-type.config.sbus.switch.subnetId.label = SubnetId
thing-type.config.sbus.switch.subnetId.description = Slave subnet id. Can take any value between 0 and 255.
thing-type.config.sbus.temperature.id.label = Device ID
thing-type.config.sbus.temperature.id.description = The ID of the Sbus device
thing-type.config.sbus.temperature.refresh.label = Refresh Interval
thing-type.config.sbus.temperature.refresh.description = Refresh interval in seconds
thing-type.config.sbus.temperature.subnetId.label = SubnetId
thing-type.config.sbus.temperature.subnetId.description = Slave subnet id. Can take any value between 0 and 255.
thing-type.config.sbus.udp.afterConnectionDelayMillis.label = Connection warm-up time
thing-type.config.sbus.udp.afterConnectionDelayMillis.description = Connection warm-up time. Additional time which is spent on preparing connection which should be spent waiting while end device is getting ready to answer first sbus call. In milliseconds.
thing-type.config.sbus.udp.connectMaxTries.label = Maximum Connection Tries
thing-type.config.sbus.udp.connectMaxTries.description = How many times we try to establish the connection. Should be at least 1.
thing-type.config.sbus.udp.connectTimeoutMillis.label = Timeout for Establishing the Connection
thing-type.config.sbus.udp.connectTimeoutMillis.description = The maximum time that is waited when establishing the connection. Value of zero means that system/OS default is respected. In milliseconds.
thing-type.config.sbus.udp.enableDiscovery.label = Discovery Enabled
thing-type.config.sbus.udp.enableDiscovery.description = When enabled we try to find a device specific handler. Turn this on if you're using one of the supported devices.
thing-type.config.sbus.udp.host.label = IP Address or Hostname
thing-type.config.sbus.udp.host.description = Network address of the device
thing-type.config.sbus.udp.port.label = Port
thing-type.config.sbus.udp.port.description = Port of the slave
thing-type.config.sbus.udp.reconnectAfterMillis.label = Reconnect Again After
thing-type.config.sbus.udp.reconnectAfterMillis.description = The connection is kept open at least the time specified here. Value of zero means that connection is disconnected after every Sbus transaction. In milliseconds.
thing-type.config.sbus.udp.rtuEncoded.label = RTU Encoding
thing-type.config.sbus.udp.rtuEncoded.description = Use RTU Encoding over IP
thing-type.config.sbus.udp.timeBetweenReconnectMillis.label = Time Between Reconnections
thing-type.config.sbus.udp.timeBetweenReconnectMillis.description = How long to wait to before trying to establish a new connection after the previous one has been disconnected. In milliseconds.
thing-type.config.sbus.udp.timeBetweenTransactionsMillis.label = Time Between Transactions
thing-type.config.sbus.udp.timeBetweenTransactionsMillis.description = How long to delay we must have at minimum between two consecutive Sbus transactions. In milliseconds.
# channel group types
channel-group-type.sbus.colors.label = Color Channels
channel-group-type.sbus.colors.description = Group of RGBW color channels
channel-group-type.sbus.sensors.label = Temperature Sensors
channel-group-type.sbus.sensors.description = Group of temperature sensors
channel-group-type.sbus.switches.label = Switch Channels
channel-group-type.sbus.switches.description = Group of switch channels
# channel types
channel-type.sbus.color-channel.label = Color
channel-type.sbus.color-channel.description = Color control
channel-type.sbus.dimmer-channel.label = Dimmer State
channel-type.sbus.dimmer-channel.description = Dimmer state (0-100%)
channel-type.sbus.paired-channel.label = Paired Channel State
channel-type.sbus.paired-channel.description = Paired channel state (OPEN/CLOSED) - controls two opposite channels
channel-type.sbus.switch-channel.label = Switch State
channel-type.sbus.switch-channel.description = Switch state (ON/OFF)
channel-type.sbus.temperature-channel.label = Temperature
channel-type.sbus.temperature-channel.description = Temperature reading from the device
# channel types config
channel-type.config.sbus.color-channel.channelNumber.label = Channel Number
channel-type.config.sbus.color-channel.channelNumber.description = The physical channel number on the Sbus device
channel-type.config.sbus.dimmer-channel.channelNumber.label = Channel Number
channel-type.config.sbus.dimmer-channel.channelNumber.description = The physical channel number on the Sbus device
channel-type.config.sbus.dimmer-channel.timer.label = Timer
channel-type.config.sbus.dimmer-channel.timer.description = Timer in seconds to automatically turn off the switch (0 = disabled)
channel-type.config.sbus.paired-channel.channelNumber.label = Channel Number
channel-type.config.sbus.paired-channel.channelNumber.description = The physical channel number on the Sbus device
channel-type.config.sbus.paired-channel.pairedChannelNumber.label = Paired Channel Number
channel-type.config.sbus.paired-channel.pairedChannelNumber.description = The physical channel number of the paired channel (will be set to opposite state)
channel-type.config.sbus.switch-channel.channelNumber.label = Channel Number
channel-type.config.sbus.switch-channel.channelNumber.description = The physical channel number on the Sbus device
channel-type.config.sbus.temperature-channel.channelNumber.label = Channel Number
channel-type.config.sbus.temperature-channel.channelNumber.description = The physical channel number on the Sbus device

View File

@ -4,7 +4,7 @@
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<bridge-type id="udp">
<label>Sbus UDP Slave</label>
<label>Sbus UDP Bridge</label>
<description>Endpoint for Sbus UDP slaves</description>
<config-description>
<parameter name="host" type="text" required="true">
@ -35,7 +35,7 @@
<!-- connection handling -->
<parameter name="timeBetweenTransactionsMillis" type="integer" min="0" unit="ms">
<label>Time Between Transactions</label>
<description>How long to delay we must have at minimum between two consecutive SBUS transactions. In milliseconds.
<description>How long to delay we must have at minimum between two consecutive Sbus transactions. In milliseconds.
</description>
<default>60</default>
</parameter>
@ -62,7 +62,7 @@
<parameter name="reconnectAfterMillis" type="integer" min="0" unit="ms">
<label>Reconnect Again After</label>
<description>The connection is kept open at least the time specified here. Value of zero means that connection is
disconnected after every SBUS transaction. In milliseconds.</description>
disconnected after every Sbus transaction. In milliseconds.</description>
<default>0</default>
<advanced>true</advanced>
</parameter>

View File

@ -10,17 +10,19 @@
<supported-bridge-type-refs>
<bridge-type-ref id="udp"/>
</supported-bridge-type-refs>
<label>SBUS Switch</label>
<description>SBUS switch device</description>
<label>Sbus Switch</label>
<description>Sbus switch device</description>
<config-description>
<parameter name="subnetId" type="integer">
<label>SubnetId</label>
<description>Slave subnet id. Can take any value between 0 and 255.</description>
<description>Slave subnet id. Can take any value between 1 and 255. 255 for broadcast.</description>
<default>1</default>
<min>1</min>
<max>255</max>
</parameter>
<parameter name="id" type="integer" required="true">
<label>Device ID</label>
<description>The ID of the SBUS device</description>
<description>The ID of the Sbus device</description>
</parameter>
<parameter name="refresh" type="integer">
<label>Refresh Interval</label>
@ -35,17 +37,19 @@
<supported-bridge-type-refs>
<bridge-type-ref id="udp"/>
</supported-bridge-type-refs>
<label>SBUS Temperature Sensor</label>
<description>SBUS temperature sensor device</description>
<label>Sbus Temperature Sensor</label>
<description>Sbus temperature sensor device</description>
<config-description>
<parameter name="subnetId" type="integer">
<label>SubnetId</label>
<description>Slave subnet id. Can take any value between 0 and 255.</description>
<description>Slave subnet id. Can take any value between 1 and 255. 255 for broadcast.</description>
<default>1</default>
<min>1</min>
<max>255</max>
</parameter>
<parameter name="id" type="integer" required="true">
<label>Device ID</label>
<description>The ID of the SBUS device</description>
<description>The ID of the Sbus device</description>
</parameter>
<parameter name="refresh" type="integer">
<label>Refresh Interval</label>
@ -60,17 +64,19 @@
<supported-bridge-type-refs>
<bridge-type-ref id="udp"/>
</supported-bridge-type-refs>
<label>SBUS RGBW Controller</label>
<description>SBUS RGBW lighting controller</description>
<label>Sbus RGBW Controller</label>
<description>Sbus RGBW lighting controller</description>
<config-description>
<parameter name="subnetId" type="integer">
<label>SubnetId</label>
<description>Slave subnet id. Can take any value between 0 and 255.</description>
<description>Slave subnet id. Can take any value between 1 and 255. 255 for broadcast.</description>
<default>1</default>
<min>1</min>
<max>255</max>
</parameter>
<parameter name="id" type="integer" required="true">
<label>Device ID</label>
<description>The ID of the SBUS device</description>
<description>The ID of the Sbus device</description>
</parameter>
<parameter name="refresh" type="integer">
<label>Refresh Interval</label>
@ -89,7 +95,7 @@
<config-description>
<parameter name="channelNumber" type="integer" required="true">
<label>Channel Number</label>
<description>The physical channel number on the SBUS device</description>
<description>The physical channel number on the Sbus device</description>
</parameter>
</config-description>
</channel-type>
@ -102,7 +108,7 @@
<config-description>
<parameter name="channelNumber" type="integer" required="true">
<label>Channel Number</label>
<description>The physical channel number on the SBUS device</description>
<description>The physical channel number on the Sbus device</description>
</parameter>
<parameter name="timer" type="integer">
<label>Timer</label>
@ -121,7 +127,7 @@
<config-description>
<parameter name="channelNumber" type="integer" required="true">
<label>Channel Number</label>
<description>The physical channel number on the SBUS device</description>
<description>The physical channel number on the Sbus device</description>
</parameter>
<parameter name="pairedChannelNumber" type="integer" required="true">
<label>Paired Channel Number</label>
@ -135,11 +141,20 @@
<label>Temperature</label>
<description>Temperature reading from the device</description>
<category>Temperature</category>
<state readOnly="true" pattern="%.1f °C"/>
<state readOnly="true" pattern="%.1f %unit%"/>
<config-description>
<parameter name="channelNumber" type="integer" required="true">
<label>Channel Number</label>
<description>The physical channel number on the SBUS device</description>
<description>The physical channel number on the Sbus device</description>
</parameter>
<parameter name="unit" type="text">
<label>Temperature Unit</label>
<description>The unit to use for temperature readings (°C or °F)</description>
<options>
<option value="CELSIUS">Celsius</option>
<option value="FAHRENHEIT">Fahrenheit</option>
</options>
<default>CELSIUS</default>
</parameter>
</config-description>
</channel-type>
@ -152,28 +167,9 @@
<config-description>
<parameter name="channelNumber" type="integer" required="true">
<label>Channel Number</label>
<description>The physical channel number on the SBUS device</description>
<description>The physical channel number on the Sbus device</description>
</parameter>
</config-description>
</channel-type>
<!-- Channel Group Types (unused, but left in case you need them) -->
<channel-group-type id="switches">
<label>Switch Channels</label>
<description>Group of switch channels</description>
<category>Switch</category>
</channel-group-type>
<channel-group-type id="sensors">
<label>Temperature Sensors</label>
<description>Group of temperature sensors</description>
<category>Temperature</category>
</channel-group-type>
<channel-group-type id="colors">
<label>Color Channels</label>
<description>Group of RGBW color channels</description>
<category>ColorLight</category>
</channel-group-type>
</thing:thing-descriptions>

View File

@ -97,67 +97,67 @@
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-api</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf-lite</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-alts</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-grpclb</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-auth</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-context</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-xds</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-services</artifactId>
<version>1.60.1</version>
<version>1.53.0</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@ -48,8 +48,4 @@
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.modbus.sungrow/${project.version}</bundle>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.modbus.sunspec/${project.version}</bundle>
</feature>
<feature name="openhab-binding-sbus" description="S-Bus Binding" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.sbus/${project.version}</bundle>
</feature>
</features>

View File

@ -4,4 +4,4 @@ checkstyle.forbiddenPackageUsageCheck.forbiddenPackages=com.fazecast.jSerialComm
checkstyle.forbiddenPackageUsageCheck.exceptions=
checkstyle.requiredFilesCheck.files=pom.xml
checkstyle.karafAddonFeatureCheck.featureNameMappings=-transform-:-transformation-,-io-:-misc-
checkstyle.karafAddonFeatureCheck.excludeAddonPatterns=org.openhab.persistence.jdbc.*,org.openhab.binding.modbus.*,org.openhab.binding.sbus.*
checkstyle.karafAddonFeatureCheck.excludeAddonPatterns=org.openhab.persistence.jdbc.*,org.openhab.binding.modbus.*