diff --git a/bundles/org.openhab.binding.pilight/pom.xml b/bundles/org.openhab.binding.pilight/pom.xml index 54e96f45dc702..1acde190f7394 100644 --- a/bundles/org.openhab.binding.pilight/pom.xml +++ b/bundles/org.openhab.binding.pilight/pom.xml @@ -14,22 +14,4 @@ openHAB Add-ons :: Bundles :: Pilight Binding - - - com.fasterxml.jackson.core - jackson-databind - 2.10.4 - - - com.fasterxml.jackson.core - jackson-annotations - 2.10.4 - - - com.fasterxml.jackson.core - jackson-core - 2.10.4 - - - diff --git a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightConnector.java b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightConnector.java index 264dc58f42374..fbdd88a3ae50d 100644 --- a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightConnector.java +++ b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/PilightConnector.java @@ -78,30 +78,33 @@ public void run() { while (!Thread.currentThread().isInterrupted()) { try { - final Socket socket = this.socket; + final @Nullable Socket socket = this.socket; if (socket != null && !socket.isClosed()) { try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) { String line = in.readLine(); while (!Thread.currentThread().isInterrupted() && line != null) { if (!line.isEmpty()) { logger.trace("Received from pilight: {}", line); + final ObjectMapper inputMapper = this.inputMapper; if (line.startsWith("{\"message\":\"config\"")) { - callback.configReceived(inputMapper.readValue(line, Message.class).getConfig()); + final @Nullable Message message = inputMapper.readValue(line, Message.class); + callback.configReceived(message.getConfig()); } else if (line.startsWith("{\"message\":\"values\"")) { - AllStatus status = inputMapper.readValue(line, AllStatus.class); + final @Nullable AllStatus status = inputMapper.readValue(line, AllStatus.class); callback.statusReceived(status.getValues()); } else if (line.startsWith("{\"version\":")) { - Version version = inputMapper.readValue(line, Version.class); + final @Nullable Version version = inputMapper.readValue(line, Version.class); callback.versionReceived(version); } else if (line.startsWith("{\"status\":")) { - Response response = inputMapper.readValue(line, Response.class); + // currently unused } else if (line.equals("1")) { throw new IOException("Connection to pilight lost"); } else { - Status status = inputMapper.readValue(line, Status.class); + final @Nullable Status status = inputMapper.readValue(line, Status.class); callback.statusReceived(Collections.singletonList(status)); } } + line = in.readLine(); } } @@ -151,13 +154,13 @@ public void close() { } private void disconnect() { - final PrintStream printStream = this.printStream; + final @Nullable PrintStream printStream = this.printStream; if (printStream != null) { printStream.close(); this.printStream = null; } - final Socket socket = this.socket; + final @Nullable Socket socket = this.socket; if (socket != null) { try { socket.close(); @@ -169,7 +172,7 @@ private void disconnect() { } private boolean isConnected() { - final Socket socket = this.socket; + final @Nullable Socket socket = this.socket; return socket != null && !socket.isClosed(); } @@ -195,7 +198,7 @@ private void connect() throws InterruptedException { PrintStream printStream = new PrintStream(socket.getOutputStream(), true); printStream.println(outputMapper.writeValueAsString(identification)); - Response response = inputMapper.readValue(socket.getInputStream(), Response.class); + final @Nullable Response response = inputMapper.readValue(socket.getInputStream(), Response.class); if (response.getStatus().equals(Response.SUCCESS)) { logger.debug("Established connection to pilight server at {}:{}", config.getIpAddress(), @@ -209,7 +212,10 @@ private void connect() throws InterruptedException { logger.debug("pilight client not accepted: {}", response.getStatus()); } } catch (IOException e) { - this.printStream.close(); + final @Nullable PrintStream printStream = this.printStream; + if (printStream != null) { + printStream.close(); + } logger.debug("connect failed: {}", e.getMessage()); callback.updateThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); } @@ -225,14 +231,17 @@ private void connect() throws InterruptedException { */ public void sendAction(Action action) { delayedActionQueue.add(action); + final @Nullable ScheduledFuture delayedActionWorkerFuture = this.delayedActionWorkerFuture; if (delayedActionWorkerFuture == null || delayedActionWorkerFuture.isCancelled()) { - delayedActionWorkerFuture = scheduler.scheduleWithFixedDelay(() -> { + this.delayedActionWorkerFuture = scheduler.scheduleWithFixedDelay(() -> { if (!delayedActionQueue.isEmpty()) { doSendAction(delayedActionQueue.poll()); } else { - delayedActionWorkerFuture.cancel(false); - delayedActionWorkerFuture = null; + if (delayedActionWorkerFuture != null) { + delayedActionWorkerFuture.cancel(false); + } + this.delayedActionWorkerFuture = null; } }, 0, config.getDelay(), TimeUnit.MILLISECONDS); } diff --git a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightBridgeDiscoveryService.java b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightBridgeDiscoveryService.java index 7be850b85545b..67cb46bd87b6e 100644 --- a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightBridgeDiscoveryService.java +++ b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightBridgeDiscoveryService.java @@ -18,7 +18,6 @@ import java.util.*; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -84,39 +83,40 @@ protected void startScan() { ssdp.send(sendPack); ssdp.setSoTimeout(SSDP_WAIT_TIMEOUT); - final AtomicBoolean loop = new AtomicBoolean(true); - while (loop.get()) { + boolean loop = true; + while (loop) { DatagramPacket recvPack = new DatagramPacket(new byte[1024], 1024); ssdp.receive(recvPack); byte[] recvData = recvPack.getData(); final Scanner scanner = new Scanner(new ByteArrayInputStream(recvData), StandardCharsets.UTF_8); - scanner.findAll("Location:([0-9.]+):(.*)").forEach(matchResult -> { + loop = scanner.findAll("Location:([0-9.]+):(.*)").peek(matchResult -> { final String server = matchResult.group(1); final Integer port = Integer.parseInt(matchResult.group(2)); + final String bridgeName = server.replace(".", "") + "" + port; logger.debug("Found pilight daemon at {}:{}", server, port); Map properties = new HashMap<>(); properties.put(PilightBindingConstants.PROPERTY_IP_ADDRESS, server); properties.put(PilightBindingConstants.PROPERTY_PORT, port); + properties.put(PilightBindingConstants.PROPERTY_NAME, bridgeName); - ThingUID uid = new ThingUID(PilightBindingConstants.THING_TYPE_BRIDGE, - server.replace(".", "") + "" + port); + ThingUID uid = new ThingUID(PilightBindingConstants.THING_TYPE_BRIDGE, bridgeName); DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties) + .withRepresentationProperty(PilightBindingConstants.PROPERTY_NAME) .withLabel("Pilight Bridge (" + server + ")").build(); thingDiscovered(result); - loop.set(false); - }); + }).count() == 0; } } } } } catch (IOException e) { - if (!e.getMessage().equals("Receive timed out")) { + if (e.getMessage() != null && !"Receive timed out".equals(e.getMessage())) { logger.warn("Unable to enumerate the local network interfaces {}", e.getMessage()); } } @@ -131,8 +131,9 @@ protected synchronized void stopScan() { @Override protected void startBackgroundDiscovery() { logger.debug("Start Pilight device background discovery"); + final @Nullable ScheduledFuture backgroundDiscoveryJob = this.backgroundDiscoveryJob; if (backgroundDiscoveryJob == null || backgroundDiscoveryJob.isCancelled()) { - backgroundDiscoveryJob = scheduler.scheduleWithFixedDelay(this::startScan, 5, + this.backgroundDiscoveryJob = scheduler.scheduleWithFixedDelay(this::startScan, 5, AUTODISCOVERY_BACKGROUND_SEARCH_INTERVAL_SEC, TimeUnit.SECONDS); } } @@ -140,9 +141,10 @@ protected void startBackgroundDiscovery() { @Override protected void stopBackgroundDiscovery() { logger.debug("Stop Pilight device background discovery"); + final @Nullable ScheduledFuture backgroundDiscoveryJob = this.backgroundDiscoveryJob; if (backgroundDiscoveryJob != null) { backgroundDiscoveryJob.cancel(true); - backgroundDiscoveryJob = null; + this.backgroundDiscoveryJob = null; } } } diff --git a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightDeviceDiscoveryService.java b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightDeviceDiscoveryService.java index 1b59ffb80ae8e..c735a976e36a5 100644 --- a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightDeviceDiscoveryService.java +++ b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/discovery/PilightDeviceDiscoveryService.java @@ -29,12 +29,10 @@ import org.openhab.core.config.discovery.AbstractDiscoveryService; import org.openhab.core.config.discovery.DiscoveryResult; import org.openhab.core.config.discovery.DiscoveryResultBuilder; -import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandlerService; -import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +43,6 @@ * @author Niklas Dörfler - Initial contribution */ @NonNullByDefault -@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.pilight") public class PilightDeviceDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService { private static final Set SUPPORTED_THING_TYPES_UIDS = PilightHandlerFactory.SUPPORTED_THING_TYPES_UIDS; @@ -79,7 +76,7 @@ protected void startScan() { config.getDevices().forEach((deviceId, device) -> { if (this.pilightBridgeHandler != null) { final Optional status = allStatus.stream() - .filter(s -> deviceId.equals(s.getDevices().get(0))).findFirst(); + .filter(s -> s.getDevices().contains(deviceId)).findFirst(); final ThingTypeUID thingTypeUID; final String typeString; @@ -106,29 +103,37 @@ protected void startScan() { typeString = "Generic"; } - final ThingUID thingUID = new ThingUID(thingTypeUID, - this.pilightBridgeHandler.getThing().getUID(), deviceId); + final @Nullable PilightBridgeHandler pilightBridgeHandler = this.pilightBridgeHandler; + if (pilightBridgeHandler != null) { + final ThingUID thingUID = new ThingUID(thingTypeUID, + pilightBridgeHandler.getThing().getUID(), deviceId); - final Map properties = new HashMap<>(); - properties.put(PROPERTY_NAME, deviceId); + final Map properties = new HashMap<>(); + properties.put(PROPERTY_NAME, deviceId); - DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID) - .withThingType(thingTypeUID).withProperties(properties).withBridge(bridgeUID) - .withRepresentationProperty(deviceId) - .withLabel("Pilight " + typeString + " Device '" + deviceId + "'").build(); + DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID) + .withThingType(thingTypeUID).withProperties(properties).withBridge(bridgeUID) + .withRepresentationProperty(PROPERTY_NAME) + .withLabel("Pilight " + typeString + " Device '" + deviceId + "'").build(); - thingDiscovered(discoveryResult); + thingDiscovered(discoveryResult); + } } }); }); - pilightBridgeHandler.refreshConfigAndStatus(); + final @Nullable PilightBridgeHandler pilightBridgeHandler = this.pilightBridgeHandler; + if (pilightBridgeHandler != null) { + pilightBridgeHandler.refreshConfigAndStatus(); + } } } @Override protected synchronized void stopScan() { super.stopScan(); + configFuture.cancel(true); + statusFuture.cancel(true); if (bridgeUID != null) { removeOlderResults(getTimestampOfLastScan(), bridgeUID); } @@ -137,8 +142,9 @@ protected synchronized void stopScan() { @Override protected void startBackgroundDiscovery() { logger.debug("Start Pilight device background discovery"); + final @Nullable ScheduledFuture backgroundDiscoveryJob = this.backgroundDiscoveryJob; if (backgroundDiscoveryJob == null || backgroundDiscoveryJob.isCancelled()) { - backgroundDiscoveryJob = scheduler.scheduleWithFixedDelay(this::startScan, 20, + this.backgroundDiscoveryJob = scheduler.scheduleWithFixedDelay(this::startScan, 20, AUTODISCOVERY_BACKGROUND_SEARCH_INTERVAL_SEC, TimeUnit.SECONDS); } } @@ -146,17 +152,21 @@ protected void startBackgroundDiscovery() { @Override protected void stopBackgroundDiscovery() { logger.debug("Stop Pilight device background discovery"); + final @Nullable ScheduledFuture backgroundDiscoveryJob = this.backgroundDiscoveryJob; if (backgroundDiscoveryJob != null) { backgroundDiscoveryJob.cancel(true); - backgroundDiscoveryJob = null; + this.backgroundDiscoveryJob = null; } } @Override public void setThingHandler(final ThingHandler handler) { if (handler instanceof PilightBridgeHandler) { - pilightBridgeHandler = (PilightBridgeHandler) handler; - bridgeUID = pilightBridgeHandler.getThing().getUID(); + this.pilightBridgeHandler = (PilightBridgeHandler) handler; + final @Nullable PilightBridgeHandler pilightBridgeHandler = this.pilightBridgeHandler; + if (pilightBridgeHandler != null) { + bridgeUID = pilightBridgeHandler.getThing().getUID(); + } } } @@ -168,6 +178,7 @@ public void setThingHandler(final ThingHandler handler) { @Override public void activate() { super.activate(null); + final @Nullable PilightBridgeHandler pilightBridgeHandler = this.pilightBridgeHandler; if (pilightBridgeHandler != null) { pilightBridgeHandler.registerDiscoveryListener(this); } @@ -179,6 +190,7 @@ public void deactivate() { removeOlderResults(getTimestampOfLastScan(), bridgeUID); } + final @Nullable PilightBridgeHandler pilightBridgeHandler = this.pilightBridgeHandler; if (pilightBridgeHandler != null) { pilightBridgeHandler.unregisterDiscoveryListener(); } @@ -192,9 +204,7 @@ public void deactivate() { * @param config config to get */ public void setConfig(Config config) { - if (!configFuture.isDone()) { - configFuture.complete(config); - } + configFuture.complete(config); } /** @@ -203,9 +213,7 @@ public void setConfig(Config config) { * @param status list of status objects */ public void setStatus(List status) { - if (!statusFuture.isDone()) { - statusFuture.complete(status); - } + statusFuture.complete(status); } @Override diff --git a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightBridgeHandler.java b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightBridgeHandler.java index 3f0651db23459..dfcfd9fdfd087 100644 --- a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightBridgeHandler.java +++ b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightBridgeHandler.java @@ -73,6 +73,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { PilightBridgeConfiguration config = getConfigAs(PilightBridgeConfiguration.class); + final @Nullable PilightDeviceDiscoveryService discoveryService = this.discoveryService; PilightConnector connector = new PilightConnector(config, new IPilightCallback() { @Override public void updateThingStatus(ThingStatus status, ThingStatusDetail statusDetail, @@ -224,6 +225,7 @@ private void processConfig(Config config) { } } + final @Nullable PilightDeviceDiscoveryService discoveryService = this.discoveryService; if (discoveryService != null) { discoveryService.setConfig(config); } diff --git a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightGenericHandler.java b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightGenericHandler.java index d66af6605cac1..21adaa309dd91 100644 --- a/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightGenericHandler.java +++ b/bundles/org.openhab.binding.pilight/src/main/java/org/openhab/binding/pilight/internal/handler/PilightGenericHandler.java @@ -33,6 +33,7 @@ import org.openhab.core.thing.type.ChannelTypeUID; import org.openhab.core.types.Command; import org.openhab.core.types.State; +import org.openhab.core.types.StateDescription; import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -120,14 +121,16 @@ private void initializeReadOnlyChannels() { logger.debug("initializeReadOnly {} {}", channelType, channelType.getState()); } - if (channelType != null && channelType.getState() != null) { - channelReadOnlyMap.putIfAbsent(channel.getUID(), channelType.getState().isReadOnly()); + if (channelType != null) { + final @Nullable StateDescription state = channelType.getState(); + if (state != null) { + channelReadOnlyMap.putIfAbsent(channel.getUID(), state.isReadOnly()); + } } } } } - @SuppressWarnings("null") private boolean isChannelReadOnly(ChannelUID channelUID) { Boolean isReadOnly = channelReadOnlyMap.get(channelUID); return isReadOnly != null ? isReadOnly : true; diff --git a/bundles/org.openhab.binding.pilight/src/main/resources/OH-INF/thing/devices.xml b/bundles/org.openhab.binding.pilight/src/main/resources/OH-INF/thing/devices.xml index 1dad29d3c104b..c55db4011e493 100644 --- a/bundles/org.openhab.binding.pilight/src/main/resources/OH-INF/thing/devices.xml +++ b/bundles/org.openhab.binding.pilight/src/main/resources/OH-INF/thing/devices.xml @@ -13,7 +13,7 @@ Pilight Switch - + @@ -43,7 +43,7 @@ Pilight Dimmer - + @@ -67,18 +67,6 @@ - - Dimmer - - Dim level of pilight dimmer. - - - - Switch - - Power ON/OFF the pilight switch. - - String