Skip to content

Commit f4338cc

Browse files
authored
[insteon] Fix missing links implementation (openhab#18274)
Signed-off-by: Jeremy Setton <[email protected]>
1 parent 2e1eb1f commit f4338cc

File tree

14 files changed

+69
-245
lines changed

14 files changed

+69
-245
lines changed

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/InsteonBindingConstants.java

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public class InsteonBindingConstants {
7575
public static final String FEATURE_LED_ON_OFF = "ledOnOff";
7676
public static final String FEATURE_LINK_FF_GROUP = "linkFFGroup";
7777
public static final String FEATURE_LOW_BATTERY_THRESHOLD = "lowBatteryThreshold";
78+
public static final String FEATURE_MONITOR_MODE = "monitorMode";
7879
public static final String FEATURE_ON_LEVEL = "onLevel";
7980
public static final String FEATURE_PING = "ping";
8081
public static final String FEATURE_RAMP_RATE = "rampRate";

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/command/DeviceCommand.java

+18-17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.openhab.binding.insteon.internal.device.InsteonDevice;
2929
import org.openhab.binding.insteon.internal.device.ProductData;
3030
import org.openhab.binding.insteon.internal.device.database.LinkDBRecord;
31+
import org.openhab.binding.insteon.internal.device.database.ModemDBRecord;
3132
import org.openhab.binding.insteon.internal.device.feature.FeatureEnums.KeypadButtonToggleMode;
3233
import org.openhab.binding.insteon.internal.handler.InsteonDeviceHandler;
3334
import org.openhab.binding.insteon.internal.handler.InsteonThingHandler;
@@ -465,9 +466,9 @@ private void listMissingLinks(Console console, String thingId) {
465466
console.println("The modem database is not loaded yet.");
466467
} else {
467468
List<String> deviceLinks = device.getMissingDeviceLinks().entrySet().stream()
468-
.map(entry -> String.format("%s: %s", entry.getKey(), entry.getValue().getRecord())).toList();
469+
.map(entry -> String.format("%s: %s", entry.getKey(), entry.getValue())).toList();
469470
List<String> modemLinks = device.getMissingModemLinks().entrySet().stream()
470-
.map(entry -> String.format("%s: %s", entry.getKey(), entry.getValue().getRecord())).toList();
471+
.map(entry -> String.format("%s: %s", entry.getKey(), entry.getValue())).toList();
471472
if (deviceLinks.isEmpty() && modemLinks.isEmpty()) {
472473
console.println("There are no missing links for device " + device.getAddress() + ".");
473474
} else {
@@ -499,33 +500,33 @@ private void addMissingLinks(Console console, String thingId) {
499500
console.println("The device " + thingId + " is not configured or enabled!");
500501
} else if (!device.getLinkDB().isComplete()) {
501502
console.println("The link database for device " + thingId + " is not loaded yet.");
502-
} else if (!device.getLinkDB().getChanges().isEmpty()) {
503-
console.println("The link database for device " + thingId + " has pending changes.");
504503
} else if (!getModem().getDB().isComplete()) {
505504
console.println("The modem database is not loaded yet.");
506-
} else if (!getModem().getDB().getChanges().isEmpty()) {
507-
console.println("The modem database has pending changes.");
508505
} else {
509-
int deviceLinkCount = device.getMissingDeviceLinks().size();
510-
int modemLinkCount = device.getMissingModemLinks().size();
511-
if (deviceLinkCount == 0 && modemLinkCount == 0) {
506+
List<LinkDBRecord> deviceLinks = device.getMissingDeviceLinks().values().stream().toList();
507+
List<ModemDBRecord> modemLinks = device.getMissingModemLinks().values().stream().toList();
508+
if (deviceLinks.isEmpty() && modemLinks.isEmpty()) {
512509
console.println("There are no missing links for device " + device.getAddress() + ".");
513510
} else {
514-
if (deviceLinkCount > 0) {
511+
if (!deviceLinks.isEmpty()) {
515512
if (!device.isAwake() || !device.isResponding()) {
516-
console.println("Scheduling " + deviceLinkCount + " missing links for device "
513+
console.println("Scheduling " + deviceLinks.size() + " missing links for device "
517514
+ device.getAddress() + " to be added to its link database the next time it is "
518515
+ (device.isBatteryPowered() ? "awake" : "online") + ".");
519516
} else {
520-
console.println("Adding " + deviceLinkCount + " missing links for device " + device.getAddress()
521-
+ " to its link database...");
517+
console.println("Adding " + deviceLinks.size() + " missing links for device "
518+
+ device.getAddress() + " to its link database...");
522519
}
523-
device.addMissingDeviceLinks();
520+
deviceLinks.forEach(record -> device.getLinkDB().markRecordForAddOrModify(record.getAddress(),
521+
record.getGroup(), record.isController(), record.getData()));
522+
device.getLinkDB().update();
524523
}
525-
if (modemLinkCount > 0) {
526-
console.println("Adding " + modemLinkCount + " missing links for device " + device.getAddress()
524+
if (!modemLinks.isEmpty()) {
525+
console.println("Adding " + modemLinks.size() + " missing links for device " + device.getAddress()
527526
+ " to the modem database...");
528-
device.addMissingModemLinks();
527+
modemLinks.forEach(record -> getModem().getDB().markRecordForAddOrModify(record.getAddress(),
528+
record.getGroup(), record.isController(), record.getData()));
529+
getModem().getDB().update();
529530
}
530531
}
531532
}

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DefaultLink.java

+2-15
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@
1212
*/
1313
package org.openhab.binding.insteon.internal.device;
1414

15-
import java.util.List;
16-
1715
import org.eclipse.jdt.annotation.NonNullByDefault;
1816
import org.openhab.binding.insteon.internal.device.database.LinkDBRecord;
1917
import org.openhab.binding.insteon.internal.device.database.ModemDBRecord;
20-
import org.openhab.binding.insteon.internal.transport.message.Msg;
2118

2219
/**
2320
* The {@link DefaultLink} represents a device default link
@@ -29,13 +26,11 @@ public class DefaultLink {
2926
private String name;
3027
private LinkDBRecord linkDBRecord;
3128
private ModemDBRecord modemDBRecord;
32-
private List<Msg> commands;
3329

34-
public DefaultLink(String name, LinkDBRecord linkDBRecord, ModemDBRecord modemDBRecord, List<Msg> commands) {
30+
public DefaultLink(String name, LinkDBRecord linkDBRecord, ModemDBRecord modemDBRecord) {
3531
this.name = name;
3632
this.linkDBRecord = linkDBRecord;
3733
this.modemDBRecord = modemDBRecord;
38-
this.commands = commands;
3934
}
4035

4136
public String getName() {
@@ -50,16 +45,8 @@ public ModemDBRecord getModemDBRecord() {
5045
return modemDBRecord;
5146
}
5247

53-
public List<Msg> getCommands() {
54-
return commands;
55-
}
56-
5748
@Override
5849
public String toString() {
59-
String s = name + "|linkDB:" + linkDBRecord + "|modemDB:" + modemDBRecord;
60-
if (!commands.isEmpty()) {
61-
s += "|commands:" + commands;
62-
}
63-
return s;
50+
return name + "|linkDB:" + linkDBRecord + "|modemDB:" + modemDBRecord;
6451
}
6552
}

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceFeature.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,13 @@ public int getGroup() {
236236

237237
public int getComponentId() {
238238
int componentId = 0;
239-
if (device instanceof InsteonDevice insteonDevice) {
239+
if (device instanceof InsteonDevice insteonDevice && isControllerOrResponderFeature()) {
240240
// use feature group as component id if device has more than one controller or responder feature,
241-
// othewise use the component id of the link db first record
241+
// set to 1 if device link db has a matching record, otherwise fall back to 0
242242
if (insteonDevice.getControllerOrResponderFeatures().size() > 1) {
243243
componentId = getGroup();
244-
} else {
245-
componentId = insteonDevice.getLinkDB().getFirstRecordComponentId();
244+
} else if (insteonDevice.getLinkDB().hasComponentIdRecord(1, isControllerFeature())) {
245+
componentId = 1;
246246
}
247247
}
248248
return componentId;

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceType.java

-62
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
import java.util.stream.Collectors;
2222

2323
import org.eclipse.jdt.annotation.NonNullByDefault;
24-
import org.eclipse.jdt.annotation.Nullable;
25-
import org.openhab.binding.insteon.internal.transport.message.FieldException;
26-
import org.openhab.binding.insteon.internal.transport.message.InvalidMessageTypeException;
27-
import org.openhab.binding.insteon.internal.transport.message.Msg;
2824
import org.openhab.binding.insteon.internal.utils.HexUtils;
2925

3026
/**
@@ -175,7 +171,6 @@ public static class DefaultLinkEntry {
175171
private boolean controller;
176172
private int group;
177173
private byte[] data;
178-
private List<CommandEntry> commands = new ArrayList<>();
179174

180175
public DefaultLinkEntry(String name, boolean controller, int group, byte[] data) {
181176
this.name = name;
@@ -196,14 +191,6 @@ public byte[] getData() {
196191
return data;
197192
}
198193

199-
public List<CommandEntry> getCommands() {
200-
return commands;
201-
}
202-
203-
public void addCommand(CommandEntry command) {
204-
commands.add(command);
205-
}
206-
207194
@Override
208195
public String toString() {
209196
String s = name + "->";
@@ -212,55 +199,6 @@ public String toString() {
212199
s += "|data1:" + HexUtils.getHexString(data[0]);
213200
s += "|data2:" + HexUtils.getHexString(data[1]);
214201
s += "|data3:" + HexUtils.getHexString(data[2]);
215-
if (!commands.isEmpty()) {
216-
s += "|commands:" + commands;
217-
}
218-
return s;
219-
}
220-
}
221-
222-
/**
223-
* Class that reflects a command entry
224-
*/
225-
public static class CommandEntry {
226-
private String name;
227-
private int ext;
228-
private byte cmd1;
229-
private byte cmd2;
230-
private byte[] data;
231-
232-
public CommandEntry(String name, int ext, byte cmd1, byte cmd2, byte[] data) {
233-
this.name = name;
234-
this.ext = ext;
235-
this.cmd1 = cmd1;
236-
this.cmd2 = cmd2;
237-
this.data = data;
238-
}
239-
240-
public @Nullable Msg getMessage(InsteonDevice device) {
241-
try {
242-
if (ext == 0) {
243-
return Msg.makeStandardMessage(device.getAddress(), cmd1, cmd2);
244-
} else if (ext == 1) {
245-
return Msg.makeExtendedMessage(device.getAddress(), cmd1, cmd2, data,
246-
device.getInsteonEngine().supportsChecksum());
247-
} else if (ext == 2) {
248-
return Msg.makeExtendedMessageCRC2(device.getAddress(), cmd1, cmd2, data);
249-
}
250-
} catch (FieldException | InvalidMessageTypeException e) {
251-
}
252-
return null;
253-
}
254-
255-
@Override
256-
public String toString() {
257-
String s = name + "->";
258-
s += "ext:" + ext;
259-
s += "|cmd1:" + HexUtils.getHexString(cmd1);
260-
s += "|cmd2:" + HexUtils.getHexString(cmd2);
261-
s += "|data1:" + HexUtils.getHexString(data[0]);
262-
s += "|data2:" + HexUtils.getHexString(data[1]);
263-
s += "|data3:" + HexUtils.getHexString(data[2]);
264202
return s;
265203
}
266204
}

bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/device/DeviceTypeRegistry.java

-43
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@
1919
import org.eclipse.jdt.annotation.NonNullByDefault;
2020
import org.eclipse.jdt.annotation.Nullable;
2121
import org.openhab.binding.insteon.internal.InsteonResourceLoader;
22-
import org.openhab.binding.insteon.internal.device.DeviceType.CommandEntry;
2322
import org.openhab.binding.insteon.internal.device.DeviceType.DefaultLinkEntry;
2423
import org.openhab.binding.insteon.internal.device.DeviceType.FeatureEntry;
25-
import org.openhab.binding.insteon.internal.utils.HexUtils;
2624
import org.w3c.dom.Element;
2725
import org.w3c.dom.Node;
2826
import org.w3c.dom.NodeList;
@@ -249,52 +247,11 @@ private void parseDefaultLink(Element element, Map<String, DefaultLinkEntry> lin
249247
getHexAttributeAsByte(element, "data3") };
250248

251249
DefaultLinkEntry link = new DefaultLinkEntry(name, isController, group, data);
252-
253-
NodeList nodes = element.getChildNodes();
254-
for (int i = 0; i < nodes.getLength(); i++) {
255-
Node node = nodes.item(i);
256-
if (node.getNodeType() == Node.ELEMENT_NODE) {
257-
Element child = (Element) node;
258-
String nodeName = child.getNodeName();
259-
if ("command".equals(nodeName)) {
260-
link.addCommand(getDefaultLinkCommand(child));
261-
}
262-
}
263-
}
264-
265250
if (links.putIfAbsent(name, link) != null) {
266251
throw new SAXException("duplicate default link: " + name);
267252
}
268253
}
269254

270-
/**
271-
* Returns a default link command
272-
*
273-
* @param element element to parse
274-
* @return default link command
275-
* @throws SAXException
276-
*/
277-
private CommandEntry getDefaultLinkCommand(Element element) throws SAXException {
278-
String name = element.getAttribute("name");
279-
if (name.isEmpty()) {
280-
throw new SAXException("undefined default link command name");
281-
}
282-
int ext = getAttributeAsInteger(element, "ext");
283-
if (ext < 0 || ext > 2) {
284-
throw new SAXException("out of bound default link command ext argument: " + ext);
285-
}
286-
byte cmd1 = getHexAttributeAsByte(element, "cmd1");
287-
if (cmd1 == 0) {
288-
throw new SAXException("invalid default link command cmd1 argument: " + HexUtils.getHexString(cmd1));
289-
}
290-
byte cmd2 = getHexAttributeAsByte(element, "cmd2", (byte) 0x00);
291-
byte[] data = { getHexAttributeAsByte(element, "data1", (byte) 0x00),
292-
getHexAttributeAsByte(element, "data2", (byte) 0x00),
293-
getHexAttributeAsByte(element, "data3", (byte) 0x00) };
294-
295-
return new CommandEntry(name, ext, cmd1, cmd2, data);
296-
}
297-
298255
/**
299256
* Singleton instance function
300257
*

0 commit comments

Comments
 (0)