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
| ra-phantomButton | Thing | Phantom Button to control multiple controls (Scenes) |
-## Thing Configurations
-
-| 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 Configuration Parameters
+
+| 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
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;
* @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) {
}
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);
@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);
}
@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;
}
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) {
*/
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;
* @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) {
*/
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;
*/
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;
*/
package org.openhab.binding.lutron.internal.radiora;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.lutron.internal.radiora.protocol.RadioRAFeedback;
/**
* @author Jeff Lauterbach - Initial Contribution
*
*/
+@NonNullByDefault
public interface RadioRAFeedbackListener {
void handleRadioRAFeedback(RadioRAFeedback feedback);
*
*/
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;
- }
}
*/
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;
- }
}
*/
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;
- }
}
*/
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;
- }
}
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;
* @author Jeff Lauterbach - Initial Contribution
*
*/
+@NonNullByDefault
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);
}
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);
-
}
}
}
}
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') {
}
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())) {
*/
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;
* @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");
}
}
+ /**
+ * 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
*/
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;
* @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);
+ }
}
}
}
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;
*
* @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);
@Override
public void dispose() {
+ ScheduledFuture<?> zoneMapScheduledTask = this.zoneMapScheduledTask;
if (zoneMapScheduledTask != null) {
zoneMapScheduledTask.cancel(true);
}
*/
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;
* @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);
+ }
}
}
}
}
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);
}
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.");
}
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.
* @author Jeff Lauterbach - Initial Contribution
*
*/
+@NonNullByDefault
public class ButtonPressCommand extends RadioRACommand {
public enum ButtonState {
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) {
args.add(String.valueOf(fadeSec));
}
+ if (system == 1 || system == 2) {
+ args.add("S" + String.valueOf(system));
+ }
+
return args;
}
}
*/
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>
* @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
*/
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>
* 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,
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() {
public int getZoneNumber() {
return zoneNumber;
}
+
+ public int getSystem() {
+ return system;
+ }
}
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 = ",";
*/
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) {
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.
* @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) {
args.add(String.valueOf(fadeSec));
}
+ if (system == 1 || system == 2) {
+ args.add("S" + String.valueOf(system));
+ }
+
return args;
}
}
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;
/**
* @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) {
args.add(String.valueOf(delaySec));
}
+ if (system == 1 || system == 2) {
+ args.add("S" + String.valueOf(system));
+ }
+
return args;
}
}
*/
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>
* <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() {
return zoneStates.charAt(zone - 1);
}
+
+ public int getSystem() {
+ return system;
+ }
}
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
<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>
<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>
<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>