import org.eclipse.jdt.annotation.NonNullByDefault;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
/**
* Used for deserializing the XML response of the LCN-PCHK discovery protocol.
*
*/
@NonNullByDefault
public class ExtServices {
- private final ExtService ExtService;
+ @XStreamAlias("ExtService")
+ private final ExtService extService;
public ExtServices(ExtService extService) {
- ExtService = extService;
+ this.extService = extService;
}
public ExtService getExtService() {
- return ExtService;
+ return extService;
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
super(SUPPORTED_THING_TYPES_UIDS, 0, false);
}
- private List<InetAddress> getLocalAddresses() {
- List<InetAddress> result = new LinkedList<>();
+ private List<NetworkInterface> getLocalNetworkInterfaces() {
+ List<NetworkInterface> result = new LinkedList<>();
try {
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
try {
if (networkInterface.isUp() && !networkInterface.isLoopback()
&& !networkInterface.isPointToPoint()) {
- result.addAll(Collections.list(networkInterface.getInetAddresses()));
+ result.add(networkInterface);
}
} catch (SocketException exception) {
// ignore
try {
InetAddress multicastAddress = InetAddress.getByName(PCHK_DISCOVERY_MULTICAST_ADDRESS);
- getLocalAddresses().forEach(localInterfaceAddress -> {
- logger.debug("Searching on {} ...", localInterfaceAddress.getHostAddress());
+ getLocalNetworkInterfaces().forEach(localNetworkInterface -> {
+ logger.debug("Searching on {} ...", localNetworkInterface);
try (MulticastSocket socket = new MulticastSocket(PCHK_DISCOVERY_PORT)) {
- socket.setInterface(localInterfaceAddress);
socket.setReuseAddress(true);
socket.setSoTimeout(INTERFACE_TIMEOUT_SEC * 1000);
- socket.joinGroup(multicastAddress);
+ socket.joinGroup(new InetSocketAddress(multicastAddress, PCHK_DISCOVERY_PORT),
+ localNetworkInterface);
byte[] requestData = DISCOVER_REQUEST.getBytes(LcnDefs.LCN_ENCODING);
DatagramPacket request = new DatagramPacket(requestData, requestData.length, multicastAddress,
thingDiscovered(discoveryResult.build());
} while (true); // left by SocketTimeoutException
} catch (IOException e) {
- logger.debug("Discovery failed for {}: {}", localInterfaceAddress, e.getMessage());
+ logger.debug("Discovery failed for {}: {}", localNetworkInterface, e.getMessage());
}
});
} catch (UnknownHostException e) {
import org.eclipse.jdt.annotation.NonNullByDefault;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
/**
* Used for deserializing the XML response of the LCN-PCHK discovery protocol.
*
*/
@NonNullByDefault
public class ServicesResponse {
- private final Version Version;
- private final Server Server;
- private final ExtServices ExtServices;
- @SuppressWarnings("unused")
- private final Object Services = new Object();
+ @XStreamAlias("Version")
+ private final Version version;
+ @XStreamAlias("Server")
+ private final Server server;
+ @XStreamAlias("ExtServices")
+ private final ExtServices extServices;
+ @XStreamAlias("Services")
+ private final Object services = new Object();
public ServicesResponse(Version version, Server server, ExtServices extServices) {
- this.Version = version;
- this.Server = server;
- this.ExtServices = extServices;
+ this.version = version;
+ this.server = server;
+ this.extServices = extServices;
}
public Server getServer() {
- return Server;
+ return server;
}
public Version getVersion() {
- return Version;
+ return version;
}
public ExtServices getExtServices() {
- return ExtServices;
+ return extServices;
}
}
public void handleStatusMessage(Matcher matcher) {
String code;
+ int base = 10;
if (matcher.pattern() == FINGERPRINT_PATTERN_HEX) {
- code = String.format("%02X%02X%02X", Integer.parseInt(matcher.group("byte0"), 16),
- Integer.parseInt(matcher.group("byte1"), 16), Integer.parseInt(matcher.group("byte2"), 16));
- } else {
- code = String.format("%02X%02X%02X", Integer.parseInt(matcher.group("byte0")),
- Integer.parseInt(matcher.group("byte1")), Integer.parseInt(matcher.group("byte2")));
+ base = 16;
}
+ code = String.format("%02X%02X%02X", Integer.parseInt(matcher.group("byte0"), base),
+ Integer.parseInt(matcher.group("byte1"), base), Integer.parseInt(matcher.group("byte2"), base));
+
if (matcher.pattern() == TRANSPONDER_PATTERN) {
handler.triggerChannel(LcnChannelGroup.CODE, "transponder", code);
} else if (matcher.pattern() == FINGERPRINT_PATTERN_HEX || matcher.pattern() == FINGERPRINT_PATTERN_DEC) {
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.types.UpDownType;
+import org.openhab.core.util.ColorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
currentColor = hsbType;
handler.updateChannel(LcnChannelGroup.OUTPUT, OUTPUT_COLOR, currentColor);
+ PercentType[] rgb = ColorUtil.hsbToRgbPercent(currentColor);
+
if (info.getFirmwareVersion().map(v -> v >= LcnBindingConstants.FIRMWARE_2014).orElse(true)) {
- handler.sendPck(PckGenerator.dimAllOutputs(currentColor.getRed().doubleValue(),
- currentColor.getGreen().doubleValue(), currentColor.getBlue().doubleValue(), output4.doubleValue(),
- COLOR_RAMP_MS));
+ handler.sendPck(PckGenerator.dimAllOutputs(rgb[0].doubleValue(), rgb[1].doubleValue(), rgb[2].doubleValue(),
+ output4.doubleValue(), COLOR_RAMP_MS));
} else {
- handler.sendPck(PckGenerator.dimOutput(0, currentColor.getRed().doubleValue(), COLOR_RAMP_MS));
- handler.sendPck(PckGenerator.dimOutput(1, currentColor.getGreen().doubleValue(), COLOR_RAMP_MS));
- handler.sendPck(PckGenerator.dimOutput(2, currentColor.getBlue().doubleValue(), COLOR_RAMP_MS));
+ handler.sendPck(PckGenerator.dimOutput(0, rgb[0].doubleValue(), COLOR_RAMP_MS));
+ handler.sendPck(PckGenerator.dimOutput(1, rgb[1].doubleValue(), COLOR_RAMP_MS));
+ handler.sendPck(PckGenerator.dimOutput(2, rgb[2].doubleValue(), COLOR_RAMP_MS));
}
}
*/
package org.openhab.binding.lcn.internal.subhandler;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
@Test
public void testDecFingerprint() {
- tryParseAllHandlers("=M000005.ZF255255255");
- verify(handler).triggerChannel(LcnChannelGroup.CODE, "fingerprint", "FFFFFF");
+ tryParseAllHandlers("=M000005.ZF255001002");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "fingerprint", "FF0102");
verify(handler).triggerChannel(any(), any(), any());
}
+
+ @Test
+ public void testTransponder() {
+ tryParseAllHandlers("=M000005.ZT255001002");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "transponder", "FF0102");
+ verify(handler).triggerChannel(any(), any(), any());
+ }
+
+ @Test
+ public void testRemote() {
+ tryParseAllHandlers("=M000005.ZI255001002013001");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "remotecontrolkey", "B3:HIT");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "remotecontrolcode", "FF0102:B3:HIT");
+ verify(handler, times(2)).triggerChannel(any(), any(), any());
+ }
+
+ @Test
+ public void testRemoteBatteryLow() {
+ tryParseAllHandlers("=M000005.ZI255001002008012");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "remotecontrolkey", "A8:MAKE");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "remotecontrolcode", "FF0102:A8:MAKE");
+ verify(handler).triggerChannel(LcnChannelGroup.CODE, "remotecontrolbatterylow", "FF0102");
+ verify(handler, times(3)).triggerChannel(any(), any(), any());
+ }
}