[lutron] Add support for bridged RadioRA (classic) systems (#10302)
Signed-off-by: Bob Adair <bob.github@att.net>
This commit is contained in:
parent
1783017be4
commit
4b70da49db
bundles/org.openhab.binding.lutron
README.md
src/main
java/org/openhab/binding/lutron/internal/radiora
RS232Connection.javaRS232MessageParser.javaRadioRAConnection.javaRadioRAConnectionException.javaRadioRAFeedbackListener.java
config
handler
protocol
resources/OH-INF/thing
@ -794,7 +794,12 @@ end
|
||||
This binding integrates with the legacy Lutron RadioRA (Classic) lighting system.
|
||||
|
||||
This binding depends on RS232 communication.
|
||||
It has only been tested using the Chronos time module but the RS232 module should work as well.
|
||||
It has only been tested using the Chronos System Bridge and Timeclock (RA-SBT-CHR) module, but Lutron's RA-RS232 or RB-RS232 module should work as well.
|
||||
|
||||
Support has been added for bridged RadioRA systems.
|
||||
A system is considered “bridged” when a Chronos System Bridge and Timeclock is used to integrate two RadioRA Systems in a single residence.
|
||||
In a bridged system, the `system` parameter of each configured ra-dimmer, ra-switch, or ra-phantomButton thing should be set to indicate which RadioRA system it is a part of (i.e. 1 or 2).
|
||||
In a non-bridged system, these parameters should be left at their default of 0.
|
||||
|
||||
## Supported Things
|
||||
|
||||
@ -808,17 +813,20 @@ This binding currently supports the following thing types:
|
||||
| ra-phantomButton | Thing | Phantom Button to control multiple controls (Scenes) |
|
||||
|
||||
|
||||
## Thing Configurations
|
||||
## Thing Configuration Parameters
|
||||
|
||||
| Thing | Config | Description |
|
||||
|------------------|--------------|-----------------------------------------------------------------------|
|
||||
| ra-rs232 | portName | The serial port to use to communicate with Chronos or RS232 module |
|
||||
| | baud | (Optional) Baud Rate (defaults to 9600) |
|
||||
| ra-dimmer | zoneNumber | Assigned Zone Number within the Lutron RadioRA system |
|
||||
| | fadeOutSec | (Optional) Time in seconds dimmer should take when lowering the level |
|
||||
| | fadeInSec | (Optional) Time in seconds dimmer should take when lowering the level |
|
||||
| ra-switch | zoneNumber | Assigned Zone Number within the Lutron RadioRA system |
|
||||
| ra-phantomButton | buttonNumber | Phantom Button Number within the Lutron RadioRA system |
|
||||
| Thing | Parameter | Description |
|
||||
|------------------|--------------|------------------------------------------------------------------------|
|
||||
| ra-rs232 | portName | The serial port to use to communicate with Chronos or RS232 module |
|
||||
| | baud | (Optional) Baud Rate (defaults to 9600) |
|
||||
| ra-dimmer | zoneNumber | Assigned Zone Number within the Lutron RadioRA system |
|
||||
| | system | (Optional) System number (1 or 2) in a bridged system. Default=0 (n/a) |
|
||||
| | fadeOutSec | (Optional) Time in seconds dimmer should take when lowering the level |
|
||||
| | fadeInSec | (Optional) Time in seconds dimmer should take when lowering the level |
|
||||
| ra-switch | zoneNumber | Assigned Zone Number within the Lutron RadioRA system |
|
||||
| | system | (Optional) System number (1 or 2) in a bridged system. Default=0 (n/a) |
|
||||
| ra-phantomButton | buttonNumber | Phantom Button Number within the Lutron RadioRA system |
|
||||
| | system | (Optional) System number (1 or 2) in a bridged system. Default=0 (n/a) |
|
||||
|
||||
## Channels
|
||||
|
||||
|
@ -15,8 +15,11 @@ package org.openhab.binding.lutron.internal.radiora;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.TooManyListenersException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
|
||||
import org.openhab.core.io.transport.serial.PortInUseException;
|
||||
import org.openhab.core.io.transport.serial.SerialPort;
|
||||
@ -34,16 +37,17 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RS232Connection implements RadioRAConnection, SerialPortEventListener {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RS232Connection.class);
|
||||
|
||||
protected SerialPortManager serialPortManager;
|
||||
protected SerialPort serialPort;
|
||||
protected @Nullable SerialPort serialPort;
|
||||
|
||||
protected BufferedReader inputReader;
|
||||
protected @Nullable BufferedReader inputReader;
|
||||
|
||||
protected RadioRAFeedbackListener listener;
|
||||
protected @Nullable RadioRAFeedbackListener listener;
|
||||
protected RS232MessageParser parser = new RS232MessageParser();
|
||||
|
||||
public RS232Connection(SerialPortManager serialPortManager) {
|
||||
@ -59,7 +63,8 @@ public class RS232Connection implements RadioRAConnection, SerialPortEventListen
|
||||
}
|
||||
|
||||
try {
|
||||
serialPort = portIdentifier.open("openhab", 5000);
|
||||
SerialPort serialPort = portIdentifier.open("openhab", 5000);
|
||||
this.serialPort = serialPort;
|
||||
serialPort.notifyOnDataAvailable(true);
|
||||
serialPort.setSerialPortParams(baud, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||
serialPort.addEventListener(this);
|
||||
@ -78,8 +83,19 @@ public class RS232Connection implements RadioRAConnection, SerialPortEventListen
|
||||
@Override
|
||||
public void write(String command) {
|
||||
logger.debug("Writing to serial port: {}", command.toString());
|
||||
SerialPort serialPort = this.serialPort;
|
||||
|
||||
try {
|
||||
serialPort.getOutputStream().write(command.getBytes());
|
||||
if (serialPort != null) {
|
||||
OutputStream outputStream = serialPort.getOutputStream();
|
||||
if (outputStream != null) {
|
||||
outputStream.write(command.getBytes());
|
||||
} else {
|
||||
logger.debug("Cannot write to serial port. outputStream is null.");
|
||||
}
|
||||
} else {
|
||||
logger.debug("Cannot write to serial port. serialPort is null.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.debug("An error occurred writing to serial port", e);
|
||||
}
|
||||
@ -87,15 +103,19 @@ public class RS232Connection implements RadioRAConnection, SerialPortEventListen
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
serialPort.close();
|
||||
SerialPort serialPort = this.serialPort;
|
||||
if (serialPort != null) {
|
||||
serialPort.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialEvent(SerialPortEvent ev) {
|
||||
switch (ev.getEventType()) {
|
||||
case SerialPortEvent.DATA_AVAILABLE:
|
||||
BufferedReader inputReader = this.inputReader;
|
||||
try {
|
||||
if (!inputReader.ready()) {
|
||||
if (inputReader == null || !inputReader.ready()) {
|
||||
logger.debug("Serial Data Available but input reader not ready");
|
||||
return;
|
||||
}
|
||||
@ -106,7 +126,12 @@ public class RS232Connection implements RadioRAConnection, SerialPortEventListen
|
||||
|
||||
if (feedback != null) {
|
||||
logger.debug("Msg Parsed as {}", feedback.getClass().getName());
|
||||
listener.handleRadioRAFeedback(feedback);
|
||||
RadioRAFeedbackListener listener = this.listener;
|
||||
if (listener != null) {
|
||||
listener.handleRadioRAFeedback(feedback);
|
||||
} else {
|
||||
logger.debug("Cannot handle feedback message. Listener is null.");
|
||||
}
|
||||
}
|
||||
logger.debug("Finished handling feedback");
|
||||
} catch (IOException e) {
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.LEDMapFeedback;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.LocalZoneChangeFeedback;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
|
||||
@ -25,11 +27,12 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RS232MessageParser {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(RS232MessageParser.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(RS232MessageParser.class);
|
||||
|
||||
public RadioRAFeedback parse(String msg) {
|
||||
public @Nullable RadioRAFeedback parse(String msg) {
|
||||
String prefix = parsePrefix(msg);
|
||||
|
||||
switch (prefix) {
|
||||
|
@ -12,12 +12,15 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Interface to the RadioRA Classic system
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface RadioRAConnection {
|
||||
|
||||
public void open(String portName, int baud) throws RadioRAConnectionException;
|
||||
|
@ -12,12 +12,15 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Thrown when an attempt to open a RadioRA Connection fails.
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RadioRAConnectionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
|
||||
|
||||
/**
|
||||
@ -20,6 +21,7 @@ import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface RadioRAFeedbackListener {
|
||||
|
||||
void handleRadioRAFeedback(RadioRAFeedback feedback);
|
||||
|
@ -21,31 +21,20 @@ import java.math.BigDecimal;
|
||||
*
|
||||
*/
|
||||
public class DimmerConfig {
|
||||
private int zoneNumber;
|
||||
private BigDecimal fadeOutSec;
|
||||
private BigDecimal fadeInSec;
|
||||
public int zoneNumber;
|
||||
public int system = 0;
|
||||
public BigDecimal fadeOutSec;
|
||||
public BigDecimal fadeInSec;
|
||||
|
||||
public int getZoneNumber() {
|
||||
return zoneNumber;
|
||||
}
|
||||
|
||||
public void setZoneNumber(int zoneNumber) {
|
||||
this.zoneNumber = zoneNumber;
|
||||
}
|
||||
|
||||
public BigDecimal getFadeOutSec() {
|
||||
return fadeOutSec;
|
||||
}
|
||||
|
||||
public void setFadeOutSec(BigDecimal fadeOutSec) {
|
||||
this.fadeOutSec = fadeOutSec;
|
||||
}
|
||||
|
||||
public BigDecimal getFadeInSec() {
|
||||
return fadeInSec;
|
||||
}
|
||||
|
||||
public void setFadeInSec(BigDecimal fadeInSec) {
|
||||
this.fadeInSec = fadeInSec;
|
||||
}
|
||||
}
|
||||
|
@ -12,32 +12,21 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.config;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Configuration class for PhantomButton thing type.
|
||||
*
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PhantomButtonConfig {
|
||||
|
||||
private int buttonNumber;
|
||||
private BigDecimal fadeSec;
|
||||
public int buttonNumber;
|
||||
public int system = 0;
|
||||
|
||||
public int getButtonNumber() {
|
||||
return buttonNumber;
|
||||
}
|
||||
|
||||
public void setButtonNumber(int buttonNumber) {
|
||||
this.buttonNumber = buttonNumber;
|
||||
}
|
||||
|
||||
public BigDecimal getFadeSec() {
|
||||
return fadeSec;
|
||||
}
|
||||
|
||||
public void setFadeSec(BigDecimal fadeSec) {
|
||||
this.fadeSec = fadeSec;
|
||||
}
|
||||
}
|
||||
|
@ -12,39 +12,30 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Configuration class for RS232 thing type.
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RS232Config {
|
||||
|
||||
private String portName;
|
||||
private int baud = 9600;
|
||||
private int zoneMapQueryInterval = 60;
|
||||
public String portName = "";
|
||||
public int baud = 9600;
|
||||
public int zoneMapQueryInterval = 60;
|
||||
|
||||
public String getPortName() {
|
||||
return portName;
|
||||
}
|
||||
|
||||
public void setPortName(String portName) {
|
||||
this.portName = portName;
|
||||
}
|
||||
|
||||
public int getBaud() {
|
||||
return baud;
|
||||
}
|
||||
|
||||
public void setBaud(int baud) {
|
||||
this.baud = baud;
|
||||
}
|
||||
|
||||
public int getZoneMapQueryInterval() {
|
||||
return zoneMapQueryInterval;
|
||||
}
|
||||
|
||||
public void setZoneMapQueryInterval(int zoneMapQueryInterval) {
|
||||
this.zoneMapQueryInterval = zoneMapQueryInterval;
|
||||
}
|
||||
}
|
||||
|
@ -12,21 +12,21 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Configuration class for Switch thing type.
|
||||
*
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SwitchConfig {
|
||||
|
||||
private int zoneNumber;
|
||||
public int zoneNumber;
|
||||
public int system = 0;
|
||||
|
||||
public int getZoneNumber() {
|
||||
return zoneNumber;
|
||||
}
|
||||
|
||||
public void setZoneNumber(int zoneNumber) {
|
||||
this.zoneNumber = zoneNumber;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ package org.openhab.binding.lutron.internal.radiora.handler;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.lutron.internal.LutronBindingConstants;
|
||||
import org.openhab.binding.lutron.internal.radiora.config.DimmerConfig;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.LocalZoneChangeFeedback;
|
||||
@ -34,6 +35,7 @@ import org.openhab.core.types.Command;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class DimmerHandler extends LutronHandler {
|
||||
|
||||
/**
|
||||
@ -41,24 +43,33 @@ public class DimmerHandler extends LutronHandler {
|
||||
* to external dimmer changes since RadioRA protocol does not send dimmer
|
||||
* levels in their messages.
|
||||
*/
|
||||
private @NonNullByDefault({}) DimmerConfig config;
|
||||
private AtomicInteger lastKnownIntensity = new AtomicInteger(100);
|
||||
|
||||
private AtomicBoolean switchEnabled = new AtomicBoolean(false);
|
||||
|
||||
public DimmerHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(DimmerConfig.class);
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
DimmerConfig config = getConfigAs(DimmerConfig.class);
|
||||
RS232Handler bridgeHandler = getRS232Handler();
|
||||
if (bridgeHandler == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LutronBindingConstants.CHANNEL_LIGHTLEVEL.equals(channelUID.getId())) {
|
||||
if (command instanceof PercentType) {
|
||||
int intensity = ((PercentType) command).intValue();
|
||||
|
||||
SetDimmerLevelCommand cmd = new SetDimmerLevelCommand(config.getZoneNumber(), intensity);
|
||||
getRS232Handler().sendCommand(cmd);
|
||||
SetDimmerLevelCommand cmd = new SetDimmerLevelCommand(config.getZoneNumber(), intensity, config.system);
|
||||
bridgeHandler.sendCommand(cmd);
|
||||
|
||||
updateInternalState(intensity);
|
||||
}
|
||||
@ -66,11 +77,10 @@ public class DimmerHandler extends LutronHandler {
|
||||
if (command instanceof OnOffType) {
|
||||
OnOffType onOffCmd = (OnOffType) command;
|
||||
|
||||
SetSwitchLevelCommand cmd = new SetSwitchLevelCommand(config.getZoneNumber(), onOffCmd);
|
||||
getRS232Handler().sendCommand(cmd);
|
||||
SetSwitchLevelCommand cmd = new SetSwitchLevelCommand(config.getZoneNumber(), onOffCmd, config.system);
|
||||
bridgeHandler.sendCommand(cmd);
|
||||
|
||||
updateInternalState(onOffCmd);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,7 +95,10 @@ public class DimmerHandler extends LutronHandler {
|
||||
}
|
||||
|
||||
private void handleZoneMapFeedback(ZoneMapFeedback feedback) {
|
||||
char value = feedback.getZoneValue(getConfigAs(DimmerConfig.class).getZoneNumber());
|
||||
if (!systemsMatch(feedback.getSystem(), config.system)) {
|
||||
return;
|
||||
}
|
||||
char value = feedback.getZoneValue(config.getZoneNumber());
|
||||
if (value == '1') {
|
||||
turnDimmerOnToLastKnownIntensity();
|
||||
} else if (value == '0') {
|
||||
@ -94,7 +107,7 @@ public class DimmerHandler extends LutronHandler {
|
||||
}
|
||||
|
||||
private void handleLocalZoneChangeFeedback(LocalZoneChangeFeedback feedback) {
|
||||
if (feedback.getZoneNumber() == getConfigAs(DimmerConfig.class).getZoneNumber()) {
|
||||
if (systemsMatch(feedback.getSystem(), config.system) && feedback.getZoneNumber() == config.getZoneNumber()) {
|
||||
if (LocalZoneChangeFeedback.State.ON.equals(feedback.getState())) {
|
||||
turnDimmerOnToLastKnownIntensity();
|
||||
} else if (LocalZoneChangeFeedback.State.OFF.equals(feedback.getState())) {
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@ -26,13 +28,14 @@ import org.openhab.core.thing.binding.ThingHandler;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class LutronHandler extends BaseThingHandler {
|
||||
|
||||
public LutronHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
public RS232Handler getRS232Handler() {
|
||||
public @Nullable RS232Handler getRS232Handler() {
|
||||
Bridge bridge = getBridge();
|
||||
if (bridge == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED, "Unable to get bridge");
|
||||
@ -47,6 +50,13 @@ public abstract class LutronHandler extends BaseThingHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if system numbers match, meaning that either both are 2 or both are 1 or 0 (n/a).
|
||||
*/
|
||||
public static boolean systemsMatch(int a, int b) {
|
||||
return ((a == 2 && b == 2) || ((a == 0 || a == 1) && (b == 0 || b == 1)));
|
||||
}
|
||||
|
||||
public abstract void handleFeedback(RadioRAFeedback feedback);
|
||||
|
||||
@Override
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.lutron.internal.LutronBindingConstants;
|
||||
import org.openhab.binding.lutron.internal.radiora.config.PhantomButtonConfig;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.ButtonPressCommand;
|
||||
@ -28,20 +29,31 @@ import org.openhab.core.types.Command;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PhantomButtonHandler extends LutronHandler {
|
||||
|
||||
private @NonNullByDefault({}) PhantomButtonConfig config;
|
||||
|
||||
public PhantomButtonHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(PhantomButtonConfig.class);
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
RS232Handler bridgeHandler = getRS232Handler();
|
||||
if (channelUID.getId().equals(LutronBindingConstants.CHANNEL_SWITCH)) {
|
||||
if (command instanceof OnOffType) {
|
||||
ButtonPressCommand cmd = new ButtonPressCommand(
|
||||
getConfigAs(PhantomButtonConfig.class).getButtonNumber(),
|
||||
ButtonPressCommand.ButtonState.valueOf(command.toString()));
|
||||
getRS232Handler().sendCommand(cmd);
|
||||
ButtonPressCommand cmd = new ButtonPressCommand(config.getButtonNumber(),
|
||||
ButtonPressCommand.ButtonState.valueOf(command.toString()), config.system);
|
||||
if (bridgeHandler != null) {
|
||||
bridgeHandler.sendCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ package org.openhab.binding.lutron.internal.radiora.handler;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.lutron.internal.radiora.RS232Connection;
|
||||
import org.openhab.binding.lutron.internal.radiora.RadioRAConnection;
|
||||
import org.openhab.binding.lutron.internal.radiora.RadioRAConnectionException;
|
||||
@ -41,13 +43,14 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RS232Handler extends BaseBridgeHandler implements RadioRAFeedbackListener {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(RS232Handler.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(RS232Handler.class);
|
||||
|
||||
private RadioRAConnection connection;
|
||||
|
||||
private ScheduledFuture<?> zoneMapScheduledTask;
|
||||
private @Nullable ScheduledFuture<?> zoneMapScheduledTask;
|
||||
|
||||
public RS232Handler(Bridge bridge, SerialPortManager serialPortManager) {
|
||||
super(bridge);
|
||||
@ -58,6 +61,7 @@ public class RS232Handler extends BaseBridgeHandler implements RadioRAFeedbackLi
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
ScheduledFuture<?> zoneMapScheduledTask = this.zoneMapScheduledTask;
|
||||
if (zoneMapScheduledTask != null) {
|
||||
zoneMapScheduledTask.cancel(true);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.lutron.internal.LutronBindingConstants;
|
||||
import org.openhab.binding.lutron.internal.radiora.config.SwitchConfig;
|
||||
import org.openhab.binding.lutron.internal.radiora.protocol.LocalZoneChangeFeedback;
|
||||
@ -31,22 +32,33 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SwitchHandler extends LutronHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(SwitchHandler.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(SwitchHandler.class);
|
||||
private @NonNullByDefault({}) SwitchConfig config;
|
||||
|
||||
public SwitchHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(SwitchConfig.class);
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
RS232Handler bridgeHandler = getRS232Handler();
|
||||
if (LutronBindingConstants.CHANNEL_SWITCH.equals(channelUID.getId())) {
|
||||
if (command instanceof OnOffType) {
|
||||
SetSwitchLevelCommand cmd = new SetSwitchLevelCommand(getConfigAs(SwitchConfig.class).getZoneNumber(),
|
||||
(OnOffType) command);
|
||||
SetSwitchLevelCommand cmd = new SetSwitchLevelCommand(config.getZoneNumber(), (OnOffType) command,
|
||||
config.system);
|
||||
|
||||
getRS232Handler().sendCommand(cmd);
|
||||
if (bridgeHandler != null) {
|
||||
bridgeHandler.sendCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,7 +73,10 @@ public class SwitchHandler extends LutronHandler {
|
||||
}
|
||||
|
||||
private void handleZoneMapFeedback(ZoneMapFeedback feedback) {
|
||||
char value = feedback.getZoneValue(getConfigAs(SwitchConfig.class).getZoneNumber());
|
||||
if (!systemsMatch(feedback.getSystem(), config.system)) {
|
||||
return;
|
||||
}
|
||||
char value = feedback.getZoneValue(config.getZoneNumber());
|
||||
|
||||
if (value == '1') {
|
||||
updateState(LutronBindingConstants.CHANNEL_SWITCH, OnOffType.ON);
|
||||
@ -71,7 +86,7 @@ public class SwitchHandler extends LutronHandler {
|
||||
}
|
||||
|
||||
private void handleLocalZoneChangeFeedback(LocalZoneChangeFeedback feedback) {
|
||||
if (feedback.getZoneNumber() == getConfigAs(SwitchConfig.class).getZoneNumber()) {
|
||||
if (systemsMatch(feedback.getSystem(), config.system) && feedback.getZoneNumber() == config.getZoneNumber()) {
|
||||
if (LocalZoneChangeFeedback.State.CHG.equals(feedback.getState())) {
|
||||
logger.debug("Not Implemented Yet - CHG state received from Local Zone Change Feedback.");
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Button Press (BP) Command.
|
||||
* Trigger a Phantom Button Press on the RadioRA Serial Device.
|
||||
@ -22,6 +25,7 @@ import java.util.List;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ButtonPressCommand extends RadioRACommand {
|
||||
|
||||
public enum ButtonState {
|
||||
@ -32,11 +36,13 @@ public class ButtonPressCommand extends RadioRACommand {
|
||||
|
||||
private int buttonNumber; // 1 to 15, 16 ALL ON, 17 ALL OFF
|
||||
private ButtonState state; // ON/OFF/TOG
|
||||
private Integer fadeSec; // 0 to 240 (optional)
|
||||
private @Nullable Integer fadeSec; // 0 to 240 (optional)
|
||||
private int system; // 1 or 2, or 0 for none
|
||||
|
||||
public ButtonPressCommand(int buttonNumber, ButtonState state) {
|
||||
public ButtonPressCommand(int buttonNumber, ButtonState state, int system) {
|
||||
this.buttonNumber = buttonNumber;
|
||||
this.state = state;
|
||||
this.system = system;
|
||||
}
|
||||
|
||||
public void setFadeSeconds(int seconds) {
|
||||
@ -58,6 +64,10 @@ public class ButtonPressCommand extends RadioRACommand {
|
||||
args.add(String.valueOf(fadeSec));
|
||||
}
|
||||
|
||||
if (system == 1 || system == 2) {
|
||||
args.add("S" + String.valueOf(system));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Feedback (LMP) that gives the state of all phantom LEDs
|
||||
* <p>
|
||||
@ -34,6 +36,7 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LEDMapFeedback extends RadioRAFeedback {
|
||||
|
||||
private String bitmap; // 15 bit String of (0,1). 1 is ON, 0 is OFF
|
||||
|
@ -12,6 +12,10 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Feedback for when a device was changed locally (not through Master Control)
|
||||
* <p>
|
||||
@ -37,13 +41,22 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
* LZC,04,ON
|
||||
* </pre>
|
||||
*
|
||||
* In a bridged system, a system parameter S1 or S2 will be appended.
|
||||
*
|
||||
* <pre>
|
||||
* LZC,04,ON,S2
|
||||
* </pre>
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class LocalZoneChangeFeedback extends RadioRAFeedback {
|
||||
private final Logger logger = LoggerFactory.getLogger(LocalZoneChangeFeedback.class);
|
||||
|
||||
private int zoneNumber; // 1 to 32
|
||||
private State state; // ON, OFF, CHG
|
||||
private int system; // 1 or 2, or 0 for none
|
||||
|
||||
public enum State {
|
||||
ON,
|
||||
@ -56,6 +69,18 @@ public class LocalZoneChangeFeedback extends RadioRAFeedback {
|
||||
|
||||
zoneNumber = Integer.parseInt(params[1].trim());
|
||||
state = State.valueOf(params[2].trim().toUpperCase());
|
||||
|
||||
system = 0;
|
||||
if (params.length > 3) {
|
||||
String sysParam = params[3].trim().toUpperCase();
|
||||
if ("S1".equals(sysParam)) {
|
||||
system = 1;
|
||||
} else if ("S2".equals(sysParam)) {
|
||||
system = 2;
|
||||
} else {
|
||||
logger.debug("Invalid 3rd parameter {} in LZC message. Should be S1 or S2.", sysParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
@ -65,4 +90,8 @@ public class LocalZoneChangeFeedback extends RadioRAFeedback {
|
||||
public int getZoneNumber() {
|
||||
return zoneNumber;
|
||||
}
|
||||
|
||||
public int getSystem() {
|
||||
return system;
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,15 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Abstract base class for commands.
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class RadioRACommand {
|
||||
|
||||
protected static final String FIELD_SEPARATOR = ",";
|
||||
|
@ -12,12 +12,15 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Base class for Feedback from RadioRA
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RadioRAFeedback {
|
||||
|
||||
public String[] parse(String msg, int numParams) {
|
||||
|
@ -15,6 +15,9 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Set Dimmer Level (SDL)
|
||||
* Set an individual Dimmer’s light level.
|
||||
@ -22,15 +25,18 @@ import java.util.List;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SetDimmerLevelCommand extends RadioRACommand {
|
||||
|
||||
private int zoneNumber; // 1 to 32
|
||||
private int dimmerLevel; // 0 to 100
|
||||
private Integer fadeSec; // 0 to 240 (optional)
|
||||
private @Nullable Integer fadeSec; // 0 to 240 (optional)
|
||||
private int system; // 1 or 2, or 0 for none
|
||||
|
||||
public SetDimmerLevelCommand(int zoneNumber, int dimmerLevel) {
|
||||
public SetDimmerLevelCommand(int zoneNumber, int dimmerLevel, int system) {
|
||||
this.zoneNumber = zoneNumber;
|
||||
this.dimmerLevel = dimmerLevel;
|
||||
this.system = system;
|
||||
}
|
||||
|
||||
public void setFadeSeconds(int seconds) {
|
||||
@ -52,6 +58,10 @@ public class SetDimmerLevelCommand extends RadioRACommand {
|
||||
args.add(String.valueOf(fadeSec));
|
||||
}
|
||||
|
||||
if (system == 1 || system == 2) {
|
||||
args.add("S" + String.valueOf(system));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
|
||||
/**
|
||||
@ -24,15 +26,18 @@ import org.openhab.core.library.types.OnOffType;
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SetSwitchLevelCommand extends RadioRACommand {
|
||||
|
||||
private int zoneNumber; // 1 to 32
|
||||
private OnOffType state; // ON/OFF
|
||||
private Integer delaySec; // 0 to 240 (optional)
|
||||
private @Nullable Integer delaySec; // 0 to 240 (optional)
|
||||
private int system; // 1 or 2, or 0 for none
|
||||
|
||||
public SetSwitchLevelCommand(int zoneNumber, OnOffType state) {
|
||||
public SetSwitchLevelCommand(int zoneNumber, OnOffType state, int system) {
|
||||
this.zoneNumber = zoneNumber;
|
||||
this.state = state;
|
||||
this.system = system;
|
||||
}
|
||||
|
||||
public void setDelaySeconds(int seconds) {
|
||||
@ -54,6 +59,10 @@ public class SetSwitchLevelCommand extends RadioRACommand {
|
||||
args.add(String.valueOf(delaySec));
|
||||
}
|
||||
|
||||
if (system == 1 || system == 2) {
|
||||
args.add("S" + String.valueOf(system));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,10 @@
|
||||
*/
|
||||
package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Feedback that gives the state of all zones
|
||||
* <p>
|
||||
@ -26,22 +30,39 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
* <b>Example:</b>
|
||||
* <p>
|
||||
* Zones 2 and 9 are ON, all others are OFF, and Zones 31 and 32 are unassigned.
|
||||
* In a bridged system, a system parameter S1 or S2 will be appended.
|
||||
*
|
||||
* <pre>
|
||||
* ZMP,010000001000000000000000000000XX
|
||||
* ZMP,00100000010000000000000000000000,S2
|
||||
* </pre>
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ZoneMapFeedback extends RadioRAFeedback {
|
||||
private final Logger logger = LoggerFactory.getLogger(ZoneMapFeedback.class);
|
||||
|
||||
private String zoneStates; // 32 bit String of (0,1,X)
|
||||
private int system; // 1 or 2, or 0 for none
|
||||
|
||||
public ZoneMapFeedback(String msg) {
|
||||
String[] params = parse(msg, 1);
|
||||
|
||||
zoneStates = params[1];
|
||||
|
||||
system = 0;
|
||||
if (params.length > 2) {
|
||||
String sysParam = params[2].trim().toUpperCase();
|
||||
if ("S1".equals(sysParam)) {
|
||||
system = 1;
|
||||
} else if ("S2".equals(sysParam)) {
|
||||
system = 2;
|
||||
} else {
|
||||
logger.debug("Invalid 2nd parameter {} in ZMP message. Should be S1 or S2.", sysParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getZoneStates() {
|
||||
@ -55,4 +76,8 @@ public class ZoneMapFeedback extends RadioRAFeedback {
|
||||
|
||||
return zoneStates.charAt(zone - 1);
|
||||
}
|
||||
|
||||
public int getSystem() {
|
||||
return system;
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,15 @@ package org.openhab.binding.lutron.internal.radiora.protocol;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Requests an updated ZoneMap.
|
||||
*
|
||||
* @author Jeff Lauterbach - Initial Contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ZoneMapInquiryCommand extends RadioRACommand {
|
||||
|
||||
@Override
|
||||
|
@ -1203,6 +1203,11 @@
|
||||
<label>Zone Number</label>
|
||||
<description>Assigned Zone Number within the Lutron RadioRA system.</description>
|
||||
</parameter>
|
||||
<parameter name="system" type="integer" min="0" max="2" required="false">
|
||||
<label>System Number</label>
|
||||
<description>System number (bridged systems only). Set to 1 or 2. 0 = NA (default).</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="fadeOutSec" type="integer" required="false">
|
||||
<label>Fade Out (sec)</label>
|
||||
<description>Time in seconds dimmer should take when lowering the level</description>
|
||||
@ -1231,6 +1236,11 @@
|
||||
<label>Zone Number</label>
|
||||
<description>Assigned Zone Number within the Lutron RadioRA system.</description>
|
||||
</parameter>
|
||||
<parameter name="system" type="integer" min="0" max="2" required="false">
|
||||
<label>System Number</label>
|
||||
<description>System number (bridged systems only). Set to 1 or 2. 0 = NA (default).</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
@ -1250,6 +1260,11 @@
|
||||
<label>Phantom Button Number</label>
|
||||
<description>Phantom Button Number within the Lutron RadioRA system.</description>
|
||||
</parameter>
|
||||
<parameter name="system" type="integer" min="0" max="2" required="false">
|
||||
<label>System Number</label>
|
||||
<description>System number (bridged systems only). Set to 1 or 2. 0 = NA (default).</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user