// List of all configuration properties
public static final String CONFIG_PROPERTY_MAC_ADDRESS = "macAddress";
public static final String CONFIG_PROPERTY_RECALIBRATE = "recalibrate";
- public static final String CONFIG_PROPERTY_SERIAL_PORT = "serialPort";
public static final String CONFIG_PROPERTY_UPDATE_CONFIGURATION = "updateConfiguration";
public static final String CONFIG_PROPERTY_UPDATE_INTERVAL = "updateInterval";
public static final int MAX_BUFFER_SIZE = 1024;
- private static final Comparator<? super @Nullable PlugwiseQueuedMessage> QUEUED_MESSAGE_COMPERATOR = new Comparator<@Nullable PlugwiseQueuedMessage>() {
- @Override
- public int compare(@Nullable PlugwiseQueuedMessage o1, @Nullable PlugwiseQueuedMessage o2) {
- if (o1 == null || o2 == null) {
- return -1;
- }
- int result = o1.getPriority().compareTo(o2.getPriority());
- if (result == 0) {
- result = o1.getDateTime().compareTo(o2.getDateTime());
- }
- return result;
+ private static final Comparator<? super @Nullable PlugwiseQueuedMessage> QUEUED_MESSAGE_COMPARATOR = (o1, o2) -> {
+ if (o1 == null || o2 == null) {
+ return -1;
+ }
+ int result = o1.getPriority().compareTo(o2.getPriority());
+ if (result == 0) {
+ result = o1.getDateTime().compareTo(o2.getDateTime());
}
+ return result;
};
private final Logger logger = LoggerFactory.getLogger(PlugwiseCommunicationContext.class);
MAX_BUFFER_SIZE, true);
private final BlockingQueue<@Nullable Message> receivedQueue = new ArrayBlockingQueue<>(MAX_BUFFER_SIZE, true);
private final PriorityBlockingQueue<@Nullable PlugwiseQueuedMessage> sendQueue = new PriorityBlockingQueue<>(
- MAX_BUFFER_SIZE, QUEUED_MESSAGE_COMPERATOR);
+ MAX_BUFFER_SIZE, QUEUED_MESSAGE_COMPARATOR);
private final BlockingQueue<@Nullable PlugwiseQueuedMessage> sentQueue = new ArrayBlockingQueue<>(MAX_BUFFER_SIZE,
true);
private final ReentrantLock sentQueueLock = new ReentrantLock();
}
// Build exception message when port not found
- String availablePorts = serialPortManager.getIdentifiers().map(id -> id.getName())
+ String availablePorts = serialPortManager.getIdentifiers().map(SerialPortIdentifier::getName)
.collect(Collectors.joining(System.lineSeparator()));
throw new PlugwiseInitializationException(
private @Nullable ScheduledFuture<?> future;
- private Runnable scheduledRunnable = new Runnable() {
- @Override
- public void run() {
- try {
- lock.lock();
- logger.debug("Running '{}' Plugwise task for {} ({})", name, deviceType, macAddress);
- runTask();
- } catch (Exception e) {
- logger.warn("Error while running '{}' Plugwise task for {} ({})", name, deviceType, macAddress, e);
- } finally {
- lock.unlock();
- }
+ private final Runnable scheduledRunnable = () -> {
+ try {
+ lock.lock();
+ logger.debug("Running '{}' Plugwise task for {} ({})", getName(), deviceType, macAddress);
+ runTask();
+ } catch (Exception e) {
+ logger.warn("Error while running '{}' Plugwise task for {} ({})", getName(), deviceType, macAddress, e);
+ } finally {
+ lock.unlock();
}
};
- public PlugwiseDeviceTask(String name, ScheduledExecutorService scheduler) {
+ protected PlugwiseDeviceTask(String name, ScheduledExecutorService scheduler) {
this.name = name;
this.scheduler = scheduler;
}
for (PlugwiseFilteredMessageListener filteredListener : filteredListeners) {
if (filteredListener.matches(message)) {
try {
- filteredListener.getListener().handleReponseMessage(message);
+ filteredListener.getListener().handleResponseMessage(message);
} catch (Exception e) {
logger.warn("Listener failed to handle message: {}", message, e);
}
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
-import java.util.Iterator;
import java.util.TooManyListenersException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
try {
context.getSentQueueLock().lock();
- Iterator<@Nullable PlugwiseQueuedMessage> messageIterator = context.getSentQueue().iterator();
- while (messageIterator.hasNext()) {
- PlugwiseQueuedMessage queuedSentMessage = messageIterator.next();
+ for (PlugwiseQueuedMessage queuedSentMessage : context.getSentQueue()) {
if (queuedSentMessage != null
&& queuedSentMessage.getMessage().getSequenceNumber() == message.getSequenceNumber()) {
logger.debug("Removing from sentQueue: {}", queuedSentMessage.getMessage());
private class MessageSenderThread extends Thread {
- private int messageWaitTime;
+ private final int messageWaitTime;
public MessageSenderThread(int messageWaitTime) {
super("OH-binding-" + context.getBridgeUID() + "-message-sender");
ThingUID thingUID = new ThingUID(thingTypeUID, bridgeUID, mac);
thingDiscovered(DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID)
- .withLabel("Plugwise " + node.deviceType.toString())
+ .withLabel("Plugwise " + node.deviceType)
.withProperty(PlugwiseBindingConstants.CONFIG_PROPERTY_MAC_ADDRESS, mac)
.withProperties(new HashMap<>(node.properties))
.withRepresentationProperty(PlugwiseBindingConstants.PROPERTY_MAC_ADDRESS).build());
}
@Override
- public void handleReponseMessage(Message message) {
+ public void handleResponseMessage(Message message) {
switch (message.getType()) {
case ANNOUNCE_AWAKE_REQUEST:
handleAnnounceAwakeRequest((AnnounceAwakeRequestMessage) message);
final String delimiter = "_";
StringBuilder upperCamelBuilder = new StringBuilder(text.length());
for (String str : text.split(delimiter)) {
- if (upperCamelBuilder.isEmpty() && str.length() > 0) {
+ if (upperCamelBuilder.isEmpty() && !str.isEmpty()) {
upperCamelBuilder.append(str.substring(0, 1).toLowerCase());
- } else if (str.length() > 0) {
+ } else if (!str.isEmpty()) {
upperCamelBuilder.append(str.substring(0, 1).toUpperCase());
}
if (str.length() > 1) {
private @Nullable LocalDateTime lastConfigurationUpdateSend;
private int unansweredPings;
- public AbstractPlugwiseThingHandler(Thing thing) {
+ protected AbstractPlugwiseThingHandler(Thing thing) {
super(thing);
}
private final Logger logger = LoggerFactory.getLogger(AbstractSleepingEndDeviceHandler.class);
- public AbstractSleepingEndDeviceHandler(Thing thing) {
+ protected AbstractSleepingEndDeviceHandler(Thing thing) {
super(thing);
}
}
@Override
- public void handleReponseMessage(Message message) {
+ public void handleResponseMessage(Message message) {
updateLastSeen();
switch (message.getType()) {
- case ACKNOWLEDGEMENT_V1:
- case ACKNOWLEDGEMENT_V2:
+ case ACKNOWLEDGEMENT_V1, ACKNOWLEDGEMENT_V2:
handleAcknowledgement((AcknowledgementMessage) message);
break;
case ANNOUNCE_AWAKE_REQUEST:
if (deviceType == DeviceType.CIRCLE_PLUS) {
// The Circle+ real-time clock needs to be updated first to prevent clock sync issues
sendCommandMessage(new RealTimeClockSetRequestMessage(macAddress, LocalDateTime.now()));
- scheduler.schedule(() -> {
- sendCommandMessage(new ClockSetRequestMessage(macAddress, LocalDateTime.now()));
- }, 5, TimeUnit.SECONDS);
+ scheduler.schedule(
+ () -> sendCommandMessage(new ClockSetRequestMessage(macAddress, LocalDateTime.now())), 5,
+ TimeUnit.SECONDS);
} else {
sendCommandMessage(new ClockSetRequestMessage(macAddress, LocalDateTime.now()));
}
}
@Override
- public void handleReponseMessage(Message message) {
+ public void handleResponseMessage(Message message) {
updateLastSeen();
switch (message.getType()) {
- case ACKNOWLEDGEMENT_V1:
- case ACKNOWLEDGEMENT_V2:
+ case ACKNOWLEDGEMENT_V1, ACKNOWLEDGEMENT_V2:
handleAcknowledgement((AcknowledgementMessage) message);
break;
case CLOCK_GET_RESPONSE:
}
@Override
- public void handleReponseMessage(Message message) {
+ public void handleResponseMessage(Message message) {
switch (message.getType()) {
case SENSE_REPORT_REQUEST:
handleSenseReportRequestMessage((SenseReportRequestMessage) message);
break;
default:
- super.handleReponseMessage(message);
+ super.handleResponseMessage(message);
break;
}
}
}
@Override
- public void handleReponseMessage(Message message) {
+ public void handleResponseMessage(Message message) {
switch (message.getType()) {
- case ACKNOWLEDGEMENT_V1:
- case ACKNOWLEDGEMENT_V2:
+ case ACKNOWLEDGEMENT_V1, ACKNOWLEDGEMENT_V2:
handleAcknowledgement((AcknowledgementMessage) message);
break;
case DEVICE_INFORMATION_RESPONSE:
@NonNullByDefault
public interface PlugwiseMessageListener {
- void handleReponseMessage(Message message);
+ void handleResponseMessage(Message message);
}
return TYPES_BY_VALUE.get(value);
}
- private int identifier;
+ private final int identifier;
- private ExtensionCode(int value) {
+ ExtensionCode(int value) {
identifier = value;
}
WAKEUP_BUTTON(5);
public static AwakeReason forValue(int value) {
- return Arrays.stream(values()).filter(awakeReason -> awakeReason.id == value).findFirst().get();
+ return Arrays.stream(values()).filter(awakeReason -> awakeReason.id == value).findFirst().orElse(null);
}
private final int id;
String minutes = String.format("%04X",
(utcDateTime.getDayOfMonth() - 1) * 24 * 60 + (utcDateTime.getHour() * 60) + utcDateTime.getMinute());
// If we set logaddress to FFFFFFFFF then previous buffered data will be kept by the Circle+
- String logaddress = "FFFFFFFF";
+ String logAddress = "FFFFFFFF";
String hour = String.format("%02X", utcDateTime.getHour());
String minute = String.format("%02X", utcDateTime.getMinute());
String second = String.format("%02X", utcDateTime.getSecond());
// Monday = 0, ... , Sunday = 6
String dayOfWeek = String.format("%02X", utcDateTime.getDayOfWeek().getValue() - 1);
- return year + month + minutes + logaddress + hour + minute + second + dayOfWeek;
+ return year + month + minutes + logAddress + hour + minute + second + dayOfWeek;
}
}
}
private DeviceType intToDeviceType(int i) {
- switch (i) {
- case 0:
- return DeviceType.STICK;
- case 1:
- return DeviceType.CIRCLE_PLUS;
- case 2:
- return DeviceType.CIRCLE;
- case 3:
- return DeviceType.SWITCH;
- case 5:
- return DeviceType.SENSE;
- case 6:
- return DeviceType.SCAN;
- case 9:
- return DeviceType.STEALTH;
- default:
- return null;
- }
+ return switch (i) {
+ case 0 -> DeviceType.STICK;
+ case 1 -> DeviceType.CIRCLE_PLUS;
+ case 2 -> DeviceType.CIRCLE;
+ case 3 -> DeviceType.SWITCH;
+ case 5 -> DeviceType.SENSE;
+ case 6 -> DeviceType.SCAN;
+ case 9 -> DeviceType.STEALTH;
+ default -> null;
+ };
}
@Override
*/
package org.openhab.binding.plugwise.internal.protocol;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import org.openhab.binding.plugwise.internal.protocol.field.MACAddress;
import org.openhab.binding.plugwise.internal.protocol.field.MessageType;
int crc = 0x0000;
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
- byte[] bytes = new byte[0];
- try {
- bytes = string.getBytes("ASCII");
- } catch (UnsupportedEncodingException e) {
- return "";
- }
-
- for (byte b : bytes) {
+ for (byte b : string.getBytes(StandardCharsets.US_ASCII)) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
protected String payload;
- public Message(MessageType messageType) {
+ protected Message(MessageType messageType) {
this(messageType, null, null, null);
}
- public Message(MessageType messageType, Integer sequenceNumber, MACAddress macAddress, String payload) {
+ protected Message(MessageType messageType, Integer sequenceNumber, MACAddress macAddress, String payload) {
this.type = messageType;
this.sequenceNumber = sequenceNumber;
this.macAddress = macAddress;
}
}
- public Message(MessageType messageType, Integer sequenceNumber, String payload) {
+ protected Message(MessageType messageType, Integer sequenceNumber, String payload) {
this(messageType, sequenceNumber, null, payload);
}
- public Message(MessageType messageType, MACAddress macAddress) {
+ protected Message(MessageType messageType, MACAddress macAddress) {
this(messageType, null, macAddress, null);
}
- public Message(MessageType messageType, MACAddress macAddress, String payload) {
+ protected Message(MessageType messageType, MACAddress macAddress, String payload) {
this(messageType, null, macAddress, payload);
}
- public Message(MessageType messageType, String payload) {
+ protected Message(MessageType messageType, String payload) {
this(messageType, null, null, payload);
}
public Message createMessage(MessageType messageType, int sequenceNumber, String payload)
throws IllegalArgumentException {
- switch (messageType) {
- case ACKNOWLEDGEMENT_V1:
- case ACKNOWLEDGEMENT_V2:
- return new AcknowledgementMessage(messageType, sequenceNumber, payload);
- case ANNOUNCE_AWAKE_REQUEST:
- return new AnnounceAwakeRequestMessage(sequenceNumber, payload);
- case BROADCAST_GROUP_SWITCH_RESPONSE:
- return new BroadcastGroupSwitchResponseMessage(sequenceNumber, payload);
- case CLOCK_GET_RESPONSE:
- return new ClockGetResponseMessage(sequenceNumber, payload);
- case DEVICE_INFORMATION_RESPONSE:
- return new InformationResponseMessage(sequenceNumber, payload);
- case DEVICE_ROLE_CALL_RESPONSE:
- return new RoleCallResponseMessage(sequenceNumber, payload);
- case MODULE_JOINED_NETWORK_REQUEST:
- return new ModuleJoinedNetworkRequestMessage(sequenceNumber, payload);
- case NETWORK_STATUS_RESPONSE:
- return new NetworkStatusResponseMessage(sequenceNumber, payload);
- case NODE_AVAILABLE:
- return new NodeAvailableMessage(sequenceNumber, payload);
- case PING_RESPONSE:
- return new PingResponseMessage(sequenceNumber, payload);
- case POWER_BUFFER_RESPONSE:
- return new PowerBufferResponseMessage(sequenceNumber, payload);
- case POWER_CALIBRATION_RESPONSE:
- return new PowerCalibrationResponseMessage(sequenceNumber, payload);
- case POWER_INFORMATION_RESPONSE:
- return new PowerInformationResponseMessage(sequenceNumber, payload);
- case REAL_TIME_CLOCK_GET_RESPONSE:
- return new RealTimeClockGetResponseMessage(sequenceNumber, payload);
- case SENSE_REPORT_REQUEST:
- return new SenseReportRequestMessage(sequenceNumber, payload);
- default:
- throw new IllegalArgumentException("Unsupported message type: " + messageType);
- }
+ return switch (messageType) {
+ case ACKNOWLEDGEMENT_V1, ACKNOWLEDGEMENT_V2 ->
+ new AcknowledgementMessage(messageType, sequenceNumber, payload);
+ case ANNOUNCE_AWAKE_REQUEST -> new AnnounceAwakeRequestMessage(sequenceNumber, payload);
+ case BROADCAST_GROUP_SWITCH_RESPONSE -> new BroadcastGroupSwitchResponseMessage(sequenceNumber, payload);
+ case CLOCK_GET_RESPONSE -> new ClockGetResponseMessage(sequenceNumber, payload);
+ case DEVICE_INFORMATION_RESPONSE -> new InformationResponseMessage(sequenceNumber, payload);
+ case DEVICE_ROLE_CALL_RESPONSE -> new RoleCallResponseMessage(sequenceNumber, payload);
+ case MODULE_JOINED_NETWORK_REQUEST -> new ModuleJoinedNetworkRequestMessage(sequenceNumber, payload);
+ case NETWORK_STATUS_RESPONSE -> new NetworkStatusResponseMessage(sequenceNumber, payload);
+ case NODE_AVAILABLE -> new NodeAvailableMessage(sequenceNumber, payload);
+ case PING_RESPONSE -> new PingResponseMessage(sequenceNumber, payload);
+ case POWER_BUFFER_RESPONSE -> new PowerBufferResponseMessage(sequenceNumber, payload);
+ case POWER_CALIBRATION_RESPONSE -> new PowerCalibrationResponseMessage(sequenceNumber, payload);
+ case POWER_INFORMATION_RESPONSE -> new PowerInformationResponseMessage(sequenceNumber, payload);
+ case REAL_TIME_CLOCK_GET_RESPONSE -> new RealTimeClockGetResponseMessage(sequenceNumber, payload);
+ case SENSE_REPORT_REQUEST -> new SenseReportRequestMessage(sequenceNumber, payload);
+ default -> throw new IllegalArgumentException("Unsupported message type: " + messageType);
+ };
}
}
}
double seconds = localInterval.getSeconds();
- seconds += localInterval.getNano() / ChronoUnit.SECONDS.getDuration().toNanos();
+ seconds += (double) localInterval.getNano() / ChronoUnit.SECONDS.getDuration().toNanos();
return seconds;
}