[insteon] remove all @SuppressWarnings("null") (#8937)
Signed-off-by: Rob Nielsen <rob.nielsen@yahoo.com>
This commit is contained in:
parent
b423f93b1f
commit
0722bd71f5
|
@ -106,15 +106,14 @@ import org.xml.sax.SAXException;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings({ "null", "unused" })
|
|
||||||
public class InsteonBinding {
|
public class InsteonBinding {
|
||||||
private static final int DEAD_DEVICE_COUNT = 10;
|
private static final int DEAD_DEVICE_COUNT = 10;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(InsteonBinding.class);
|
private final Logger logger = LoggerFactory.getLogger(InsteonBinding.class);
|
||||||
|
|
||||||
private Driver driver;
|
private Driver driver;
|
||||||
private ConcurrentHashMap<InsteonAddress, InsteonDevice> devices = new ConcurrentHashMap<>();
|
private Map<InsteonAddress, InsteonDevice> devices = new ConcurrentHashMap<>();
|
||||||
private ConcurrentHashMap<String, InsteonChannelConfiguration> bindingConfigs = new ConcurrentHashMap<>();
|
private Map<String, InsteonChannelConfiguration> bindingConfigs = new ConcurrentHashMap<>();
|
||||||
private PortListener portListener = new PortListener();
|
private PortListener portListener = new PortListener();
|
||||||
private int devicePollIntervalMilliseconds = 300000;
|
private int devicePollIntervalMilliseconds = 300000;
|
||||||
private int deadDeviceTimeout = -1;
|
private int deadDeviceTimeout = -1;
|
||||||
|
@ -123,8 +122,8 @@ public class InsteonBinding {
|
||||||
private int x10HouseUnit = -1;
|
private int x10HouseUnit = -1;
|
||||||
private InsteonNetworkHandler handler;
|
private InsteonNetworkHandler handler;
|
||||||
|
|
||||||
public InsteonBinding(InsteonNetworkHandler handler, @Nullable InsteonNetworkConfiguration config,
|
public InsteonBinding(InsteonNetworkHandler handler, InsteonNetworkConfiguration config,
|
||||||
@Nullable SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
|
SerialPortManager serialPortManager, ScheduledExecutorService scheduler) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
|
|
||||||
String port = config.getPort();
|
String port = config.getPort();
|
||||||
|
@ -142,8 +141,13 @@ public class InsteonBinding {
|
||||||
String additionalDevices = config.getAdditionalDevices();
|
String additionalDevices = config.getAdditionalDevices();
|
||||||
if (additionalDevices != null) {
|
if (additionalDevices != null) {
|
||||||
try {
|
try {
|
||||||
DeviceTypeLoader.instance().loadDeviceTypesXML(additionalDevices);
|
DeviceTypeLoader instance = DeviceTypeLoader.instance();
|
||||||
logger.debug("read additional device definitions from {}", additionalDevices);
|
if (instance != null) {
|
||||||
|
instance.loadDeviceTypesXML(additionalDevices);
|
||||||
|
logger.debug("read additional device definitions from {}", additionalDevices);
|
||||||
|
} else {
|
||||||
|
logger.warn("device type loader instance is null");
|
||||||
|
}
|
||||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||||
logger.warn("error reading additional devices from {}", additionalDevices, e);
|
logger.warn("error reading additional devices from {}", additionalDevices, e);
|
||||||
}
|
}
|
||||||
|
@ -201,6 +205,10 @@ public class InsteonBinding {
|
||||||
|
|
||||||
InsteonAddress address = bindingConfig.getAddress();
|
InsteonAddress address = bindingConfig.getAddress();
|
||||||
InsteonDevice dev = getDevice(address);
|
InsteonDevice dev = getDevice(address);
|
||||||
|
if (dev == null) {
|
||||||
|
logger.warn("device for address {} is null", address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
@Nullable
|
@Nullable
|
||||||
DeviceFeature f = dev.getFeature(bindingConfig.getFeature());
|
DeviceFeature f = dev.getFeature(bindingConfig.getFeature());
|
||||||
if (f == null || f.isFeatureGroup()) {
|
if (f == null || f.isFeatureGroup()) {
|
||||||
|
@ -209,7 +217,7 @@ public class InsteonBinding {
|
||||||
Collections.sort(names);
|
Collections.sort(names);
|
||||||
for (String name : names) {
|
for (String name : names) {
|
||||||
DeviceFeature feature = dev.getFeature(name);
|
DeviceFeature feature = dev.getFeature(name);
|
||||||
if (!feature.isFeatureGroup()) {
|
if (feature != null && !feature.isFeatureGroup()) {
|
||||||
if (buf.length() > 0) {
|
if (buf.length() > 0) {
|
||||||
buf.append(", ");
|
buf.append(", ");
|
||||||
}
|
}
|
||||||
|
@ -249,8 +257,16 @@ public class InsteonBinding {
|
||||||
handler.updateState(channelUID, state);
|
handler.updateState(channelUID, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsteonDevice makeNewDevice(InsteonAddress addr, String productKey, Map<String, Object> deviceConfigMap) {
|
public @Nullable InsteonDevice makeNewDevice(InsteonAddress addr, String productKey,
|
||||||
DeviceType dt = DeviceTypeLoader.instance().getDeviceType(productKey);
|
Map<String, Object> deviceConfigMap) {
|
||||||
|
DeviceTypeLoader instance = DeviceTypeLoader.instance();
|
||||||
|
if (instance == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
DeviceType dt = instance.getDeviceType(productKey);
|
||||||
|
if (dt == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
InsteonDevice dev = InsteonDevice.makeDevice(dt);
|
InsteonDevice dev = InsteonDevice.makeDevice(dt);
|
||||||
dev.setAddress(addr);
|
dev.setAddress(addr);
|
||||||
dev.setProductKey(productKey);
|
dev.setProductKey(productKey);
|
||||||
|
@ -361,10 +377,16 @@ public class InsteonBinding {
|
||||||
|
|
||||||
private String getLinkInfo(Map<InsteonAddress, ModemDBEntry> dbes, InsteonAddress a, boolean prefix) {
|
private String getLinkInfo(Map<InsteonAddress, ModemDBEntry> dbes, InsteonAddress a, boolean prefix) {
|
||||||
ModemDBEntry dbe = dbes.get(a);
|
ModemDBEntry dbe = dbes.get(a);
|
||||||
|
if (dbe == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
List<Byte> controls = dbe.getControls();
|
List<Byte> controls = dbe.getControls();
|
||||||
List<Byte> responds = dbe.getRespondsTo();
|
List<Byte> responds = dbe.getRespondsTo();
|
||||||
|
|
||||||
Port port = dbe.getPort();
|
Port port = dbe.getPort();
|
||||||
|
if (port == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
String deviceName = port.getDeviceName();
|
String deviceName = port.getDeviceName();
|
||||||
String s = deviceName.startsWith("/hub") ? "hub" : "plm";
|
String s = deviceName.startsWith("/hub") ? "hub" : "plm";
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
@ -433,7 +455,6 @@ public class InsteonBinding {
|
||||||
* Handles messages that come in from the ports.
|
* Handles messages that come in from the ports.
|
||||||
* Will only process one message at a time.
|
* Will only process one message at a time.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
private class PortListener implements MsgListener, DriverListener {
|
private class PortListener implements MsgListener, DriverListener {
|
||||||
@Override
|
@Override
|
||||||
public void msg(Msg msg) {
|
public void msg(Msg msg) {
|
||||||
|
|
|
@ -182,6 +182,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
|
||||||
public void msg(Msg msg) {
|
public void msg(Msg msg) {
|
||||||
if (monitorAllDevices || monitoredAddresses.contains(msg.getAddr("fromAddress"))) {
|
if (monitorAllDevices || monitoredAddresses.contains(msg.getAddr("fromAddress"))) {
|
||||||
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
|
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
|
||||||
|
Console console = this.console;
|
||||||
if (console != null) {
|
if (console != null) {
|
||||||
console.println(date + " " + msg.toString());
|
console.println(date + " " + msg.toString());
|
||||||
}
|
}
|
||||||
|
@ -218,7 +219,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
|
||||||
|
|
||||||
private void startMonitoring(Console console, String addr) {
|
private void startMonitoring(Console console, String addr) {
|
||||||
if (addr.equalsIgnoreCase("all")) {
|
if (addr.equalsIgnoreCase("all")) {
|
||||||
if (monitorAllDevices != true) {
|
if (!monitorAllDevices) {
|
||||||
monitorAllDevices = true;
|
monitorAllDevices = true;
|
||||||
monitoredAddresses.clear();
|
monitoredAddresses.clear();
|
||||||
console.println("Started monitoring all devices.");
|
console.println("Started monitoring all devices.");
|
||||||
|
@ -240,7 +241,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitoring == false) {
|
if (!monitoring) {
|
||||||
getInsteonBinding().getDriver().addMsgListener(this);
|
getInsteonBinding().getDriver().addMsgListener(this);
|
||||||
|
|
||||||
this.console = console;
|
this.console = console;
|
||||||
|
@ -249,7 +250,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopMonitoring(Console console, String addr) {
|
private void stopMonitoring(Console console, String addr) {
|
||||||
if (monitoring == false) {
|
if (!monitoring) {
|
||||||
console.println("Not mointoring any devices.");
|
console.println("Not mointoring any devices.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +278,7 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitorAllDevices == false && monitoredAddresses.isEmpty()) {
|
if (!monitorAllDevices && monitoredAddresses.isEmpty()) {
|
||||||
getInsteonBinding().getDriver().removeListener(this);
|
getInsteonBinding().getDriver().removeListener(this);
|
||||||
this.console = null;
|
this.console = null;
|
||||||
monitoring = false;
|
monitoring = false;
|
||||||
|
@ -335,18 +336,12 @@ public class InsteonCommandExtension extends AbstractConsoleCommandExtension imp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("null")
|
|
||||||
private InsteonBinding getInsteonBinding() {
|
private InsteonBinding getInsteonBinding() {
|
||||||
|
InsteonNetworkHandler handler = this.handler;
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
throw new IllegalArgumentException("No Insteon network bridge configured.");
|
throw new IllegalArgumentException("No Insteon network bridge configured.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
return handler.getInsteonBinding();
|
||||||
InsteonBinding insteonBinding = handler.getInsteonBinding();
|
|
||||||
if (insteonBinding == null) {
|
|
||||||
throw new IllegalArgumentException("Insteon binding is null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return insteonBinding;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,9 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public abstract class CommandHandler {
|
public abstract class CommandHandler {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CommandHandler.class);
|
private static final Logger logger = LoggerFactory.getLogger(CommandHandler.class);
|
||||||
DeviceFeature feature; // related DeviceFeature
|
DeviceFeature feature; // related DeviceFeature
|
||||||
@Nullable
|
|
||||||
Map<String, String> parameters = new HashMap<>();
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,22 +112,24 @@ public abstract class CommandHandler {
|
||||||
|
|
||||||
protected int getMaxLightLevel(InsteonChannelConfiguration conf, int defaultLevel) {
|
protected int getMaxLightLevel(InsteonChannelConfiguration conf, int defaultLevel) {
|
||||||
Map<String, String> params = conf.getParameters();
|
Map<String, String> params = conf.getParameters();
|
||||||
if (conf.getFeature().contains("dimmer") && params.containsKey("dimmermax")) {
|
if (conf.getFeature().contains("dimmer")) {
|
||||||
String item = conf.getChannelName();
|
|
||||||
String dimmerMax = params.get("dimmermax");
|
String dimmerMax = params.get("dimmermax");
|
||||||
try {
|
if (dimmerMax != null) {
|
||||||
int i = Integer.parseInt(dimmerMax);
|
String item = conf.getChannelName();
|
||||||
if (i > 1 && i <= 99) {
|
try {
|
||||||
int level = (int) Math.ceil((i * 255.0) / 100); // round up
|
int i = Integer.parseInt(dimmerMax);
|
||||||
if (level < defaultLevel) {
|
if (i > 1 && i <= 99) {
|
||||||
logger.debug("item {}: using dimmermax value of {}", item, dimmerMax);
|
int level = (int) Math.ceil((i * 255.0) / 100); // round up
|
||||||
return level;
|
if (level < defaultLevel) {
|
||||||
|
logger.debug("item {}: using dimmermax value of {}", item, dimmerMax);
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("item {}: dimmermax must be between 1-99 inclusive: {}", item, dimmerMax);
|
||||||
}
|
}
|
||||||
} else {
|
} catch (NumberFormatException e) {
|
||||||
logger.warn("item {}: dimmermax must be between 1-99 inclusive: {}", item, dimmerMax);
|
logger.warn("item {}: invalid int value for dimmermax: {}", item, dimmerMax);
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
logger.warn("item {}: invalid int value for dimmermax: {}", item, dimmerMax);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,6 @@ public abstract class CommandHandler {
|
||||||
return iv;
|
return iv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class WarnCommandHandler extends CommandHandler {
|
public static class WarnCommandHandler extends CommandHandler {
|
||||||
WarnCommandHandler(DeviceFeature f) {
|
WarnCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -169,7 +168,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class NoOpCommandHandler extends CommandHandler {
|
public static class NoOpCommandHandler extends CommandHandler {
|
||||||
NoOpCommandHandler(DeviceFeature f) {
|
NoOpCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -181,7 +179,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LightOnOffCommandHandler extends CommandHandler {
|
public static class LightOnOffCommandHandler extends CommandHandler {
|
||||||
LightOnOffCommandHandler(DeviceFeature f) {
|
LightOnOffCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -227,7 +224,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class FastOnOffCommandHandler extends CommandHandler {
|
public static class FastOnOffCommandHandler extends CommandHandler {
|
||||||
FastOnOffCommandHandler(DeviceFeature f) {
|
FastOnOffCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -256,7 +252,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class RampOnOffCommandHandler extends RampCommandHandler {
|
public static class RampOnOffCommandHandler extends RampCommandHandler {
|
||||||
RampOnOffCommandHandler(DeviceFeature f) {
|
RampOnOffCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -296,7 +291,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class ManualChangeCommandHandler extends CommandHandler {
|
public static class ManualChangeCommandHandler extends CommandHandler {
|
||||||
ManualChangeCommandHandler(DeviceFeature f) {
|
ManualChangeCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -327,7 +321,6 @@ public abstract class CommandHandler {
|
||||||
/**
|
/**
|
||||||
* Sends ALLLink broadcast commands to group
|
* Sends ALLLink broadcast commands to group
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class GroupBroadcastCommandHandler extends CommandHandler {
|
public static class GroupBroadcastCommandHandler extends CommandHandler {
|
||||||
GroupBroadcastCommandHandler(DeviceFeature f) {
|
GroupBroadcastCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -358,7 +351,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LEDOnOffCommandHandler extends CommandHandler {
|
public static class LEDOnOffCommandHandler extends CommandHandler {
|
||||||
LEDOnOffCommandHandler(DeviceFeature f) {
|
LEDOnOffCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -386,7 +378,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10OnOffCommandHandler extends CommandHandler {
|
public static class X10OnOffCommandHandler extends CommandHandler {
|
||||||
X10OnOffCommandHandler(DeviceFeature f) {
|
X10OnOffCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -415,7 +406,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10PercentCommandHandler extends CommandHandler {
|
public static class X10PercentCommandHandler extends CommandHandler {
|
||||||
X10PercentCommandHandler(DeviceFeature f) {
|
X10PercentCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -454,7 +444,6 @@ public abstract class CommandHandler {
|
||||||
private final int[] x10CodeForLevel = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
|
private final int[] x10CodeForLevel = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10IncreaseDecreaseCommandHandler extends CommandHandler {
|
public static class X10IncreaseDecreaseCommandHandler extends CommandHandler {
|
||||||
X10IncreaseDecreaseCommandHandler(DeviceFeature f) {
|
X10IncreaseDecreaseCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -484,7 +473,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class IOLincOnOffCommandHandler extends CommandHandler {
|
public static class IOLincOnOffCommandHandler extends CommandHandler {
|
||||||
IOLincOnOffCommandHandler(DeviceFeature f) {
|
IOLincOnOffCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -526,7 +514,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class IncreaseDecreaseCommandHandler extends CommandHandler {
|
public static class IncreaseDecreaseCommandHandler extends CommandHandler {
|
||||||
IncreaseDecreaseCommandHandler(DeviceFeature f) {
|
IncreaseDecreaseCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -552,7 +539,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class PercentHandler extends CommandHandler {
|
public static class PercentHandler extends CommandHandler {
|
||||||
PercentHandler(DeviceFeature f) {
|
PercentHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -582,7 +568,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
private abstract static class RampCommandHandler extends CommandHandler {
|
private abstract static class RampCommandHandler extends CommandHandler {
|
||||||
private static double[] halfRateRampTimes = new double[] { 0.1, 0.3, 2, 6.5, 19, 23.5, 28, 32, 38.5, 47, 90,
|
private static double[] halfRateRampTimes = new double[] { 0.1, 0.3, 2, 6.5, 19, 23.5, 28, 32, 38.5, 47, 90,
|
||||||
150, 210, 270, 360, 480 };
|
150, 210, 270, 360, 480 };
|
||||||
|
@ -647,7 +632,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class RampPercentHandler extends RampCommandHandler {
|
public static class RampPercentHandler extends RampCommandHandler {
|
||||||
|
|
||||||
RampPercentHandler(DeviceFeature f) {
|
RampPercentHandler(DeviceFeature f) {
|
||||||
|
@ -681,7 +665,6 @@ public abstract class CommandHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class PowerMeterCommandHandler extends CommandHandler {
|
public static class PowerMeterCommandHandler extends CommandHandler {
|
||||||
PowerMeterCommandHandler(DeviceFeature f) {
|
PowerMeterCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -728,7 +711,6 @@ public abstract class CommandHandler {
|
||||||
* First used for setting thermostat parameters.
|
* First used for setting thermostat parameters.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class NumberCommandHandler extends CommandHandler {
|
public static class NumberCommandHandler extends CommandHandler {
|
||||||
NumberCommandHandler(DeviceFeature f) {
|
NumberCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -792,7 +774,6 @@ public abstract class CommandHandler {
|
||||||
/**
|
/**
|
||||||
* Handler to set the thermostat system mode
|
* Handler to set the thermostat system mode
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class ThermostatSystemModeCommandHandler extends NumberCommandHandler {
|
public static class ThermostatSystemModeCommandHandler extends NumberCommandHandler {
|
||||||
ThermostatSystemModeCommandHandler(DeviceFeature f) {
|
ThermostatSystemModeCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -821,7 +802,6 @@ public abstract class CommandHandler {
|
||||||
/**
|
/**
|
||||||
* Handler to set the thermostat fan mode
|
* Handler to set the thermostat fan mode
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class ThermostatFanModeCommandHandler extends NumberCommandHandler {
|
public static class ThermostatFanModeCommandHandler extends NumberCommandHandler {
|
||||||
ThermostatFanModeCommandHandler(DeviceFeature f) {
|
ThermostatFanModeCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -844,7 +824,6 @@ public abstract class CommandHandler {
|
||||||
/**
|
/**
|
||||||
* Handler to set the fanlinc fan mode
|
* Handler to set the fanlinc fan mode
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class FanLincFanCommandHandler extends NumberCommandHandler {
|
public static class FanLincFanCommandHandler extends NumberCommandHandler {
|
||||||
FanLincFanCommandHandler(DeviceFeature f) {
|
FanLincFanCommandHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -883,6 +862,7 @@ public abstract class CommandHandler {
|
||||||
Class<?> c = Class.forName(cname);
|
Class<?> c = Class.forName(cname);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends T> dc = (Class<? extends T>) c;
|
Class<? extends T> dc = (Class<? extends T>) c;
|
||||||
|
@Nullable
|
||||||
T ch = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
T ch = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
||||||
ch.setParameters(params);
|
ch.setParameters(params);
|
||||||
return ch;
|
return ch;
|
||||||
|
|
|
@ -62,7 +62,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class DeviceFeature {
|
public class DeviceFeature {
|
||||||
public static enum QueryStatus {
|
public static enum QueryStatus {
|
||||||
NEVER_QUERIED,
|
NEVER_QUERIED,
|
||||||
|
@ -80,8 +79,8 @@ public class DeviceFeature {
|
||||||
private int directAckTimeout = 6000;
|
private int directAckTimeout = 6000;
|
||||||
private QueryStatus queryStatus = QueryStatus.NEVER_QUERIED;
|
private QueryStatus queryStatus = QueryStatus.NEVER_QUERIED;
|
||||||
|
|
||||||
private @Nullable MessageHandler defaultMsgHandler = new MessageHandler.DefaultMsgHandler(this);
|
private MessageHandler defaultMsgHandler = new MessageHandler.DefaultMsgHandler(this);
|
||||||
private @Nullable CommandHandler defaultCommandHandler = new CommandHandler.WarnCommandHandler(this);
|
private CommandHandler defaultCommandHandler = new CommandHandler.WarnCommandHandler(this);
|
||||||
private @Nullable PollHandler pollHandler = null;
|
private @Nullable PollHandler pollHandler = null;
|
||||||
private @Nullable MessageDispatcher dispatcher = null;
|
private @Nullable MessageDispatcher dispatcher = null;
|
||||||
|
|
||||||
|
@ -135,7 +134,7 @@ public class DeviceFeature {
|
||||||
return directAckTimeout;
|
return directAckTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable MessageHandler getDefaultMsgHandler() {
|
public MessageHandler getDefaultMsgHandler() {
|
||||||
return defaultMsgHandler;
|
return defaultMsgHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,11 +163,11 @@ public class DeviceFeature {
|
||||||
dispatcher = md;
|
dispatcher = md;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultCommandHandler(@Nullable CommandHandler ch) {
|
public void setDefaultCommandHandler(CommandHandler ch) {
|
||||||
defaultCommandHandler = ch;
|
defaultCommandHandler = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultMsgHandler(@Nullable MessageHandler mh) {
|
public void setDefaultMsgHandler(MessageHandler mh) {
|
||||||
defaultMsgHandler = mh;
|
defaultMsgHandler = mh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,11 +263,12 @@ public class DeviceFeature {
|
||||||
* @return true if dispatch successful
|
* @return true if dispatch successful
|
||||||
*/
|
*/
|
||||||
public boolean handleMessage(Msg msg) {
|
public boolean handleMessage(Msg msg) {
|
||||||
|
MessageDispatcher dispatcher = this.dispatcher;
|
||||||
if (dispatcher == null) {
|
if (dispatcher == null) {
|
||||||
logger.warn("{} no dispatcher for msg {}", name, msg);
|
logger.warn("{} no dispatcher for msg {}", name, msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (dispatcher.dispatch(msg));
|
return dispatcher.dispatch(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,9 +280,11 @@ public class DeviceFeature {
|
||||||
public void handleCommand(InsteonChannelConfiguration c, Command cmd) {
|
public void handleCommand(InsteonChannelConfiguration c, Command cmd) {
|
||||||
Class<? extends Command> key = cmd.getClass();
|
Class<? extends Command> key = cmd.getClass();
|
||||||
CommandHandler h = commandHandlers.containsKey(key) ? commandHandlers.get(key) : defaultCommandHandler;
|
CommandHandler h = commandHandlers.containsKey(key) ? commandHandlers.get(key) : defaultCommandHandler;
|
||||||
logger.trace("{} uses {} to handle command {} for {}", getName(), h.getClass().getSimpleName(),
|
if (h != null) {
|
||||||
key.getSimpleName(), getDevice().getAddress());
|
logger.trace("{} uses {} to handle command {} for {}", getName(), h.getClass().getSimpleName(),
|
||||||
h.handleCommand(c, cmd, getDevice());
|
key.getSimpleName(), getDevice().getAddress());
|
||||||
|
h.handleCommand(c, cmd, getDevice());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -291,6 +293,7 @@ public class DeviceFeature {
|
||||||
* @return the poll message
|
* @return the poll message
|
||||||
*/
|
*/
|
||||||
public @Nullable Msg makePollMsg() {
|
public @Nullable Msg makePollMsg() {
|
||||||
|
PollHandler pollHandler = this.pollHandler;
|
||||||
if (pollHandler == null) {
|
if (pollHandler == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -387,8 +390,9 @@ public class DeviceFeature {
|
||||||
public static DeviceFeature makeDeviceFeature(String s) {
|
public static DeviceFeature makeDeviceFeature(String s) {
|
||||||
DeviceFeature f = null;
|
DeviceFeature f = null;
|
||||||
synchronized (features) {
|
synchronized (features) {
|
||||||
if (features.containsKey(s)) {
|
FeatureTemplate ft = features.get(s);
|
||||||
f = features.get(s).build();
|
if (ft != null) {
|
||||||
|
f = ft.build();
|
||||||
} else {
|
} else {
|
||||||
logger.warn("unimplemented feature requested: {}", s);
|
logger.warn("unimplemented feature requested: {}", s);
|
||||||
}
|
}
|
||||||
|
@ -436,6 +440,8 @@ public class DeviceFeature {
|
||||||
static {
|
static {
|
||||||
// read features from xml file and store them in a map
|
// read features from xml file and store them in a map
|
||||||
InputStream input = DeviceFeature.class.getResourceAsStream("/device_features.xml");
|
InputStream input = DeviceFeature.class.getResourceAsStream("/device_features.xml");
|
||||||
readFeatureTemplates(input);
|
if (input != null) {
|
||||||
|
readFeatureTemplates(input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ package org.openhab.binding.insteon.internal.device;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
@ -26,13 +27,12 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class DeviceType {
|
public class DeviceType {
|
||||||
private String productKey;
|
private String productKey;
|
||||||
private String model = "";
|
private String model = "";
|
||||||
private String description = "";
|
private String description = "";
|
||||||
private HashMap<String, String> features = new HashMap<>();
|
private Map<String, String> features = new HashMap<>();
|
||||||
private HashMap<String, FeatureGroup> featureGroups = new HashMap<>();
|
private Map<String, FeatureGroup> featureGroups = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -48,7 +48,7 @@ public class DeviceType {
|
||||||
*
|
*
|
||||||
* @return all features that this device type supports
|
* @return all features that this device type supports
|
||||||
*/
|
*/
|
||||||
public HashMap<String, String> getFeatures() {
|
public Map<String, String> getFeatures() {
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public class DeviceType {
|
||||||
*
|
*
|
||||||
* @return all feature groups of this device type
|
* @return all feature groups of this device type
|
||||||
*/
|
*/
|
||||||
public HashMap<String, FeatureGroup> getFeatureGroups() {
|
public Map<String, FeatureGroup> getFeatureGroups() {
|
||||||
return featureGroups;
|
return featureGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,6 @@ public class DeviceType {
|
||||||
*
|
*
|
||||||
* @author Bernd Pfrommer - Initial contribution
|
* @author Bernd Pfrommer - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class FeatureGroup {
|
public static class FeatureGroup {
|
||||||
private String name;
|
private String name;
|
||||||
private String type;
|
private String type;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
@ -42,11 +43,10 @@ import org.xml.sax.SAXException;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class DeviceTypeLoader {
|
public class DeviceTypeLoader {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DeviceTypeLoader.class);
|
private static final Logger logger = LoggerFactory.getLogger(DeviceTypeLoader.class);
|
||||||
private HashMap<String, DeviceType> deviceTypes = new HashMap<>();
|
private Map<String, DeviceType> deviceTypes = new HashMap<>();
|
||||||
private @Nullable static DeviceTypeLoader deviceTypeLoader = null;
|
private static DeviceTypeLoader deviceTypeLoader = new DeviceTypeLoader();
|
||||||
|
|
||||||
private DeviceTypeLoader() {
|
private DeviceTypeLoader() {
|
||||||
} // private so nobody can call it
|
} // private so nobody can call it
|
||||||
|
@ -66,7 +66,7 @@ public class DeviceTypeLoader {
|
||||||
*
|
*
|
||||||
* @return currently known device types
|
* @return currently known device types
|
||||||
*/
|
*/
|
||||||
public HashMap<String, DeviceType> getDeviceTypes() {
|
public Map<String, DeviceType> getDeviceTypes() {
|
||||||
return (deviceTypes);
|
return (deviceTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,20 +202,23 @@ public class DeviceTypeLoader {
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static synchronized DeviceTypeLoader instance() {
|
public static synchronized DeviceTypeLoader instance() {
|
||||||
if (deviceTypeLoader == null) {
|
if (deviceTypeLoader.getDeviceTypes().isEmpty()) {
|
||||||
deviceTypeLoader = new DeviceTypeLoader();
|
|
||||||
InputStream input = DeviceTypeLoader.class.getResourceAsStream("/device_types.xml");
|
InputStream input = DeviceTypeLoader.class.getResourceAsStream("/device_types.xml");
|
||||||
try {
|
if (input != null) {
|
||||||
deviceTypeLoader.loadDeviceTypesXML(input);
|
try {
|
||||||
} catch (ParserConfigurationException e) {
|
deviceTypeLoader.loadDeviceTypesXML(input);
|
||||||
logger.warn("parser config error when reading device types xml file: ", e);
|
} catch (ParserConfigurationException e) {
|
||||||
} catch (SAXException e) {
|
logger.warn("parser config error when reading device types xml file: ", e);
|
||||||
logger.warn("SAX exception when reading device types xml file: ", e);
|
} catch (SAXException e) {
|
||||||
} catch (IOException e) {
|
logger.warn("SAX exception when reading device types xml file: ", e);
|
||||||
logger.warn("I/O exception when reading device types xml file: ", e);
|
} catch (IOException e) {
|
||||||
|
logger.warn("I/O exception when reading device types xml file: ", e);
|
||||||
|
}
|
||||||
|
logger.debug("loaded {} devices: ", deviceTypeLoader.getDeviceTypes().size());
|
||||||
|
deviceTypeLoader.logDeviceTypes();
|
||||||
|
} else {
|
||||||
|
logger.warn("unable to get device types xml file as a resource");
|
||||||
}
|
}
|
||||||
logger.debug("loaded {} devices: ", deviceTypeLoader.getDeviceTypes().size());
|
|
||||||
deviceTypeLoader.logDeviceTypes();
|
|
||||||
}
|
}
|
||||||
return deviceTypeLoader;
|
return deviceTypeLoader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
package org.openhab.binding.insteon.internal.device;
|
package org.openhab.binding.insteon.internal.device;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
@ -28,7 +29,6 @@ import org.openhab.core.types.Command;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class FeatureTemplate {
|
public class FeatureTemplate {
|
||||||
private String name;
|
private String name;
|
||||||
private String timeout;
|
private String timeout;
|
||||||
|
@ -37,8 +37,8 @@ public class FeatureTemplate {
|
||||||
private @Nullable HandlerEntry pollHandler = null;
|
private @Nullable HandlerEntry pollHandler = null;
|
||||||
private @Nullable HandlerEntry defaultMsgHandler = null;
|
private @Nullable HandlerEntry defaultMsgHandler = null;
|
||||||
private @Nullable HandlerEntry defaultCmdHandler = null;
|
private @Nullable HandlerEntry defaultCmdHandler = null;
|
||||||
private HashMap<Integer, HandlerEntry> messageHandlers = new HashMap<>();
|
private Map<Integer, HandlerEntry> messageHandlers = new HashMap<>();
|
||||||
private HashMap<Class<? extends Command>, HandlerEntry> commandHandlers = new HashMap<>();
|
private Map<Class<? extends Command>, HandlerEntry> commandHandlers = new HashMap<>();
|
||||||
|
|
||||||
public FeatureTemplate(String name, boolean isStatus, String timeout) {
|
public FeatureTemplate(String name, boolean isStatus, String timeout) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -80,7 +80,7 @@ public class FeatureTemplate {
|
||||||
*
|
*
|
||||||
* @return a Hashmap from Integer to String representing the command codes and the associated message handlers
|
* @return a Hashmap from Integer to String representing the command codes and the associated message handlers
|
||||||
*/
|
*/
|
||||||
public HashMap<Integer, HandlerEntry> getMessageHandlers() {
|
public Map<Integer, HandlerEntry> getMessageHandlers() {
|
||||||
return messageHandlers;
|
return messageHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ public class FeatureTemplate {
|
||||||
* @see #getMessageHandlers()
|
* @see #getMessageHandlers()
|
||||||
* @return a HashMap from Command Classes to CommandHandler names
|
* @return a HashMap from Command Classes to CommandHandler names
|
||||||
*/
|
*/
|
||||||
public HashMap<Class<? extends Command>, HandlerEntry> getCommandHandlers() {
|
public Map<Class<? extends Command>, HandlerEntry> getCommandHandlers() {
|
||||||
return commandHandlers;
|
return commandHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,19 +141,29 @@ public class FeatureTemplate {
|
||||||
DeviceFeature f = new DeviceFeature(name);
|
DeviceFeature f = new DeviceFeature(name);
|
||||||
f.setStatusFeature(isStatus);
|
f.setStatusFeature(isStatus);
|
||||||
f.setTimeout(timeout);
|
f.setTimeout(timeout);
|
||||||
|
HandlerEntry dispatcher = this.dispatcher;
|
||||||
if (dispatcher != null) {
|
if (dispatcher != null) {
|
||||||
f.setMessageDispatcher(MessageDispatcher.makeHandler(dispatcher.getName(), dispatcher.getParams(), f));
|
f.setMessageDispatcher(MessageDispatcher.makeHandler(dispatcher.getName(), dispatcher.getParams(), f));
|
||||||
}
|
}
|
||||||
|
HandlerEntry pollHandler = this.pollHandler;
|
||||||
if (pollHandler != null) {
|
if (pollHandler != null) {
|
||||||
f.setPollHandler(PollHandler.makeHandler(pollHandler, f));
|
f.setPollHandler(PollHandler.makeHandler(pollHandler, f));
|
||||||
}
|
}
|
||||||
|
HandlerEntry defaultCmdHandler = this.defaultCmdHandler;
|
||||||
if (defaultCmdHandler != null) {
|
if (defaultCmdHandler != null) {
|
||||||
f.setDefaultCommandHandler(
|
CommandHandler h = CommandHandler.makeHandler(defaultCmdHandler.getName(), defaultCmdHandler.getParams(),
|
||||||
CommandHandler.makeHandler(defaultCmdHandler.getName(), defaultCmdHandler.getParams(), f));
|
f);
|
||||||
|
if (h != null) {
|
||||||
|
f.setDefaultCommandHandler(h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
HandlerEntry defaultMsgHandler = this.defaultMsgHandler;
|
||||||
if (defaultMsgHandler != null) {
|
if (defaultMsgHandler != null) {
|
||||||
f.setDefaultMsgHandler(
|
MessageHandler h = MessageHandler.makeHandler(defaultMsgHandler.getName(), defaultMsgHandler.getParams(),
|
||||||
MessageHandler.makeHandler(defaultMsgHandler.getName(), defaultMsgHandler.getParams(), f));
|
f);
|
||||||
|
if (h != null) {
|
||||||
|
f.setDefaultMsgHandler(h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (Entry<Integer, HandlerEntry> mH : messageHandlers.entrySet()) {
|
for (Entry<Integer, HandlerEntry> mH : messageHandlers.entrySet()) {
|
||||||
f.addMessageHandler(mH.getKey(),
|
f.addMessageHandler(mH.getKey(),
|
||||||
|
|
|
@ -46,7 +46,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class InsteonDevice {
|
public class InsteonDevice {
|
||||||
private final Logger logger = LoggerFactory.getLogger(InsteonDevice.class);
|
private final Logger logger = LoggerFactory.getLogger(InsteonDevice.class);
|
||||||
|
|
||||||
|
@ -134,6 +133,7 @@ public class InsteonDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasProductKey(String key) {
|
public boolean hasProductKey(String key) {
|
||||||
|
String productKey = this.productKey;
|
||||||
return productKey != null && productKey.equals(key);
|
return productKey != null && productKey.equals(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,12 @@ public class InsteonDevice {
|
||||||
mrequestQueue.add(e);
|
mrequestQueue.add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RequestQueueManager.instance().addQueue(this, now + delay);
|
RequestQueueManager instance = RequestQueueManager.instance();
|
||||||
|
if (instance != null) {
|
||||||
|
instance.addQueue(this, now + delay);
|
||||||
|
} else {
|
||||||
|
logger.warn("request queue manager is null");
|
||||||
|
}
|
||||||
|
|
||||||
if (!l.isEmpty()) {
|
if (!l.isEmpty()) {
|
||||||
lastTimePolled = now;
|
lastTimePolled = now;
|
||||||
|
@ -440,6 +445,7 @@ public class InsteonDevice {
|
||||||
if (mrequestQueue.isEmpty()) {
|
if (mrequestQueue.isEmpty()) {
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
DeviceFeature featureQueried = this.featureQueried;
|
||||||
if (featureQueried != null) {
|
if (featureQueried != null) {
|
||||||
// A feature has been queried, but
|
// A feature has been queried, but
|
||||||
// the response has not been digested yet.
|
// the response has not been digested yet.
|
||||||
|
@ -453,6 +459,9 @@ public class InsteonDevice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QEntry qe = mrequestQueue.poll(); // take it off the queue!
|
QEntry qe = mrequestQueue.poll(); // take it off the queue!
|
||||||
|
if (qe == null) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
if (!qe.getMsg().isBroadcast()) {
|
if (!qe.getMsg().isBroadcast()) {
|
||||||
logger.debug("qe taken off direct: {} {}", qe.getFeature(), qe.getMsg());
|
logger.debug("qe taken off direct: {} {}", qe.getFeature(), qe.getMsg());
|
||||||
lastQueryTime = timeNow;
|
lastQueryTime = timeNow;
|
||||||
|
@ -505,14 +514,22 @@ public class InsteonDevice {
|
||||||
m.setQuietTime(QUIET_TIME_DIRECT_MESSAGE);
|
m.setQuietTime(QUIET_TIME_DIRECT_MESSAGE);
|
||||||
}
|
}
|
||||||
logger.trace("enqueing direct message with delay {}", delay);
|
logger.trace("enqueing direct message with delay {}", delay);
|
||||||
RequestQueueManager.instance().addQueue(this, now + delay);
|
RequestQueueManager instance = RequestQueueManager.instance();
|
||||||
|
if (instance != null) {
|
||||||
|
instance.addQueue(this, now + delay);
|
||||||
|
} else {
|
||||||
|
logger.warn("request queue manger instance is null");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMessage(Msg m) throws IOException {
|
private void writeMessage(Msg m) throws IOException {
|
||||||
driver.writeMessage(m);
|
Driver driver = this.driver;
|
||||||
|
if (driver != null) {
|
||||||
|
driver.writeMessage(m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void instantiateFeatures(@Nullable DeviceType dt) {
|
private void instantiateFeatures(DeviceType dt) {
|
||||||
for (Entry<String, String> fe : dt.getFeatures().entrySet()) {
|
for (Entry<String, String> fe : dt.getFeatures().entrySet()) {
|
||||||
DeviceFeature f = DeviceFeature.makeDeviceFeature(fe.getValue());
|
DeviceFeature f = DeviceFeature.makeDeviceFeature(fe.getValue());
|
||||||
if (f == null) {
|
if (f == null) {
|
||||||
|
@ -596,7 +613,7 @@ public class InsteonDevice {
|
||||||
* @param dt device type after which to model the device
|
* @param dt device type after which to model the device
|
||||||
* @return newly created device
|
* @return newly created device
|
||||||
*/
|
*/
|
||||||
public static InsteonDevice makeDevice(@Nullable DeviceType dt) {
|
public static InsteonDevice makeDevice(DeviceType dt) {
|
||||||
InsteonDevice dev = new InsteonDevice();
|
InsteonDevice dev = new InsteonDevice();
|
||||||
dev.instantiateFeatures(dt);
|
dev.instantiateFeatures(dt);
|
||||||
return dev;
|
return dev;
|
||||||
|
@ -607,7 +624,6 @@ public class InsteonDevice {
|
||||||
*
|
*
|
||||||
* @author Bernd Pfrommer - Initial contribution
|
* @author Bernd Pfrommer - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class QEntry implements Comparable<QEntry> {
|
public static class QEntry implements Comparable<QEntry> {
|
||||||
private DeviceFeature feature;
|
private DeviceFeature feature;
|
||||||
private Msg msg;
|
private Msg msg;
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public abstract class MessageDispatcher {
|
public abstract class MessageDispatcher {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MessageDispatcher.class);
|
private static final Logger logger = LoggerFactory.getLogger(MessageDispatcher.class);
|
||||||
|
|
||||||
|
@ -128,7 +127,6 @@ public abstract class MessageDispatcher {
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class DefaultDispatcher extends MessageDispatcher {
|
public static class DefaultDispatcher extends MessageDispatcher {
|
||||||
DefaultDispatcher(DeviceFeature f) {
|
DefaultDispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -194,7 +192,6 @@ public abstract class MessageDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class DefaultGroupDispatcher extends MessageDispatcher {
|
public static class DefaultGroupDispatcher extends MessageDispatcher {
|
||||||
DefaultGroupDispatcher(DeviceFeature f) {
|
DefaultGroupDispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -263,7 +260,6 @@ public abstract class MessageDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class PollGroupDispatcher extends MessageDispatcher {
|
public static class PollGroupDispatcher extends MessageDispatcher {
|
||||||
PollGroupDispatcher(DeviceFeature f) {
|
PollGroupDispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -290,7 +286,6 @@ public abstract class MessageDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class SimpleDispatcher extends MessageDispatcher {
|
public static class SimpleDispatcher extends MessageDispatcher {
|
||||||
SimpleDispatcher(DeviceFeature f) {
|
SimpleDispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -328,7 +323,6 @@ public abstract class MessageDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10Dispatcher extends MessageDispatcher {
|
public static class X10Dispatcher extends MessageDispatcher {
|
||||||
X10Dispatcher(DeviceFeature f) {
|
X10Dispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -355,7 +349,6 @@ public abstract class MessageDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class PassThroughDispatcher extends MessageDispatcher {
|
public static class PassThroughDispatcher extends MessageDispatcher {
|
||||||
PassThroughDispatcher(DeviceFeature f) {
|
PassThroughDispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -376,7 +369,6 @@ public abstract class MessageDispatcher {
|
||||||
/**
|
/**
|
||||||
* Drop all incoming messages silently
|
* Drop all incoming messages silently
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class NoOpDispatcher extends MessageDispatcher {
|
public static class NoOpDispatcher extends MessageDispatcher {
|
||||||
NoOpDispatcher(DeviceFeature f) {
|
NoOpDispatcher(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -404,6 +396,7 @@ public abstract class MessageDispatcher {
|
||||||
Class<?> c = Class.forName(cname);
|
Class<?> c = Class.forName(cname);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends T> dc = (Class<? extends T>) c;
|
Class<? extends T> dc = (Class<? extends T>) c;
|
||||||
|
@Nullable
|
||||||
T ch = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
T ch = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
||||||
ch.setParameters(params);
|
ch.setParameters(params);
|
||||||
return ch;
|
return ch;
|
||||||
|
|
|
@ -50,7 +50,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public abstract class MessageHandler {
|
public abstract class MessageHandler {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);
|
private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);
|
||||||
|
|
||||||
|
@ -147,7 +146,8 @@ public abstract class MessageHandler {
|
||||||
* @return value of parameter (or default if not found)
|
* @return value of parameter (or default if not found)
|
||||||
*/
|
*/
|
||||||
protected @Nullable String getStringParameter(String key, @Nullable String def) {
|
protected @Nullable String getStringParameter(String key, @Nullable String def) {
|
||||||
return (parameters.get(key) == null ? def : parameters.get(key));
|
String str = parameters.get(key);
|
||||||
|
return str != null ? str : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -334,7 +334,6 @@ public abstract class MessageHandler {
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class DefaultMsgHandler extends MessageHandler {
|
public static class DefaultMsgHandler extends MessageHandler {
|
||||||
DefaultMsgHandler(DeviceFeature p) {
|
DefaultMsgHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -346,7 +345,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class NoOpMsgHandler extends MessageHandler {
|
public static class NoOpMsgHandler extends MessageHandler {
|
||||||
NoOpMsgHandler(DeviceFeature p) {
|
NoOpMsgHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -358,7 +356,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LightOnDimmerHandler extends MessageHandler {
|
public static class LightOnDimmerHandler extends MessageHandler {
|
||||||
LightOnDimmerHandler(DeviceFeature p) {
|
LightOnDimmerHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -388,7 +385,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LightOffDimmerHandler extends MessageHandler {
|
public static class LightOffDimmerHandler extends MessageHandler {
|
||||||
LightOffDimmerHandler(DeviceFeature p) {
|
LightOffDimmerHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -404,7 +400,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LightOnSwitchHandler extends MessageHandler {
|
public static class LightOnSwitchHandler extends MessageHandler {
|
||||||
LightOnSwitchHandler(DeviceFeature p) {
|
LightOnSwitchHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -422,7 +417,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LightOffSwitchHandler extends MessageHandler {
|
public static class LightOffSwitchHandler extends MessageHandler {
|
||||||
LightOffSwitchHandler(DeviceFeature p) {
|
LightOffSwitchHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -445,7 +439,6 @@ public abstract class MessageHandler {
|
||||||
* handler and the command handler will need to be extended to support
|
* handler and the command handler will need to be extended to support
|
||||||
* those devices.
|
* those devices.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class RampDimmerHandler extends MessageHandler {
|
public static class RampDimmerHandler extends MessageHandler {
|
||||||
private int onCmd;
|
private int onCmd;
|
||||||
private int offCmd;
|
private int offCmd;
|
||||||
|
@ -505,7 +498,6 @@ public abstract class MessageHandler {
|
||||||
* else if command2 == 0x00 then the light has been turned off
|
* else if command2 == 0x00 then the light has been turned off
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class SwitchRequestReplyHandler extends MessageHandler {
|
public static class SwitchRequestReplyHandler extends MessageHandler {
|
||||||
SwitchRequestReplyHandler(DeviceFeature p) {
|
SwitchRequestReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -573,7 +565,6 @@ public abstract class MessageHandler {
|
||||||
* Handles Dimmer replies to status requests.
|
* Handles Dimmer replies to status requests.
|
||||||
* In the dimmers case the command2 byte represents the light level from 0-255
|
* In the dimmers case the command2 byte represents the light level from 0-255
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class DimmerRequestReplyHandler extends MessageHandler {
|
public static class DimmerRequestReplyHandler extends MessageHandler {
|
||||||
DimmerRequestReplyHandler(DeviceFeature p) {
|
DimmerRequestReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -609,7 +600,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class DimmerStopManualChangeHandler extends MessageHandler {
|
public static class DimmerStopManualChangeHandler extends MessageHandler {
|
||||||
DimmerStopManualChangeHandler(DeviceFeature p) {
|
DimmerStopManualChangeHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -631,7 +621,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class StartManualChangeHandler extends MessageHandler {
|
public static class StartManualChangeHandler extends MessageHandler {
|
||||||
StartManualChangeHandler(DeviceFeature p) {
|
StartManualChangeHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -658,7 +647,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class StopManualChangeHandler extends MessageHandler {
|
public static class StopManualChangeHandler extends MessageHandler {
|
||||||
StopManualChangeHandler(DeviceFeature p) {
|
StopManualChangeHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -678,7 +666,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class InfoRequestReplyHandler extends MessageHandler {
|
public static class InfoRequestReplyHandler extends MessageHandler {
|
||||||
InfoRequestReplyHandler(DeviceFeature p) {
|
InfoRequestReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -714,7 +701,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class MotionSensorDataReplyHandler extends MessageHandler {
|
public static class MotionSensorDataReplyHandler extends MessageHandler {
|
||||||
MotionSensorDataReplyHandler(DeviceFeature p) {
|
MotionSensorDataReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -780,7 +766,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class MotionSensor2AlternateHeartbeatHandler extends MessageHandler {
|
public static class MotionSensor2AlternateHeartbeatHandler extends MessageHandler {
|
||||||
MotionSensor2AlternateHeartbeatHandler(DeviceFeature p) {
|
MotionSensor2AlternateHeartbeatHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -792,6 +777,10 @@ public abstract class MessageHandler {
|
||||||
try {
|
try {
|
||||||
// group 0x0B (11) - alternate heartbeat group
|
// group 0x0B (11) - alternate heartbeat group
|
||||||
InsteonAddress toAddr = msg.getAddr("toAddress");
|
InsteonAddress toAddr = msg.getAddr("toAddress");
|
||||||
|
if (toAddr == null) {
|
||||||
|
logger.warn("toAddr is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int batteryLevel = toAddr.getHighByte() & 0xff;
|
int batteryLevel = toAddr.getHighByte() & 0xff;
|
||||||
int lightLevel = toAddr.getMiddleByte() & 0xff;
|
int lightLevel = toAddr.getMiddleByte() & 0xff;
|
||||||
int temperatureLevel = msg.getByte("command2") & 0xff;
|
int temperatureLevel = msg.getByte("command2") & 0xff;
|
||||||
|
@ -823,7 +812,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class HiddenDoorSensorDataReplyHandler extends MessageHandler {
|
public static class HiddenDoorSensorDataReplyHandler extends MessageHandler {
|
||||||
HiddenDoorSensorDataReplyHandler(DeviceFeature p) {
|
HiddenDoorSensorDataReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -859,7 +847,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class PowerMeterUpdateHandler extends MessageHandler {
|
public static class PowerMeterUpdateHandler extends MessageHandler {
|
||||||
PowerMeterUpdateHandler(DeviceFeature p) {
|
PowerMeterUpdateHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -899,7 +886,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class PowerMeterResetHandler extends MessageHandler {
|
public static class PowerMeterResetHandler extends MessageHandler {
|
||||||
PowerMeterResetHandler(DeviceFeature p) {
|
PowerMeterResetHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -918,7 +904,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class LastTimeHandler extends MessageHandler {
|
public static class LastTimeHandler extends MessageHandler {
|
||||||
LastTimeHandler(DeviceFeature p) {
|
LastTimeHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -930,7 +915,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class ContactRequestReplyHandler extends MessageHandler {
|
public static class ContactRequestReplyHandler extends MessageHandler {
|
||||||
ContactRequestReplyHandler(DeviceFeature p) {
|
ContactRequestReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -955,7 +939,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class ClosedContactHandler extends MessageHandler {
|
public static class ClosedContactHandler extends MessageHandler {
|
||||||
ClosedContactHandler(DeviceFeature p) {
|
ClosedContactHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -967,7 +950,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class OpenedContactHandler extends MessageHandler {
|
public static class OpenedContactHandler extends MessageHandler {
|
||||||
OpenedContactHandler(DeviceFeature p) {
|
OpenedContactHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -979,7 +961,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class OpenedOrClosedContactHandler extends MessageHandler {
|
public static class OpenedOrClosedContactHandler extends MessageHandler {
|
||||||
OpenedOrClosedContactHandler(DeviceFeature p) {
|
OpenedOrClosedContactHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1020,7 +1001,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class ClosedSleepingContactHandler extends MessageHandler {
|
public static class ClosedSleepingContactHandler extends MessageHandler {
|
||||||
ClosedSleepingContactHandler(DeviceFeature p) {
|
ClosedSleepingContactHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1039,7 +1019,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class OpenedSleepingContactHandler extends MessageHandler {
|
public static class OpenedSleepingContactHandler extends MessageHandler {
|
||||||
OpenedSleepingContactHandler(DeviceFeature p) {
|
OpenedSleepingContactHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1066,7 +1045,6 @@ public abstract class MessageHandler {
|
||||||
* Then connect this handler to the ACK, such that the device will be polled, and
|
* Then connect this handler to the ACK, such that the device will be polled, and
|
||||||
* the settings updated.
|
* the settings updated.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class TriggerPollMsgHandler extends MessageHandler {
|
public static class TriggerPollMsgHandler extends MessageHandler {
|
||||||
TriggerPollMsgHandler(DeviceFeature p) {
|
TriggerPollMsgHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1081,7 +1059,6 @@ public abstract class MessageHandler {
|
||||||
/**
|
/**
|
||||||
* Flexible handler to extract numerical data from messages.
|
* Flexible handler to extract numerical data from messages.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class NumberMsgHandler extends MessageHandler {
|
public static class NumberMsgHandler extends MessageHandler {
|
||||||
NumberMsgHandler(DeviceFeature p) {
|
NumberMsgHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1120,8 +1097,8 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int extractValue(Msg msg, int group) throws FieldException {
|
private int extractValue(Msg msg, int group) throws FieldException {
|
||||||
String lowByte = getStringParameter("low_byte", "");
|
String lowByte = getStringParameter("low_byte", null);
|
||||||
if (lowByte.equals("")) {
|
if (lowByte == null) {
|
||||||
logger.warn("{} handler misconfigured, missing low_byte!", nm());
|
logger.warn("{} handler misconfigured, missing low_byte!", nm());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1131,8 +1108,8 @@ public abstract class MessageHandler {
|
||||||
} else {
|
} else {
|
||||||
value = msg.getByte(lowByte) & 0xFF;
|
value = msg.getByte(lowByte) & 0xFF;
|
||||||
}
|
}
|
||||||
String highByte = getStringParameter("high_byte", "");
|
String highByte = getStringParameter("high_byte", null);
|
||||||
if (!highByte.equals("")) {
|
if (highByte != null) {
|
||||||
value |= (msg.getByte(highByte) & 0xFF) << 8;
|
value |= (msg.getByte(highByte) & 0xFF) << 8;
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
@ -1143,7 +1120,6 @@ public abstract class MessageHandler {
|
||||||
* Convert system mode field to number 0...4. Insteon has two different
|
* Convert system mode field to number 0...4. Insteon has two different
|
||||||
* conventions for numbering, we use the one of the status update messages
|
* conventions for numbering, we use the one of the status update messages
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class ThermostatSystemModeMsgHandler extends NumberMsgHandler {
|
public static class ThermostatSystemModeMsgHandler extends NumberMsgHandler {
|
||||||
ThermostatSystemModeMsgHandler(DeviceFeature p) {
|
ThermostatSystemModeMsgHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1172,7 +1148,6 @@ public abstract class MessageHandler {
|
||||||
/**
|
/**
|
||||||
* Handle reply to system mode change command
|
* Handle reply to system mode change command
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class ThermostatSystemModeReplyHandler extends NumberMsgHandler {
|
public static class ThermostatSystemModeReplyHandler extends NumberMsgHandler {
|
||||||
ThermostatSystemModeReplyHandler(DeviceFeature p) {
|
ThermostatSystemModeReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1201,7 +1176,6 @@ public abstract class MessageHandler {
|
||||||
/**
|
/**
|
||||||
* Handle reply to fan mode change command
|
* Handle reply to fan mode change command
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class ThermostatFanModeReplyHandler extends NumberMsgHandler {
|
public static class ThermostatFanModeReplyHandler extends NumberMsgHandler {
|
||||||
ThermostatFanModeReplyHandler(DeviceFeature p) {
|
ThermostatFanModeReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1224,7 +1198,6 @@ public abstract class MessageHandler {
|
||||||
/**
|
/**
|
||||||
* Handle reply to fanlinc fan speed change command
|
* Handle reply to fanlinc fan speed change command
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class FanLincFanReplyHandler extends NumberMsgHandler {
|
public static class FanLincFanReplyHandler extends NumberMsgHandler {
|
||||||
FanLincFanReplyHandler(DeviceFeature p) {
|
FanLincFanReplyHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1252,7 +1225,6 @@ public abstract class MessageHandler {
|
||||||
* Process X10 messages that are generated when another controller
|
* Process X10 messages that are generated when another controller
|
||||||
* changes the state of an X10 device.
|
* changes the state of an X10 device.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10OnHandler extends MessageHandler {
|
public static class X10OnHandler extends MessageHandler {
|
||||||
X10OnHandler(DeviceFeature p) {
|
X10OnHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1266,7 +1238,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10OffHandler extends MessageHandler {
|
public static class X10OffHandler extends MessageHandler {
|
||||||
X10OffHandler(DeviceFeature p) {
|
X10OffHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1280,7 +1251,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10BrightHandler extends MessageHandler {
|
public static class X10BrightHandler extends MessageHandler {
|
||||||
X10BrightHandler(DeviceFeature p) {
|
X10BrightHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1293,7 +1263,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10DimHandler extends MessageHandler {
|
public static class X10DimHandler extends MessageHandler {
|
||||||
X10DimHandler(DeviceFeature p) {
|
X10DimHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1306,7 +1275,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10OpenHandler extends MessageHandler {
|
public static class X10OpenHandler extends MessageHandler {
|
||||||
X10OpenHandler(DeviceFeature p) {
|
X10OpenHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1320,7 +1288,6 @@ public abstract class MessageHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class X10ClosedHandler extends MessageHandler {
|
public static class X10ClosedHandler extends MessageHandler {
|
||||||
X10ClosedHandler(DeviceFeature p) {
|
X10ClosedHandler(DeviceFeature p) {
|
||||||
super(p);
|
super(p);
|
||||||
|
@ -1349,6 +1316,7 @@ public abstract class MessageHandler {
|
||||||
Class<?> c = Class.forName(cname);
|
Class<?> c = Class.forName(cname);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends T> dc = (Class<? extends T>) c;
|
Class<? extends T> dc = (Class<? extends T>) c;
|
||||||
|
@Nullable
|
||||||
T mh = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
T mh = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
||||||
mh.setParameters(params);
|
mh.setParameters(params);
|
||||||
return mh;
|
return mh;
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class ModemDBBuilder implements MsgListener {
|
public class ModemDBBuilder implements MsgListener {
|
||||||
private static final int MESSAGE_TIMEOUT = 30000;
|
private static final int MESSAGE_TIMEOUT = 30000;
|
||||||
|
|
||||||
|
@ -65,8 +64,11 @@ public class ModemDBBuilder implements MsgListener {
|
||||||
job = scheduler.scheduleWithFixedDelay(() -> {
|
job = scheduler.scheduleWithFixedDelay(() -> {
|
||||||
if (isComplete()) {
|
if (isComplete()) {
|
||||||
logger.trace("modem db builder finished");
|
logger.trace("modem db builder finished");
|
||||||
job.cancel(false);
|
ScheduledFuture<?> job = this.job;
|
||||||
job = null;
|
if (job != null) {
|
||||||
|
job.cancel(false);
|
||||||
|
}
|
||||||
|
this.job = null;
|
||||||
} else {
|
} else {
|
||||||
if (System.currentTimeMillis() - lastMessageTimestamp > MESSAGE_TIMEOUT) {
|
if (System.currentTimeMillis() - lastMessageTimestamp > MESSAGE_TIMEOUT) {
|
||||||
String s = "";
|
String s = "";
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public abstract class PollHandler {
|
public abstract class PollHandler {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PollHandler.class);
|
private static final Logger logger = LoggerFactory.getLogger(PollHandler.class);
|
||||||
DeviceFeature feature;
|
DeviceFeature feature;
|
||||||
|
@ -87,7 +86,6 @@ public abstract class PollHandler {
|
||||||
* most query messages. Provide the suitable parameters in
|
* most query messages. Provide the suitable parameters in
|
||||||
* the device features file.
|
* the device features file.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class FlexPollHandler extends PollHandler {
|
public static class FlexPollHandler extends PollHandler {
|
||||||
FlexPollHandler(DeviceFeature f) {
|
FlexPollHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -124,7 +122,6 @@ public abstract class PollHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class NoPollHandler extends PollHandler {
|
public static class NoPollHandler extends PollHandler {
|
||||||
NoPollHandler(DeviceFeature f) {
|
NoPollHandler(DeviceFeature f) {
|
||||||
super(f);
|
super(f);
|
||||||
|
@ -144,12 +141,13 @@ public abstract class PollHandler {
|
||||||
* @return the handler which was created
|
* @return the handler which was created
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends PollHandler> T makeHandler(@Nullable HandlerEntry ph, DeviceFeature f) {
|
public static <T extends PollHandler> T makeHandler(HandlerEntry ph, DeviceFeature f) {
|
||||||
String cname = PollHandler.class.getName() + "$" + ph.getName();
|
String cname = PollHandler.class.getName() + "$" + ph.getName();
|
||||||
try {
|
try {
|
||||||
Class<?> c = Class.forName(cname);
|
Class<?> c = Class.forName(cname);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends T> dc = (Class<? extends T>) c;
|
Class<? extends T> dc = (Class<? extends T>) c;
|
||||||
|
@Nullable
|
||||||
T phc = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
T phc = dc.getDeclaredConstructor(DeviceFeature.class).newInstance(f);
|
||||||
phc.setParameters(ph.getParams());
|
phc.setParameters(ph.getParams());
|
||||||
return phc;
|
return phc;
|
||||||
|
|
|
@ -15,6 +15,7 @@ package org.openhab.binding.insteon.internal.device;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -36,20 +37,25 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class RequestQueueManager {
|
public class RequestQueueManager {
|
||||||
private static @Nullable RequestQueueManager instance = null;
|
private static @Nullable RequestQueueManager instance = null;
|
||||||
private final Logger logger = LoggerFactory.getLogger(RequestQueueManager.class);
|
private final Logger logger = LoggerFactory.getLogger(RequestQueueManager.class);
|
||||||
private @Nullable Thread queueThread = null;
|
private @Nullable Thread queueThread = null;
|
||||||
private PriorityQueue<RequestQueue> requestQueues = new PriorityQueue<>();
|
private Queue<RequestQueue> requestQueues = new PriorityQueue<>();
|
||||||
private Map<InsteonDevice, RequestQueue> requestQueueHash = new HashMap<>();
|
private Map<InsteonDevice, RequestQueue> requestQueueHash = new HashMap<>();
|
||||||
private boolean keepRunning = true;
|
private boolean keepRunning = true;
|
||||||
|
|
||||||
private RequestQueueManager() {
|
private RequestQueueManager() {
|
||||||
queueThread = new Thread(new RequestQueueReader());
|
queueThread = new Thread(new RequestQueueReader());
|
||||||
queueThread.setName("Insteon Request Queue Reader");
|
setParamsAndStart(queueThread);
|
||||||
queueThread.setDaemon(true);
|
}
|
||||||
queueThread.start();
|
|
||||||
|
private void setParamsAndStart(@Nullable Thread thread) {
|
||||||
|
if (thread != null) {
|
||||||
|
thread.setName("Insteon Request Queue Reader");
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,6 +96,7 @@ public class RequestQueueManager {
|
||||||
*/
|
*/
|
||||||
private void stopThread() {
|
private void stopThread() {
|
||||||
logger.debug("stopping thread");
|
logger.debug("stopping thread");
|
||||||
|
Thread queueThread = this.queueThread;
|
||||||
if (queueThread != null) {
|
if (queueThread != null) {
|
||||||
synchronized (requestQueues) {
|
synchronized (requestQueues) {
|
||||||
keepRunning = false;
|
keepRunning = false;
|
||||||
|
@ -102,11 +109,10 @@ public class RequestQueueManager {
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.warn("got interrupted waiting for thread exit ", e);
|
logger.warn("got interrupted waiting for thread exit ", e);
|
||||||
}
|
}
|
||||||
queueThread = null;
|
this.queueThread = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
class RequestQueueReader implements Runnable {
|
class RequestQueueReader implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -114,8 +120,8 @@ public class RequestQueueManager {
|
||||||
synchronized (requestQueues) {
|
synchronized (requestQueues) {
|
||||||
while (keepRunning) {
|
while (keepRunning) {
|
||||||
try {
|
try {
|
||||||
while (keepRunning && !requestQueues.isEmpty()) {
|
RequestQueue q;
|
||||||
RequestQueue q = requestQueues.peek();
|
while (keepRunning && (q = requestQueues.peek()) != null) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
long expTime = q.getExpirationTime();
|
long expTime = q.getExpirationTime();
|
||||||
InsteonDevice dev = q.getDevice();
|
InsteonDevice dev = q.getDevice();
|
||||||
|
@ -161,7 +167,6 @@ public class RequestQueueManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class RequestQueue implements Comparable<RequestQueue> {
|
public static class RequestQueue implements Comparable<RequestQueue> {
|
||||||
private InsteonDevice device;
|
private InsteonDevice device;
|
||||||
private long expirationTime;
|
private long expirationTime;
|
||||||
|
@ -189,18 +194,18 @@ public class RequestQueueManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static synchronized @Nullable RequestQueueManager instance() {
|
public static synchronized @Nullable RequestQueueManager instance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new RequestQueueManager();
|
instance = new RequestQueueManager();
|
||||||
}
|
}
|
||||||
return (instance);
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void destroyInstance() {
|
public static synchronized void destroyInstance() {
|
||||||
|
RequestQueueManager instance = RequestQueueManager.instance;
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
instance.stopThread();
|
instance.stopThread();
|
||||||
instance = null;
|
RequestQueueManager.instance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class has utilities related to the X10 protocol.
|
* This class has utilities related to the X10 protocol.
|
||||||
|
@ -26,7 +25,6 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class X10 {
|
public class X10 {
|
||||||
/**
|
/**
|
||||||
* Enumerates the X10 command codes.
|
* Enumerates the X10 command codes.
|
||||||
|
@ -120,8 +118,12 @@ public class X10 {
|
||||||
* @return coded house byte
|
* @return coded house byte
|
||||||
*/
|
*/
|
||||||
public static int houseStringToCode(String s) {
|
public static int houseStringToCode(String s) {
|
||||||
Integer i = findKey(houseCodeToString, s);
|
for (Entry<Integer, String> entry : houseCodeToString.entrySet()) {
|
||||||
return (i == null) ? 0xf : i;
|
if (s.equals(entry.getValue())) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,23 +134,17 @@ public class X10 {
|
||||||
*/
|
*/
|
||||||
public static int unitStringToCode(String s) {
|
public static int unitStringToCode(String s) {
|
||||||
try {
|
try {
|
||||||
Integer key = Integer.parseInt(s);
|
int i = Integer.parseInt(s);
|
||||||
Integer i = findKey(unitCodeToInt, key);
|
for (Entry<Integer, Integer> entry : unitCodeToInt.entrySet()) {
|
||||||
return i;
|
if (i == entry.getValue()) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
}
|
}
|
||||||
return 0xf;
|
return 0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable <T, E> T findKey(Map<T, E> map, E value) {
|
|
||||||
for (Entry<T, E> entry : map.entrySet()) {
|
|
||||||
if (value.equals(entry.getValue())) {
|
|
||||||
return entry.getKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map between 4-bit X10 code and the house code.
|
* Map between 4-bit X10 code and the house code.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public abstract class IOStream {
|
public abstract class IOStream {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(IOStream.class);
|
private static final Logger logger = LoggerFactory.getLogger(IOStream.class);
|
||||||
protected @Nullable InputStream in = null;
|
protected @Nullable InputStream in = null;
|
||||||
|
@ -59,7 +58,12 @@ public abstract class IOStream {
|
||||||
public int read(byte[] b, int offset, int readSize) throws InterruptedException, IOException {
|
public int read(byte[] b, int offset, int readSize) throws InterruptedException, IOException {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while (!stopped && len < 1) {
|
while (!stopped && len < 1) {
|
||||||
len = in.read(b, offset, readSize);
|
InputStream in = this.in;
|
||||||
|
if (in != null) {
|
||||||
|
len = in.read(b, offset, readSize);
|
||||||
|
} else {
|
||||||
|
throw new IOException("in is null");
|
||||||
|
}
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
throw new EOFException();
|
throw new EOFException();
|
||||||
}
|
}
|
||||||
|
@ -77,7 +81,12 @@ public abstract class IOStream {
|
||||||
* @param b byte array to write
|
* @param b byte array to write
|
||||||
*/
|
*/
|
||||||
public void write(byte @Nullable [] b) throws IOException {
|
public void write(byte @Nullable [] b) throws IOException {
|
||||||
out.write(b);
|
OutputStream out = this.out;
|
||||||
|
if (out != null) {
|
||||||
|
out.write(b);
|
||||||
|
} else {
|
||||||
|
throw new IOException("out is null");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,7 +165,6 @@ public abstract class IOStream {
|
||||||
return new TcpIOStream(hp.host, hp.port);
|
return new TcpIOStream(hp.host, hp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
private static class HostPort {
|
private static class HostPort {
|
||||||
public String host = "localhost";
|
public String host = "localhost";
|
||||||
public int port = -1;
|
public int port = -1;
|
||||||
|
|
|
@ -41,7 +41,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class Poller {
|
public class Poller {
|
||||||
private static final long MIN_MSEC_BETWEEN_POLLS = 2000L;
|
private static final long MIN_MSEC_BETWEEN_POLLS = 2000L;
|
||||||
|
|
||||||
|
@ -107,9 +106,15 @@ public class Poller {
|
||||||
public void start() {
|
public void start() {
|
||||||
if (pollThread == null) {
|
if (pollThread == null) {
|
||||||
pollThread = new Thread(new PollQueueReader());
|
pollThread = new Thread(new PollQueueReader());
|
||||||
pollThread.setName("Insteon Poll Queue Reader");
|
setParamsAndStart(pollThread);
|
||||||
pollThread.setDaemon(true);
|
}
|
||||||
pollThread.start();
|
}
|
||||||
|
|
||||||
|
private void setParamsAndStart(@Nullable Thread thread) {
|
||||||
|
if (thread != null) {
|
||||||
|
thread.setName("Insteon Poll Queue Reader");
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,9 +129,10 @@ public class Poller {
|
||||||
pollQueue.notify();
|
pollQueue.notify();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
Thread pollThread = this.pollThread;
|
||||||
if (pollThread != null) {
|
if (pollThread != null) {
|
||||||
pollThread.join();
|
pollThread.join();
|
||||||
pollThread = null;
|
this.pollThread = null;
|
||||||
}
|
}
|
||||||
keepRunning = true;
|
keepRunning = true;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -194,7 +200,6 @@ public class Poller {
|
||||||
return expTime;
|
return expTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
private class PollQueueReader implements Runnable {
|
private class PollQueueReader implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -246,9 +251,14 @@ public class Poller {
|
||||||
* @param now the current time
|
* @param now the current time
|
||||||
*/
|
*/
|
||||||
private void processQueue(long now) {
|
private void processQueue(long now) {
|
||||||
PQEntry pqe = pollQueue.pollFirst();
|
processQueue(now, pollQueue.pollFirst());
|
||||||
pqe.getDevice().doPoll(0);
|
}
|
||||||
addToPollQueue(pqe.getDevice(), now + pqe.getDevice().getPollInterval());
|
|
||||||
|
private void processQueue(long now, @Nullable PQEntry pqe) {
|
||||||
|
if (pqe != null) {
|
||||||
|
pqe.getDevice().doPoll(0);
|
||||||
|
addToPollQueue(pqe.getDevice(), now + pqe.getDevice().getPollInterval());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +269,6 @@ public class Poller {
|
||||||
* @author Bernd Pfrommer - Initial contribution
|
* @author Bernd Pfrommer - Initial contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
private static class PQEntry implements Comparable<PQEntry> {
|
private static class PQEntry implements Comparable<PQEntry> {
|
||||||
private InsteonDevice dev;
|
private InsteonDevice dev;
|
||||||
private long expirationTime;
|
private long expirationTime;
|
||||||
|
|
|
@ -15,7 +15,7 @@ package org.openhab.binding.insteon.internal.driver;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
@ -57,7 +57,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class Port {
|
public class Port {
|
||||||
private final Logger logger = LoggerFactory.getLogger(Port.class);
|
private final Logger logger = LoggerFactory.getLogger(Port.class);
|
||||||
|
|
||||||
|
@ -153,9 +152,9 @@ public class Port {
|
||||||
public void clearModemDB() {
|
public void clearModemDB() {
|
||||||
logger.debug("clearing modem db!");
|
logger.debug("clearing modem db!");
|
||||||
Map<InsteonAddress, ModemDBEntry> dbes = getDriver().lockModemDBEntries();
|
Map<InsteonAddress, ModemDBEntry> dbes = getDriver().lockModemDBEntries();
|
||||||
for (InsteonAddress addr : dbes.keySet()) {
|
for (Entry<InsteonAddress, ModemDBEntry> entry : dbes.entrySet()) {
|
||||||
if (!dbes.get(addr).isModem()) {
|
if (!entry.getValue().isModem()) {
|
||||||
dbes.remove(addr);
|
dbes.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getDriver().unlockModemDBEntries();
|
getDriver().unlockModemDBEntries();
|
||||||
|
@ -178,13 +177,9 @@ public class Port {
|
||||||
}
|
}
|
||||||
ioStream.start();
|
ioStream.start();
|
||||||
readThread = new Thread(reader);
|
readThread = new Thread(reader);
|
||||||
readThread.setName("Insteon " + logName + " Reader");
|
setParamsAndStart(readThread, "Reader");
|
||||||
readThread.setDaemon(true);
|
|
||||||
readThread.start();
|
|
||||||
writeThread = new Thread(writer);
|
writeThread = new Thread(writer);
|
||||||
writeThread.setName("Insteon " + logName + " Writer");
|
setParamsAndStart(writeThread, "Writer");
|
||||||
writeThread.setDaemon(true);
|
|
||||||
writeThread.start();
|
|
||||||
|
|
||||||
if (!mdbb.isComplete()) {
|
if (!mdbb.isComplete()) {
|
||||||
modem.initialize();
|
modem.initialize();
|
||||||
|
@ -195,6 +190,14 @@ public class Port {
|
||||||
disconnected.set(false);
|
disconnected.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setParamsAndStart(@Nullable Thread thread, String type) {
|
||||||
|
if (thread != null) {
|
||||||
|
thread.setName("Insteon " + logName + " " + type);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops all threads
|
* Stops all threads
|
||||||
*/
|
*/
|
||||||
|
@ -208,9 +211,11 @@ public class Port {
|
||||||
ioStream.stop();
|
ioStream.stop();
|
||||||
ioStream.close();
|
ioStream.close();
|
||||||
|
|
||||||
|
Thread readThread = this.readThread;
|
||||||
if (readThread != null) {
|
if (readThread != null) {
|
||||||
readThread.interrupt();
|
readThread.interrupt();
|
||||||
}
|
}
|
||||||
|
Thread writeThread = this.writeThread;
|
||||||
if (writeThread != null) {
|
if (writeThread != null) {
|
||||||
writeThread.interrupt();
|
writeThread.interrupt();
|
||||||
}
|
}
|
||||||
|
@ -230,8 +235,8 @@ public class Port {
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.debug("got interrupted waiting for write thread to exit.");
|
logger.debug("got interrupted waiting for write thread to exit.");
|
||||||
}
|
}
|
||||||
readThread = null;
|
this.readThread = null;
|
||||||
writeThread = null;
|
this.writeThread = null;
|
||||||
|
|
||||||
logger.debug("all threads for port {} stopped.", logName);
|
logger.debug("all threads for port {} stopped.", logName);
|
||||||
}
|
}
|
||||||
|
@ -286,12 +291,10 @@ public class Port {
|
||||||
*
|
*
|
||||||
* @author Bernd Pfrommer - Initial contribution
|
* @author Bernd Pfrommer - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
class IOStreamReader implements Runnable {
|
class IOStreamReader implements Runnable {
|
||||||
|
|
||||||
private ReplyType reply = ReplyType.GOT_ACK;
|
private ReplyType reply = ReplyType.GOT_ACK;
|
||||||
private Object replyLock = new Object();
|
private Object replyLock = new Object();
|
||||||
private boolean dropRandomBytes = false; // set to true for fault injection
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for implementing synchronization between reader and writer
|
* Helper function for implementing synchronization between reader and writer
|
||||||
|
@ -306,12 +309,8 @@ public class Port {
|
||||||
public void run() {
|
public void run() {
|
||||||
logger.debug("starting reader...");
|
logger.debug("starting reader...");
|
||||||
byte[] buffer = new byte[2 * readSize];
|
byte[] buffer = new byte[2 * readSize];
|
||||||
Random rng = new Random();
|
|
||||||
try {
|
try {
|
||||||
for (int len = -1; (len = ioStream.read(buffer, 0, readSize)) > 0;) {
|
for (int len = -1; (len = ioStream.read(buffer, 0, readSize)) > 0;) {
|
||||||
if (dropRandomBytes && rng.nextInt(100) < 20) {
|
|
||||||
len = dropBytes(buffer, len);
|
|
||||||
}
|
|
||||||
msgFactory.addData(buffer, len);
|
msgFactory.addData(buffer, len);
|
||||||
processMessages();
|
processMessages();
|
||||||
}
|
}
|
||||||
|
@ -365,29 +364,6 @@ public class Port {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Drops bytes randomly from buffer to simulate errors seen
|
|
||||||
* from the InsteonHub using the raw interface
|
|
||||||
*
|
|
||||||
* @param buffer byte buffer from which to drop bytes
|
|
||||||
* @param len original number of valid bytes in buffer
|
|
||||||
* @return length of byte buffer after dropping from it
|
|
||||||
*/
|
|
||||||
private int dropBytes(byte[] buffer, int len) {
|
|
||||||
final int dropRate = 2; // in percent
|
|
||||||
Random rng = new Random();
|
|
||||||
ArrayList<Byte> l = new ArrayList<>();
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
if (rng.nextInt(100) >= dropRate) {
|
|
||||||
l.add(buffer[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < l.size(); i++) {
|
|
||||||
buffer[i] = l.get(i);
|
|
||||||
}
|
|
||||||
return (l.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void toAllListeners(Msg msg) {
|
private void toAllListeners(Msg msg) {
|
||||||
// When we deliver the message, the recipient
|
// When we deliver the message, the recipient
|
||||||
|
@ -442,7 +418,6 @@ public class Port {
|
||||||
*
|
*
|
||||||
* @author Bernd Pfrommer - Initial contribution
|
* @author Bernd Pfrommer - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
class IOStreamWriter implements Runnable {
|
class IOStreamWriter implements Runnable {
|
||||||
private static final int WAIT_TIME = 200; // milliseconds
|
private static final int WAIT_TIME = 200; // milliseconds
|
||||||
|
|
||||||
|
@ -492,11 +467,11 @@ public class Port {
|
||||||
/**
|
/**
|
||||||
* Class to get info about the modem
|
* Class to get info about the modem
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
class Modem implements MsgListener {
|
class Modem implements MsgListener {
|
||||||
private @Nullable InsteonDevice device = null;
|
private @Nullable InsteonDevice device = null;
|
||||||
|
|
||||||
InsteonAddress getAddress() {
|
InsteonAddress getAddress() {
|
||||||
|
InsteonDevice device = this.device;
|
||||||
return (device == null) ? new InsteonAddress() : (device.getAddress());
|
return (device == null) ? new InsteonAddress() : (device.getAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,18 +489,19 @@ public class Port {
|
||||||
if (msg.getByte("Cmd") == 0x60) {
|
if (msg.getByte("Cmd") == 0x60) {
|
||||||
// add the modem to the device list
|
// add the modem to the device list
|
||||||
InsteonAddress a = new InsteonAddress(msg.getAddress("IMAddress"));
|
InsteonAddress a = new InsteonAddress(msg.getAddress("IMAddress"));
|
||||||
DeviceType dt = DeviceTypeLoader.instance().getDeviceType(InsteonDeviceHandler.PLM_PRODUCT_KEY);
|
DeviceTypeLoader instance = DeviceTypeLoader.instance();
|
||||||
if (dt == null) {
|
if (instance != null) {
|
||||||
logger.warn("unknown modem product key: {} for modem: {}.",
|
DeviceType dt = instance.getDeviceType(InsteonDeviceHandler.PLM_PRODUCT_KEY);
|
||||||
InsteonDeviceHandler.PLM_PRODUCT_KEY, a);
|
if (dt == null) {
|
||||||
|
logger.warn("unknown modem product key: {} for modem: {}.",
|
||||||
|
InsteonDeviceHandler.PLM_PRODUCT_KEY, a);
|
||||||
|
} else {
|
||||||
|
device = InsteonDevice.makeDevice(dt);
|
||||||
|
initDevice(a, device);
|
||||||
|
mdbb.updateModemDB(a, Port.this, null, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
device = InsteonDevice.makeDevice(dt);
|
logger.warn("device type loader instance is null");
|
||||||
device.setAddress(a);
|
|
||||||
device.setProductKey(InsteonDeviceHandler.PLM_PRODUCT_KEY);
|
|
||||||
device.setDriver(driver);
|
|
||||||
device.setIsModem(true);
|
|
||||||
logger.debug("found modem {} in device_types: {}", a, device.toString());
|
|
||||||
mdbb.updateModemDB(a, Port.this, null, true);
|
|
||||||
}
|
}
|
||||||
// can unsubscribe now
|
// can unsubscribe now
|
||||||
removeListener(this);
|
removeListener(this);
|
||||||
|
@ -535,6 +511,18 @@ public class Port {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initDevice(InsteonAddress a, @Nullable InsteonDevice device) {
|
||||||
|
if (device != null) {
|
||||||
|
device.setAddress(a);
|
||||||
|
device.setProductKey(InsteonDeviceHandler.PLM_PRODUCT_KEY);
|
||||||
|
device.setDriver(driver);
|
||||||
|
device.setIsModem(true);
|
||||||
|
logger.debug("found modem {} in device_types: {}", a, device.toString());
|
||||||
|
} else {
|
||||||
|
logger.warn("device is null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
try {
|
try {
|
||||||
Msg m = Msg.makeMessage("GetIMInfo");
|
Msg m = Msg.makeMessage("GetIMInfo");
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
package org.openhab.binding.insteon.internal.driver;
|
package org.openhab.binding.insteon.internal.driver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -32,7 +34,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class SerialIOStream extends IOStream {
|
public class SerialIOStream extends IOStream {
|
||||||
private final Logger logger = LoggerFactory.getLogger(SerialIOStream.class);
|
private final Logger logger = LoggerFactory.getLogger(SerialIOStream.class);
|
||||||
private @Nullable SerialPort port = null;
|
private @Nullable SerialPort port = null;
|
||||||
|
@ -82,6 +83,11 @@ public class SerialIOStream extends IOStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
SerialPortManager serialPortManager = this.serialPortManager;
|
||||||
|
if (serialPortManager == null) {
|
||||||
|
logger.warn("serial port manager is null.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
SerialPortIdentifier spi = serialPortManager.getIdentifier(devName);
|
SerialPortIdentifier spi = serialPortManager.getIdentifier(devName);
|
||||||
if (spi == null) {
|
if (spi == null) {
|
||||||
logger.warn("{} is not a valid serial port.", devName);
|
logger.warn("{} is not a valid serial port.", devName);
|
||||||
|
@ -89,13 +95,7 @@ public class SerialIOStream extends IOStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
port = spi.open(appName, 1000);
|
port = spi.open(appName, 1000);
|
||||||
port.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
open(port);
|
||||||
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
|
|
||||||
logger.debug("setting {} baud rate to {}", devName, baudRate);
|
|
||||||
port.enableReceiveThreshold(1);
|
|
||||||
port.enableReceiveTimeout(1000);
|
|
||||||
in = port.getInputStream();
|
|
||||||
out = port.getOutputStream();
|
|
||||||
logger.debug("successfully opened port {}", devName);
|
logger.debug("successfully opened port {}", devName);
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -109,29 +109,46 @@ public class SerialIOStream extends IOStream {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void open(@Nullable SerialPort port) throws UnsupportedCommOperationException, IOException {
|
||||||
|
if (port != null) {
|
||||||
|
port.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||||
|
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
|
||||||
|
logger.debug("setting {} baud rate to {}", devName, baudRate);
|
||||||
|
port.enableReceiveThreshold(1);
|
||||||
|
port.enableReceiveTimeout(1000);
|
||||||
|
in = port.getInputStream();
|
||||||
|
out = port.getOutputStream();
|
||||||
|
} else {
|
||||||
|
logger.warn("port is null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
InputStream in = this.in;
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
try {
|
try {
|
||||||
in.close();
|
in.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close input stream", e);
|
logger.warn("failed to close input stream", e);
|
||||||
}
|
}
|
||||||
in = null;
|
this.in = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputStream out = this.out;
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
try {
|
try {
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close output stream", e);
|
logger.warn("failed to close output stream", e);
|
||||||
}
|
}
|
||||||
out = null;
|
this.out = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SerialPort port = this.port;
|
||||||
if (port != null) {
|
if (port != null) {
|
||||||
port.close();
|
port.close();
|
||||||
port = null;
|
this.port = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
package org.openhab.binding.insteon.internal.driver;
|
package org.openhab.binding.insteon.internal.driver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
@ -30,7 +32,6 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class TcpIOStream extends IOStream {
|
public class TcpIOStream extends IOStream {
|
||||||
private final Logger logger = LoggerFactory.getLogger(TcpIOStream.class);
|
private final Logger logger = LoggerFactory.getLogger(TcpIOStream.class);
|
||||||
|
|
||||||
|
@ -57,8 +58,7 @@ public class TcpIOStream extends IOStream {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
socket = new Socket(host, port);
|
socket = new Socket(host, port);
|
||||||
in = socket.getInputStream();
|
open(socket);
|
||||||
out = socket.getOutputStream();
|
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
logger.warn("unknown host name: {}", host);
|
logger.warn("unknown host name: {}", host);
|
||||||
return (false);
|
return (false);
|
||||||
|
@ -69,33 +69,43 @@ public class TcpIOStream extends IOStream {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void open(@Nullable Socket socket) throws IOException {
|
||||||
|
if (socket != null) {
|
||||||
|
in = socket.getInputStream();
|
||||||
|
out = socket.getOutputStream();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
|
InputStream in = this.in;
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
try {
|
try {
|
||||||
in.close();
|
in.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close input stream", e);
|
logger.warn("failed to close input stream", e);
|
||||||
}
|
}
|
||||||
in = null;
|
this.in = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputStream out = this.out;
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
try {
|
try {
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close output stream", e);
|
logger.warn("failed to close output stream", e);
|
||||||
}
|
}
|
||||||
out = null;
|
this.out = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Socket socket = this.socket;
|
||||||
if (socket != null) {
|
if (socket != null) {
|
||||||
try {
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close the socket", e);
|
logger.warn("failed to close the socket", e);
|
||||||
}
|
}
|
||||||
socket = null;
|
this.socket = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class HubIOStream extends IOStream implements Runnable {
|
public class HubIOStream extends IOStream implements Runnable {
|
||||||
private final Logger logger = LoggerFactory.getLogger(HubIOStream.class);
|
private final Logger logger = LoggerFactory.getLogger(HubIOStream.class);
|
||||||
|
|
||||||
|
@ -96,13 +95,19 @@ public class HubIOStream extends IOStream implements Runnable {
|
||||||
|
|
||||||
polling = true;
|
polling = true;
|
||||||
pollThread = new Thread(this);
|
pollThread = new Thread(this);
|
||||||
pollThread.setName("Insteon Hub Poller");
|
setParamsAndStart(pollThread);
|
||||||
pollThread.setDaemon(true);
|
|
||||||
pollThread.start();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setParamsAndStart(@Nullable Thread thread) {
|
||||||
|
if (thread != null) {
|
||||||
|
thread.setName("Insteon Hub Poller");
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
polling = false;
|
polling = false;
|
||||||
|
@ -111,22 +116,24 @@ public class HubIOStream extends IOStream implements Runnable {
|
||||||
pollThread = null;
|
pollThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputStream in = this.in;
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
try {
|
try {
|
||||||
in.close();
|
in.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close input stream", e);
|
logger.warn("failed to close input stream", e);
|
||||||
}
|
}
|
||||||
in = null;
|
this.in = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputStream out = this.out;
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
try {
|
try {
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("failed to close output stream", e);
|
logger.warn("failed to close output stream", e);
|
||||||
}
|
}
|
||||||
out = null;
|
this.out = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +242,12 @@ public class HubIOStream extends IOStream implements Runnable {
|
||||||
}
|
}
|
||||||
if (msg.length() != 0) {
|
if (msg.length() != 0) {
|
||||||
ByteBuffer buf = ByteBuffer.wrap(hexStringToByteArray(msg.toString()));
|
ByteBuffer buf = ByteBuffer.wrap(hexStringToByteArray(msg.toString()));
|
||||||
((HubInputStream) in).handle(buf);
|
InputStream in = this.in;
|
||||||
|
if (in != null) {
|
||||||
|
((HubInputStream) in).handle(buf);
|
||||||
|
} else {
|
||||||
|
logger.warn("in is null");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bufferIdx = nIdx;
|
bufferIdx = nIdx;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +356,6 @@ public class HubIOStream extends IOStream implements Runnable {
|
||||||
* @author Daniel Pfrommer - Initial contribution
|
* @author Daniel Pfrommer - Initial contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public class HubInputStream extends InputStream {
|
public class HubInputStream extends InputStream {
|
||||||
|
|
||||||
// A buffer to keep bytes while we are waiting for the inputstream to read
|
// A buffer to keep bytes while we are waiting for the inputstream to read
|
||||||
|
@ -381,7 +392,6 @@ public class HubIOStream extends IOStream implements Runnable {
|
||||||
* @author Daniel Pfrommer - Initial contribution
|
* @author Daniel Pfrommer - Initial contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public class HubOutputStream extends OutputStream {
|
public class HubOutputStream extends OutputStream {
|
||||||
private ByteArrayOutputStream out = new ByteArrayOutputStream();
|
private ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,14 @@ import org.openhab.binding.insteon.internal.device.DeviceFeature;
|
||||||
import org.openhab.binding.insteon.internal.device.DeviceTypeLoader;
|
import org.openhab.binding.insteon.internal.device.DeviceTypeLoader;
|
||||||
import org.openhab.binding.insteon.internal.device.InsteonAddress;
|
import org.openhab.binding.insteon.internal.device.InsteonAddress;
|
||||||
import org.openhab.binding.insteon.internal.device.InsteonDevice;
|
import org.openhab.binding.insteon.internal.device.InsteonDevice;
|
||||||
|
import org.openhab.core.thing.Bridge;
|
||||||
import org.openhab.core.thing.Channel;
|
import org.openhab.core.thing.Channel;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
import org.openhab.core.thing.ThingStatus;
|
import org.openhab.core.thing.ThingStatus;
|
||||||
import org.openhab.core.thing.ThingStatusDetail;
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -56,7 +58,6 @@ import com.google.gson.reflect.TypeToken;
|
||||||
* @author Rob Nielsen - Initial contribution
|
* @author Rob Nielsen - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class InsteonDeviceHandler extends BaseThingHandler {
|
public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private static final Set<String> ALL_CHANNEL_IDS = Collections.unmodifiableSet(Stream.of(
|
private static final Set<String> ALL_CHANNEL_IDS = Collections.unmodifiableSet(Stream.of(
|
||||||
|
@ -142,6 +143,14 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InsteonDeviceConfiguration config = this.config;
|
||||||
|
if (config == null) {
|
||||||
|
String msg = "Insteon device configuration is null.";
|
||||||
|
logger.warn("{} {}", thing.getUID().getAsString(), msg);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
String address = config.getAddress();
|
String address = config.getAddress();
|
||||||
if (!InsteonAddress.isValid(address)) {
|
if (!InsteonAddress.isValid(address)) {
|
||||||
String msg = "Unable to start Insteon device, the insteon or X10 address '" + address
|
String msg = "Unable to start Insteon device, the insteon or X10 address '" + address
|
||||||
|
@ -152,8 +161,17 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceTypeLoader instance = DeviceTypeLoader.instance();
|
||||||
|
if (instance == null) {
|
||||||
|
String msg = "Device type loader is null.";
|
||||||
|
logger.warn("{} {}", thing.getUID().getAsString(), msg);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String productKey = config.getProductKey();
|
String productKey = config.getProductKey();
|
||||||
if (DeviceTypeLoader.instance().getDeviceType(productKey) == null) {
|
if (instance.getDeviceType(productKey) == null) {
|
||||||
String msg = "Unable to start Insteon device, invalid product key '" + productKey + "'.";
|
String msg = "Unable to start Insteon device, invalid product key '" + productKey + "'.";
|
||||||
logger.warn("{} {}", thing.getUID().getAsString(), msg);
|
logger.warn("{} {}", thing.getUID().getAsString(), msg);
|
||||||
|
|
||||||
|
@ -190,6 +208,23 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
InsteonDevice device = insteonBinding.makeNewDevice(insteonAddress, productKey, deviceConfigMap);
|
InsteonDevice device = insteonBinding.makeNewDevice(insteonAddress, productKey, deviceConfigMap);
|
||||||
|
if (device == null) {
|
||||||
|
String msg = "Unable to create a device with the product key '" + productKey + "' with the address'"
|
||||||
|
+ address + "'.";
|
||||||
|
logger.warn("{} {}", thing.getUID().getAsString(), msg);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingHandlerCallback callback = getCallback();
|
||||||
|
if (callback == null) {
|
||||||
|
String msg = "Unable to get thing handler callback.";
|
||||||
|
logger.warn("{} {}", thing.getUID().getAsString(), msg);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder channelList = new StringBuilder();
|
StringBuilder channelList = new StringBuilder();
|
||||||
List<Channel> channels = new ArrayList<>();
|
List<Channel> channels = new ArrayList<>();
|
||||||
|
@ -256,7 +291,7 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
ChannelTypeUID channelTypeUID = new ChannelTypeUID(
|
ChannelTypeUID channelTypeUID = new ChannelTypeUID(
|
||||||
InsteonBindingConstants.BINDING_ID,
|
InsteonBindingConstants.BINDING_ID,
|
||||||
InsteonBindingConstants.SWITCH);
|
InsteonBindingConstants.SWITCH);
|
||||||
Channel channel = getCallback()
|
Channel channel = callback
|
||||||
.createChannelBuilder(channelUID, channelTypeUID).withLabel(id)
|
.createChannelBuilder(channelUID, channelTypeUID).withLabel(id)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -285,7 +320,7 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
channelId);
|
channelId);
|
||||||
Channel channel = thing.getChannel(channelUID);
|
Channel channel = thing.getChannel(channelUID);
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
channel = getCallback().createChannelBuilder(channelUID, channelTypeUID).build();
|
channel = callback.createChannelBuilder(channelUID, channelTypeUID).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
addChannel(channel, channelId, channels, channelList);
|
addChannel(channel, channelId, channels, channelList);
|
||||||
|
@ -343,15 +378,18 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
String address = config.getAddress();
|
InsteonDeviceConfiguration config = this.config;
|
||||||
if (getBridge() != null && InsteonAddress.isValid(address)) {
|
if (config != null) {
|
||||||
getInsteonBinding().removeDevice(new InsteonAddress(address));
|
String address = config.getAddress();
|
||||||
|
if (getBridge() != null && InsteonAddress.isValid(address)) {
|
||||||
|
getInsteonBinding().removeDevice(new InsteonAddress(address));
|
||||||
|
|
||||||
logger.debug("removed {} address = {}", getThing().getUID().getAsString(), address);
|
logger.debug("removed {} address = {}", getThing().getUID().getAsString(), address);
|
||||||
|
}
|
||||||
|
|
||||||
|
getInsteonNetworkHandler().disposed(getThing().getUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
getInsteonNetworkHandler().disposed(getThing().getUID());
|
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +408,10 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
Channel channel = getThing().getChannel(channelUID.getId());
|
Channel channel = getThing().getChannel(channelUID.getId());
|
||||||
|
if (channel == null) {
|
||||||
|
logger.warn("channel is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> channelProperties = channel.getConfiguration().getProperties();
|
Map<String, Object> channelProperties = channel.getConfiguration().getProperties();
|
||||||
for (String key : channelProperties.keySet()) {
|
for (String key : channelProperties.keySet()) {
|
||||||
|
@ -381,11 +423,16 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
params.put(key, s);
|
params.put(key, s);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("not a string or big decimal value key '{}' value '{}' {}", key, value,
|
logger.warn("not a string or big decimal value key '{}' value '{}' {}", key, value,
|
||||||
value.getClass().getName());
|
value != null ? value.getClass().getName() : "unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String feature = channelUID.getId().toLowerCase();
|
String feature = channelUID.getId().toLowerCase();
|
||||||
|
InsteonDeviceConfiguration config = this.config;
|
||||||
|
if (config == null) {
|
||||||
|
logger.warn("insteon device config is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
String productKey = config.getProductKey();
|
String productKey = config.getProductKey();
|
||||||
if (productKey.equals(HIDDEN_DOOR_SENSOR_PRODUCT_KEY)) {
|
if (productKey.equals(HIDDEN_DOOR_SENSOR_PRODUCT_KEY)) {
|
||||||
if (feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_LEVEL)) {
|
if (feature.equalsIgnoreCase(InsteonBindingConstants.BATTERY_LEVEL)) {
|
||||||
|
@ -461,11 +508,19 @@ public class InsteonDeviceHandler extends BaseThingHandler {
|
||||||
logger.debug("channel {} unlinked ", channelUID.getAsString());
|
logger.debug("channel {} unlinked ", channelUID.getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable InsteonNetworkHandler getInsteonNetworkHandler() {
|
private InsteonNetworkHandler getInsteonNetworkHandler() {
|
||||||
return (InsteonNetworkHandler) getBridge().getHandler();
|
Bridge bridge = getBridge();
|
||||||
|
if (bridge == null) {
|
||||||
|
throw new IllegalArgumentException("insteon network bridge is null");
|
||||||
|
}
|
||||||
|
InsteonNetworkHandler handler = (InsteonNetworkHandler) bridge.getHandler();
|
||||||
|
if (handler == null) {
|
||||||
|
throw new IllegalArgumentException("insteon network handler is null");
|
||||||
|
}
|
||||||
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable InsteonBinding getInsteonBinding() {
|
private InsteonBinding getInsteonBinding() {
|
||||||
return getInsteonNetworkHandler().getInsteonBinding();
|
return getInsteonNetworkHandler().getInsteonBinding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Initial contribution
|
* @author Rob Nielsen - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class InsteonNetworkHandler extends BaseBridgeHandler {
|
public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
private static final int LOG_DEVICE_STATISTICS_DELAY_IN_SECONDS = 600;
|
private static final int LOG_DEVICE_STATISTICS_DELAY_IN_SECONDS = 600;
|
||||||
private static final int RETRY_DELAY_IN_SECONDS = 30;
|
private static final int RETRY_DELAY_IN_SECONDS = 30;
|
||||||
|
@ -82,6 +81,23 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
updateStatus(ThingStatus.UNKNOWN);
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
|
|
||||||
scheduler.execute(() -> {
|
scheduler.execute(() -> {
|
||||||
|
InsteonNetworkConfiguration config = this.config;
|
||||||
|
if (config == null) {
|
||||||
|
String msg = "Initialization failed, configuration is null.";
|
||||||
|
logger.warn(msg);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SerialPortManager serialPortManager = this.serialPortManager;
|
||||||
|
if (serialPortManager == null) {
|
||||||
|
String msg = "Initialization failed, serial port manager is null.";
|
||||||
|
logger.warn(msg);
|
||||||
|
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
insteonBinding = new InsteonBinding(this, config, serialPortManager, scheduler);
|
insteonBinding = new InsteonBinding(this, config, serialPortManager, scheduler);
|
||||||
|
|
||||||
// hold off on starting to poll until devices that already are defined as things are added.
|
// hold off on starting to poll until devices that already are defined as things are added.
|
||||||
|
@ -91,7 +107,8 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
// check to see if it has been at least SETTLE_TIME_IN_SECONDS since last device was created
|
// check to see if it has been at least SETTLE_TIME_IN_SECONDS since last device was created
|
||||||
if (System.currentTimeMillis() - lastInsteonDeviceCreatedTimestamp > SETTLE_TIME_IN_SECONDS * 1000) {
|
if (System.currentTimeMillis() - lastInsteonDeviceCreatedTimestamp > SETTLE_TIME_IN_SECONDS * 1000) {
|
||||||
// settle time has expired start polling
|
// settle time has expired start polling
|
||||||
if (insteonBinding.startPolling()) {
|
InsteonBinding insteonBinding = this.insteonBinding;
|
||||||
|
if (insteonBinding != null && insteonBinding.startPolling()) {
|
||||||
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
|
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||||
insteonBinding.logDeviceStatistics();
|
insteonBinding.logDeviceStatistics();
|
||||||
}, 0, LOG_DEVICE_STATISTICS_DELAY_IN_SECONDS, TimeUnit.SECONDS);
|
}, 0, LOG_DEVICE_STATISTICS_DELAY_IN_SECONDS, TimeUnit.SECONDS);
|
||||||
|
@ -107,8 +124,11 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
settleJob.cancel(false);
|
ScheduledFuture<?> settleJob = this.settleJob;
|
||||||
settleJob = null;
|
if (settleJob != null) {
|
||||||
|
settleJob.cancel(false);
|
||||||
|
}
|
||||||
|
this.settleJob = null;
|
||||||
}
|
}
|
||||||
}, SETTLE_TIME_IN_SECONDS, 1, TimeUnit.SECONDS);
|
}, SETTLE_TIME_IN_SECONDS, 1, TimeUnit.SECONDS);
|
||||||
});
|
});
|
||||||
|
@ -118,24 +138,28 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
logger.debug("Shutting down Insteon bridge");
|
logger.debug("Shutting down Insteon bridge");
|
||||||
|
|
||||||
|
ScheduledFuture<?> pollingJob = this.pollingJob;
|
||||||
if (pollingJob != null) {
|
if (pollingJob != null) {
|
||||||
pollingJob.cancel(true);
|
pollingJob.cancel(true);
|
||||||
pollingJob = null;
|
this.pollingJob = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScheduledFuture<?> reconnectJob = this.reconnectJob;
|
||||||
if (reconnectJob != null) {
|
if (reconnectJob != null) {
|
||||||
reconnectJob.cancel(true);
|
reconnectJob.cancel(true);
|
||||||
reconnectJob = null;
|
this.reconnectJob = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScheduledFuture<?> settleJob = this.settleJob;
|
||||||
if (settleJob != null) {
|
if (settleJob != null) {
|
||||||
settleJob.cancel(true);
|
settleJob.cancel(true);
|
||||||
settleJob = null;
|
this.settleJob = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InsteonBinding insteonBinding = this.insteonBinding;
|
||||||
if (insteonBinding != null) {
|
if (insteonBinding != null) {
|
||||||
insteonBinding.shutdown();
|
insteonBinding.shutdown();
|
||||||
insteonBinding = null;
|
this.insteonBinding = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceInfo.clear();
|
deviceInfo.clear();
|
||||||
|
@ -151,10 +175,14 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
|
|
||||||
public void bindingDisconnected() {
|
public void bindingDisconnected() {
|
||||||
reconnectJob = scheduler.scheduleWithFixedDelay(() -> {
|
reconnectJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||||
if (insteonBinding.reconnect()) {
|
InsteonBinding insteonBinding = this.insteonBinding;
|
||||||
|
if (insteonBinding != null && insteonBinding.reconnect()) {
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
reconnectJob.cancel(false);
|
ScheduledFuture<?> reconnectJob = this.reconnectJob;
|
||||||
reconnectJob = null;
|
if (reconnectJob != null) {
|
||||||
|
reconnectJob.cancel(false);
|
||||||
|
}
|
||||||
|
this.reconnectJob = null;
|
||||||
} else {
|
} else {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Port disconnected.");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Port disconnected.");
|
||||||
}
|
}
|
||||||
|
@ -165,8 +193,13 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
lastInsteonDeviceCreatedTimestamp = System.currentTimeMillis();
|
lastInsteonDeviceCreatedTimestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable InsteonBinding getInsteonBinding() {
|
public InsteonBinding getInsteonBinding() {
|
||||||
return insteonBinding;
|
InsteonBinding insteonBinding = this.insteonBinding;
|
||||||
|
if (insteonBinding != null) {
|
||||||
|
return insteonBinding;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("insteon binding is null");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInsteonDeviceDiscoveryService(InsteonDeviceDiscoveryService insteonDeviceDiscoveryService) {
|
public void setInsteonDeviceDiscoveryService(InsteonDeviceDiscoveryService insteonDeviceDiscoveryService) {
|
||||||
|
@ -175,7 +208,10 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
|
|
||||||
public void addMissingDevices(List<String> missing) {
|
public void addMissingDevices(List<String> missing) {
|
||||||
scheduler.execute(() -> {
|
scheduler.execute(() -> {
|
||||||
insteonDeviceDiscoveryService.addInsteonDevices(missing, getThing().getUID());
|
InsteonDeviceDiscoveryService insteonDeviceDiscoveryService = this.insteonDeviceDiscoveryService;
|
||||||
|
if (insteonDeviceDiscoveryService != null) {
|
||||||
|
insteonDeviceDiscoveryService.addInsteonDevices(missing, getThing().getUID());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +224,12 @@ public class InsteonNetworkHandler extends BaseBridgeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayLocalDatabase(Console console) {
|
public void displayLocalDatabase(Console console) {
|
||||||
Map<String, String> databaseInfo = insteonBinding.getDatabaseInfo();
|
InsteonBinding insteonBinding = this.insteonBinding;
|
||||||
console.println("local database contains " + databaseInfo.size() + " entries");
|
if (insteonBinding != null) {
|
||||||
display(console, databaseInfo);
|
Map<String, String> databaseInfo = insteonBinding.getDatabaseInfo();
|
||||||
|
console.println("local database contains " + databaseInfo.size() + " entries");
|
||||||
|
display(console, databaseInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialized(ThingUID uid, String msg) {
|
public void initialized(ThingUID uid, String msg) {
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
package org.openhab.binding.insteon.internal.message;
|
package org.openhab.binding.insteon.internal.message;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the data types that can be used in the fields of a message.
|
* Defines the data types that can be used in the fields of a message.
|
||||||
|
@ -31,10 +31,10 @@ public enum DataType {
|
||||||
ADDRESS("address", 3),
|
ADDRESS("address", 3),
|
||||||
INVALID("INVALID", -1);
|
INVALID("INVALID", -1);
|
||||||
|
|
||||||
private static HashMap<String, DataType> typeMap = new HashMap<>();
|
private static Map<String, DataType> typeMap = new HashMap<>();
|
||||||
|
|
||||||
private int size = -1; // number of bytes consumed
|
private int size;
|
||||||
private String name = "";
|
private String name;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
typeMap.put(BYTE.getName(), BYTE);
|
typeMap.put(BYTE.getName(), BYTE);
|
||||||
|
@ -74,7 +74,12 @@ public enum DataType {
|
||||||
* @param name the string to translate to a type
|
* @param name the string to translate to a type
|
||||||
* @return the data type corresponding to the name string, or null if not found
|
* @return the data type corresponding to the name string, or null if not found
|
||||||
*/
|
*/
|
||||||
public static @Nullable DataType getDataType(String name) {
|
public static DataType getDataType(String name) {
|
||||||
return typeMap.get(name);
|
DataType dataType = typeMap.get(name);
|
||||||
|
if (dataType != null) {
|
||||||
|
return dataType;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unable to find data type for " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,10 @@ import org.openhab.binding.insteon.internal.utils.Utils;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public final class Field {
|
public final class Field {
|
||||||
private final String name;
|
private final String name;
|
||||||
private final int offset;
|
private final int offset;
|
||||||
private final @Nullable DataType type;
|
private final DataType type;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
|
@ -42,11 +41,11 @@ public final class Field {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable DataType getType() {
|
public DataType getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field(String name, @Nullable DataType type, int off) {
|
public Field(String name, DataType type, int off) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.offset = off;
|
this.offset = off;
|
||||||
|
@ -74,7 +73,7 @@ public final class Field {
|
||||||
return getName() + " Type: " + getType() + " Offset " + getOffset();
|
return getName() + " Type: " + getType() + " Offset " + getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(byte @Nullable [] array) {
|
public String toString(byte[] array) {
|
||||||
String s = name + ":";
|
String s = name + ":";
|
||||||
try {
|
try {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -96,7 +95,7 @@ public final class Field {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(byte @Nullable [] array, Object o) throws FieldException {
|
public void set(byte[] array, Object o) throws FieldException {
|
||||||
switch (getType()) {
|
switch (getType()) {
|
||||||
case BYTE:
|
case BYTE:
|
||||||
setByte(array, (Byte) o);
|
setByte(array, (Byte) o);
|
||||||
|
@ -121,7 +120,7 @@ public final class Field {
|
||||||
* @param b the value you want to set the byte to
|
* @param b the value you want to set the byte to
|
||||||
* @throws FieldException
|
* @throws FieldException
|
||||||
*/
|
*/
|
||||||
public void setByte(byte @Nullable [] array, byte b) throws FieldException {
|
public void setByte(byte[] array, byte b) throws FieldException {
|
||||||
check(array.length, DataType.BYTE);
|
check(array.length, DataType.BYTE);
|
||||||
array[offset] = b;
|
array[offset] = b;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +132,7 @@ public final class Field {
|
||||||
* @param array the destination array
|
* @param array the destination array
|
||||||
* @param i the integer value to set
|
* @param i the integer value to set
|
||||||
*/
|
*/
|
||||||
public void setInt(byte @Nullable [] array, int i) throws FieldException {
|
public void setInt(byte[] array, int i) throws FieldException {
|
||||||
check(array.length, DataType.INT);
|
check(array.length, DataType.INT);
|
||||||
array[offset] = (byte) ((i >>> 24) & 0xFF);
|
array[offset] = (byte) ((i >>> 24) & 0xFF);
|
||||||
array[offset + 1] = (byte) ((i >>> 16) & 0xFF);
|
array[offset + 1] = (byte) ((i >>> 16) & 0xFF);
|
||||||
|
@ -149,7 +148,7 @@ public final class Field {
|
||||||
* @param adr the insteon address value to set
|
* @param adr the insteon address value to set
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setAddress(byte @Nullable [] array, InsteonAddress adr) throws FieldException {
|
public void setAddress(byte[] array, InsteonAddress adr) throws FieldException {
|
||||||
check(array.length, DataType.ADDRESS);
|
check(array.length, DataType.ADDRESS);
|
||||||
adr.storeBytes(array, offset);
|
adr.storeBytes(array, offset);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +159,7 @@ public final class Field {
|
||||||
* @param array the array to fetch from
|
* @param array the array to fetch from
|
||||||
* @return the byte value of the field
|
* @return the byte value of the field
|
||||||
*/
|
*/
|
||||||
public byte getByte(byte @Nullable [] array) throws FieldException {
|
public byte getByte(byte[] array) throws FieldException {
|
||||||
check(array.length, DataType.BYTE);
|
check(array.length, DataType.BYTE);
|
||||||
return array[offset];
|
return array[offset];
|
||||||
}
|
}
|
||||||
|
@ -171,7 +170,7 @@ public final class Field {
|
||||||
* @param array the array to fetch from
|
* @param array the array to fetch from
|
||||||
* @return the int value of the field
|
* @return the int value of the field
|
||||||
*/
|
*/
|
||||||
public int getInt(byte @Nullable [] array) throws FieldException {
|
public int getInt(byte[] array) throws FieldException {
|
||||||
check(array.length, DataType.INT);
|
check(array.length, DataType.INT);
|
||||||
byte b1 = array[offset];
|
byte b1 = array[offset];
|
||||||
byte b2 = array[offset + 1];
|
byte b2 = array[offset + 1];
|
||||||
|
@ -188,7 +187,7 @@ public final class Field {
|
||||||
* @return the address
|
* @return the address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public InsteonAddress getAddress(byte @Nullable [] array) throws FieldException {
|
public InsteonAddress getAddress(byte[] array) throws FieldException {
|
||||||
check(array.length, DataType.ADDRESS);
|
check(array.length, DataType.ADDRESS);
|
||||||
InsteonAddress adr = new InsteonAddress();
|
InsteonAddress adr = new InsteonAddress();
|
||||||
adr.loadBytes(array, offset);
|
adr.loadBytes(array, offset);
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class Msg {
|
public class Msg {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Msg.class);
|
private static final Logger logger = LoggerFactory.getLogger(Msg.class);
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ public class Msg {
|
||||||
TO_MODEM("TO_MODEM"),
|
TO_MODEM("TO_MODEM"),
|
||||||
FROM_MODEM("FROM_MODEM");
|
FROM_MODEM("FROM_MODEM");
|
||||||
|
|
||||||
private static HashMap<String, Direction> map = new HashMap<>();
|
private static Map<String, Direction> map = new HashMap<>();
|
||||||
|
|
||||||
private String directionString;
|
private String directionString;
|
||||||
|
|
||||||
|
@ -69,7 +68,12 @@ public class Msg {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Direction getDirectionFromString(String dir) {
|
public static Direction getDirectionFromString(String dir) {
|
||||||
return map.get(dir);
|
Direction direction = map.get(dir);
|
||||||
|
if (direction != null) {
|
||||||
|
return direction;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unable to find direction for " + dir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +85,7 @@ public class Msg {
|
||||||
private static final Map<Integer, Msg> REPLY_MAP = new HashMap<>();
|
private static final Map<Integer, Msg> REPLY_MAP = new HashMap<>();
|
||||||
|
|
||||||
private int headerLength = -1;
|
private int headerLength = -1;
|
||||||
private byte @Nullable [] data = null;
|
private byte[] data;
|
||||||
private MsgDefinition definition = new MsgDefinition();
|
private MsgDefinition definition = new MsgDefinition();
|
||||||
private Direction direction = Direction.TO_MODEM;
|
private Direction direction = Direction.TO_MODEM;
|
||||||
private long quietTime = 0;
|
private long quietTime = 0;
|
||||||
|
@ -97,7 +101,8 @@ public class Msg {
|
||||||
public Msg(int headerLength, byte[] data, int dataLength, Direction dir) {
|
public Msg(int headerLength, byte[] data, int dataLength, Direction dir) {
|
||||||
this.headerLength = headerLength;
|
this.headerLength = headerLength;
|
||||||
this.direction = dir;
|
this.direction = dir;
|
||||||
initialize(data, 0, dataLength);
|
this.data = new byte[dataLength];
|
||||||
|
System.arraycopy(data, 0, this.data, 0, dataLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,7 +124,7 @@ public class Msg {
|
||||||
try {
|
try {
|
||||||
InputStream stream = FrameworkUtil.getBundle(Msg.class).getResource("/msg_definitions.xml").openStream();
|
InputStream stream = FrameworkUtil.getBundle(Msg.class).getResource("/msg_definitions.xml").openStream();
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
HashMap<String, Msg> msgs = XMLMessageReader.readMessageDefinitions(stream);
|
Map<String, Msg> msgs = XMLMessageReader.readMessageDefinitions(stream);
|
||||||
MSG_MAP.putAll(msgs);
|
MSG_MAP.putAll(msgs);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("could not get message definition resource!");
|
logger.warn("could not get message definition resource!");
|
||||||
|
@ -171,15 +176,15 @@ public class Msg {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getCommandNumber() {
|
public byte getCommandNumber() {
|
||||||
return ((data == null || data.length < 2) ? -1 : data[1]);
|
return data.length < 2 ? -1 : data[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPureNack() {
|
public boolean isPureNack() {
|
||||||
return (data.length == 2 && data[1] == 0x15);
|
return data.length == 2 && data[1] == 0x15;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExtended() {
|
public boolean isExtended() {
|
||||||
if (data == null || getLength() < 2) {
|
if (getLength() < 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!definition.containsField("messageFlags")) {
|
if (!definition.containsField("messageFlags")) {
|
||||||
|
@ -272,23 +277,6 @@ public class Msg {
|
||||||
return hops;
|
return hops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Will initialize the message with a byte[], an offset, and a length
|
|
||||||
*
|
|
||||||
* @param newData the src byte array
|
|
||||||
* @param offset the offset in the src byte array
|
|
||||||
* @param len the length to copy from the src byte array
|
|
||||||
*/
|
|
||||||
private void initialize(byte[] newData, int offset, int len) {
|
|
||||||
byte[] data = new byte[len];
|
|
||||||
if (offset >= 0 && offset < newData.length) {
|
|
||||||
System.arraycopy(newData, offset, data, 0, len);
|
|
||||||
} else {
|
|
||||||
logger.warn("intialize(): Offset out of bounds!");
|
|
||||||
}
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will put a byte at the specified key
|
* Will put a byte at the specified key
|
||||||
*
|
*
|
||||||
|
@ -346,9 +334,7 @@ public class Msg {
|
||||||
}
|
}
|
||||||
byte[] section = new byte[numBytes];
|
byte[] section = new byte[numBytes];
|
||||||
byte[] data = this.data;
|
byte[] data = this.data;
|
||||||
if (data != null) {
|
System.arraycopy(data, offset, section, 0, numBytes);
|
||||||
System.arraycopy(data, offset, section, 0, numBytes);
|
|
||||||
}
|
|
||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,10 +363,7 @@ public class Msg {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toHexString() {
|
public String toHexString() {
|
||||||
if (data != null) {
|
return Utils.getHexString(data);
|
||||||
return Utils.getHexString(data);
|
|
||||||
}
|
|
||||||
return super.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -473,19 +456,15 @@ public class Msg {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String s = (direction == Direction.TO_MODEM) ? "OUT:" : "IN:";
|
String s = (direction == Direction.TO_MODEM) ? "OUT:" : "IN:";
|
||||||
if (data == null) {
|
|
||||||
return toHexString();
|
|
||||||
}
|
|
||||||
// need to first sort the fields by offset
|
// need to first sort the fields by offset
|
||||||
Comparator<@Nullable Field> cmp = new Comparator<@Nullable Field>() {
|
Comparator<Field> cmp = new Comparator<Field>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(@Nullable Field f1, @Nullable Field f2) {
|
public int compare(Field f1, Field f2) {
|
||||||
return f1.getOffset() - f2.getOffset();
|
return f1.getOffset() - f2.getOffset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TreeSet<@Nullable Field> fields = new TreeSet<>(cmp);
|
TreeSet<Field> fields = new TreeSet<>(cmp);
|
||||||
for (@Nullable
|
for (Field f : definition.getFields().values()) {
|
||||||
Field f : definition.getFields().values()) {
|
|
||||||
fields.add(f);
|
fields.add(f);
|
||||||
}
|
}
|
||||||
for (Field f : fields) {
|
for (Field f : fields) {
|
||||||
|
@ -517,7 +496,7 @@ public class Msg {
|
||||||
* @return message, or null if the Msg cannot be created
|
* @return message, or null if the Msg cannot be created
|
||||||
*/
|
*/
|
||||||
public static @Nullable Msg createMessage(byte[] buf, int msgLen, boolean isExtended) {
|
public static @Nullable Msg createMessage(byte[] buf, int msgLen, boolean isExtended) {
|
||||||
if (buf == null || buf.length < 2) {
|
if (buf.length < 2) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Msg template = REPLY_MAP.get(cmdToKey(buf[1], isExtended));
|
Msg template = REPLY_MAP.get(cmdToKey(buf[1], isExtended));
|
||||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class MsgDefinition {
|
public class MsgDefinition {
|
||||||
private Map<String, Field> fields = new HashMap<>();
|
private Map<String, Field> fields = new HashMap<>();
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ public class MsgDefinition {
|
||||||
*
|
*
|
||||||
* @param m the definition to copy
|
* @param m the definition to copy
|
||||||
*/
|
*/
|
||||||
MsgDefinition(@Nullable MsgDefinition m) {
|
MsgDefinition(MsgDefinition m) {
|
||||||
fields = new HashMap<>(m.fields);
|
fields = new HashMap<>(m.fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
@ -23,7 +24,6 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
|
||||||
import org.openhab.binding.insteon.internal.utils.Pair;
|
import org.openhab.binding.insteon.internal.utils.Pair;
|
||||||
import org.openhab.binding.insteon.internal.utils.Utils.DataTypeParser;
|
import org.openhab.binding.insteon.internal.utils.Utils.DataTypeParser;
|
||||||
import org.openhab.binding.insteon.internal.utils.Utils.ParsingException;
|
import org.openhab.binding.insteon.internal.utils.Utils.ParsingException;
|
||||||
|
@ -40,7 +40,6 @@ import org.xml.sax.SAXException;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class XMLMessageReader {
|
public class XMLMessageReader {
|
||||||
/**
|
/**
|
||||||
* Reads the message definitions from an xml file
|
* Reads the message definitions from an xml file
|
||||||
|
@ -51,9 +50,9 @@ public class XMLMessageReader {
|
||||||
* @throws ParsingException something wrong with the file format
|
* @throws ParsingException something wrong with the file format
|
||||||
* @throws FieldException something wrong with the field definition
|
* @throws FieldException something wrong with the field definition
|
||||||
*/
|
*/
|
||||||
public static HashMap<String, Msg> readMessageDefinitions(InputStream input)
|
public static Map<String, Msg> readMessageDefinitions(InputStream input)
|
||||||
throws IOException, ParsingException, FieldException {
|
throws IOException, ParsingException, FieldException {
|
||||||
HashMap<String, Msg> messageMap = new HashMap<>();
|
Map<String, Msg> messageMap = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||||
|
@ -133,12 +132,9 @@ public class XMLMessageReader {
|
||||||
for (int i = 0; i < nodes.getLength(); i++) {
|
for (int i = 0; i < nodes.getLength(); i++) {
|
||||||
Node node = nodes.item(i);
|
Node node = nodes.item(i);
|
||||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
@Nullable
|
|
||||||
Pair<Field, Object> definition = readField((Element) node, offset);
|
Pair<Field, Object> definition = readField((Element) node, offset);
|
||||||
if (definition != null) {
|
offset += definition.getKey().getType().getSize();
|
||||||
offset += definition.getKey().getType().getSize();
|
fields.put(definition.getKey(), definition.getValue());
|
||||||
fields.put(definition.getKey(), definition.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (headerLen != offset) {
|
if (headerLen != offset) {
|
||||||
|
@ -165,8 +161,13 @@ public class XMLMessageReader {
|
||||||
Msg msg = new Msg(headerLength, new byte[length], length, dir);
|
Msg msg = new Msg(headerLength, new byte[length], length, dir);
|
||||||
for (Entry<Field, Object> e : values.entrySet()) {
|
for (Entry<Field, Object> e : values.entrySet()) {
|
||||||
Field f = e.getKey();
|
Field f = e.getKey();
|
||||||
f.set(msg.getData(), e.getValue());
|
byte[] data = msg.getData();
|
||||||
if (f.getName() != null && !f.getName().equals("")) {
|
if (data != null) {
|
||||||
|
f.set(data, e.getValue());
|
||||||
|
} else {
|
||||||
|
throw new FieldException("data is null");
|
||||||
|
}
|
||||||
|
if (!f.getName().equals("")) {
|
||||||
msg.addField(f);
|
msg.addField(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,13 @@ import org.openhab.binding.insteon.internal.message.DataType;
|
||||||
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
* @author Rob Nielsen - Port to openHAB 2 insteon binding
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@SuppressWarnings("null")
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
public static String getHexString(int b) {
|
public static String getHexString(int b) {
|
||||||
String result = String.format("%02X", b & 0xFF);
|
String result = String.format("%02X", b & 0xFF);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getHexString(byte @Nullable [] b) {
|
public static String getHexString(byte[] b) {
|
||||||
return getHexString(b, b.length);
|
return getHexString(b, b.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +69,8 @@ public class Utils {
|
||||||
return String.format("0x%02X", b);
|
return String.format("0x%02X", b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault
|
|
||||||
public static class DataTypeParser {
|
public static class DataTypeParser {
|
||||||
public static Object parseDataType(@Nullable DataType type, String val) {
|
public static Object parseDataType(DataType type, String val) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BYTE:
|
case BYTE:
|
||||||
return parseByte(val);
|
return parseByte(val);
|
||||||
|
@ -123,7 +121,6 @@ public class Utils {
|
||||||
/**
|
/**
|
||||||
* Exception to indicate various xml parsing errors.
|
* Exception to indicate various xml parsing errors.
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
|
||||||
public static class ParsingException extends Exception {
|
public static class ParsingException extends Exception {
|
||||||
private static final long serialVersionUID = 3997461423241843949L;
|
private static final long serialVersionUID = 3997461423241843949L;
|
||||||
|
|
||||||
|
|
|
@ -622,7 +622,7 @@
|
||||||
<message-dispatcher>DefaultDispatcher</message-dispatcher>
|
<message-dispatcher>DefaultDispatcher</message-dispatcher>
|
||||||
<!-- handles direct extended message after query -->
|
<!-- handles direct extended message after query -->
|
||||||
<message-handler cmd="0x2e" ext="1" match_cmd1="0x2e" match_cmd2="0x02" match_d1="0x01"
|
<message-handler cmd="0x2e" ext="1" match_cmd1="0x2e" match_cmd2="0x02" match_d1="0x01"
|
||||||
low_byte="userData10" high_byte="userData9" factor="0.1">NumberMsgHandler</message-handler>
|
low_byte="userData10" high_byte="userData9" factor="0.1" scale="celsius">NumberMsgHandler</message-handler>
|
||||||
<!-- handles out-of band status messages -->
|
<!-- handles out-of band status messages -->
|
||||||
<message-handler cmd="0x6e" ext="0" match_cmd1="0x6e" low_byte="command2" offset="-17.7777778"
|
<message-handler cmd="0x6e" ext="0" match_cmd1="0x6e" low_byte="command2" offset="-17.7777778"
|
||||||
factor="0.2777778" scale="celsius">NumberMsgHandler</message-handler>
|
factor="0.2777778" scale="celsius">NumberMsgHandler</message-handler>
|
||||||
|
@ -634,7 +634,7 @@
|
||||||
<message-dispatcher>DefaultDispatcher</message-dispatcher>
|
<message-dispatcher>DefaultDispatcher</message-dispatcher>
|
||||||
<!-- handles direct extended message after query -->
|
<!-- handles direct extended message after query -->
|
||||||
<message-handler cmd="0x2e" ext="1" match_cmd1="0x2e" match_cmd2="0x02" match_d1="0x01"
|
<message-handler cmd="0x2e" ext="1" match_cmd1="0x2e" match_cmd2="0x02" match_d1="0x01"
|
||||||
low_byte="userData10" high_byte="userData9" offset="32" factor="0.18">NumberMsgHandler</message-handler>
|
low_byte="userData10" high_byte="userData9" offset="32" factor="0.18" scale="fahrenheit">NumberMsgHandler</message-handler>
|
||||||
<!-- handles out-of band status messages -->
|
<!-- handles out-of band status messages -->
|
||||||
<message-handler cmd="0x6e" ext="0" match_cmd1="0x6e" low_byte="command2" offset="0" factor="0.5"
|
<message-handler cmd="0x6e" ext="0" match_cmd1="0x6e" low_byte="command2" offset="0" factor="0.5"
|
||||||
scale="fahrenheit">NumberMsgHandler</message-handler>
|
scale="fahrenheit">NumberMsgHandler</message-handler>
|
||||||
|
|
Loading…
Reference in New Issue