From 177ce2a217bf8fe47abd1993cf99d4defe6ff711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Austvik?= Date: Thu, 8 Dec 2022 21:00:11 +0100 Subject: [PATCH] [Nanolaef] Visual State Bugfix (#13880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Nanoleaf Visual State fix Fix the visual state channel name. Also: - Better name (from state to visual state) of the (new) channel - Better logs which has helped us debug the problem - Some more information on when it will work in the README Signed-off-by: Jørgen Austvik --- .../org.openhab.binding.nanoleaf/README.md | 2 ++ .../internal/NanoleafBindingConstants.java | 2 +- .../handler/NanoleafControllerHandler.java | 26 +++++++++++++++---- .../internal/layout/NanoleafLayout.java | 5 ++++ .../nanoleaf/internal/layout/PanelState.java | 16 ++++++++++++ .../resources/OH-INF/i18n/nanoleaf.properties | 4 +-- .../resources/OH-INF/thing/lightpanels.xml | 4 +-- 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/bundles/org.openhab.binding.nanoleaf/README.md b/bundles/org.openhab.binding.nanoleaf/README.md index c7220da82f6..c6226731fed 100644 --- a/bundles/org.openhab.binding.nanoleaf/README.md +++ b/bundles/org.openhab.binding.nanoleaf/README.md @@ -110,6 +110,8 @@ Compare the following output with the right picture at the beginning of the arti The state channel shows an image of the panels on the wall. You have to configure things for each panel to get the correct color. Since the colors of the panels can make it difficult to see the panel ids, please use the layout channel where the background color is always white to identify them. +For state to work, you need to set static colors to your panel. +This is because Nanoleaf does not return updates on colors for dynamic effects and animations. ![Image](doc/NanoCanvas_rendered.jpg) diff --git a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/NanoleafBindingConstants.java b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/NanoleafBindingConstants.java index db83c1fd789..5109d8abce3 100644 --- a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/NanoleafBindingConstants.java +++ b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/NanoleafBindingConstants.java @@ -59,7 +59,7 @@ public class NanoleafBindingConstants { public static final String CHANNEL_SWIPE_EVENT_LEFT = "LEFT"; public static final String CHANNEL_SWIPE_EVENT_RIGHT = "RIGHT"; public static final String CHANNEL_LAYOUT = "layout"; - public static final String CHANNEL_STATE = "state"; + public static final String CHANNEL_VISUAL_STATE = "visualState"; // List of light panel channels public static final String CHANNEL_PANEL_COLOR = "color"; diff --git a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/handler/NanoleafControllerHandler.java b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/handler/NanoleafControllerHandler.java index d37a82f06c7..cd34d655d75 100644 --- a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/handler/NanoleafControllerHandler.java +++ b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/handler/NanoleafControllerHandler.java @@ -669,7 +669,7 @@ public class NanoleafControllerHandler extends BaseBridgeHandler { updateProperties(); updateConfiguration(); updateLayout(controllerInfo.getPanelLayout()); - updateState(controllerInfo.getPanelLayout()); + updateVisualState(controllerInfo.getPanelLayout()); for (NanoleafControllerListener controllerListener : controllerListeners) { controllerListener.onControllerInfoFetched(getThing().getUID(), controllerInfo); @@ -711,16 +711,27 @@ public class NanoleafControllerHandler extends BaseBridgeHandler { } } - private void updateState(PanelLayout panelLayout) { - ChannelUID stateChannel = new ChannelUID(getThing().getUID(), CHANNEL_STATE); + private void updateVisualState(PanelLayout panelLayout) { + ChannelUID stateChannel = new ChannelUID(getThing().getUID(), CHANNEL_VISUAL_STATE); Bridge bridge = getThing(); List things = bridge.getThings(); + if (things == null) { + logger.trace("No things to get state from!"); + return; + } + try { LayoutSettings settings = new LayoutSettings(false, true, true, true); - byte[] bytes = NanoleafLayout.render(panelLayout, new PanelState(things), settings); + logger.trace("Getting panel state for {} things", things.size()); + PanelState panelState = new PanelState(things); + byte[] bytes = NanoleafLayout.render(panelLayout, panelState, settings); if (bytes.length > 0) { updateState(stateChannel, new RawType(bytes, "image/png")); + logger.trace("Rendered visual state of panel {} in updateState has {} bytes", getThing().getUID(), + bytes.length); + } else { + logger.debug("Visual state of {} failed to produce any image", getThing().getUID()); } previousPanelLayout = panelLayout; @@ -740,7 +751,8 @@ public class NanoleafControllerHandler extends BaseBridgeHandler { } if (previousPanelLayout.equals(panelLayout)) { - logger.trace("Not rendering panel layout as it is the same as previous rendered panel layout"); + logger.trace("Not rendering panel layout for {} as it is the same as previous rendered panel layout", + getThing().getUID()); return; } @@ -751,6 +763,10 @@ public class NanoleafControllerHandler extends BaseBridgeHandler { byte[] bytes = NanoleafLayout.render(panelLayout, new PanelState(things), settings); if (bytes.length > 0) { updateState(layoutChannel, new RawType(bytes, "image/png")); + logger.trace("Rendered layout of panel {} in updateState has {} bytes", getThing().getUID(), + bytes.length); + } else { + logger.debug("Layout of {} failed to produce any image", getThing().getUID()); } previousPanelLayout = panelLayout; diff --git a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/NanoleafLayout.java b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/NanoleafLayout.java index 61ceaa5497d..ebdb4ffe991 100644 --- a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/NanoleafLayout.java +++ b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/NanoleafLayout.java @@ -31,6 +31,8 @@ import org.openhab.binding.nanoleaf.internal.model.GlobalOrientation; import org.openhab.binding.nanoleaf.internal.model.Layout; import org.openhab.binding.nanoleaf.internal.model.PanelLayout; import org.openhab.binding.nanoleaf.internal.model.PositionDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Renders the Nanoleaf layout to an image. @@ -40,6 +42,7 @@ import org.openhab.binding.nanoleaf.internal.model.PositionDatum; @NonNullByDefault public class NanoleafLayout { + private static final Logger logger = LoggerFactory.getLogger(NanoleafLayout.class); private static final Color COLOR_BACKGROUND = Color.WHITE; public static byte[] render(PanelLayout panelLayout, PanelState state, LayoutSettings settings) throws IOException { @@ -51,11 +54,13 @@ public class NanoleafLayout { Layout layout = panelLayout.getLayout(); if (layout == null) { + logger.warn("Returning no image as we don't have any layout to render"); return new byte[] {}; } List positionDatums = layout.getPositionData(); if (positionDatums == null) { + logger.warn("Returning no image as we don't have any position datums to render"); return new byte[] {}; } diff --git a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/PanelState.java b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/PanelState.java index fba1804fe85..02c6a7a947d 100644 --- a/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/PanelState.java +++ b/bundles/org.openhab.binding.nanoleaf/src/main/java/org/openhab/binding/nanoleaf/internal/layout/PanelState.java @@ -23,6 +23,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.nanoleaf.internal.handler.NanoleafPanelHandler; import org.openhab.core.library.types.HSBType; import org.openhab.core.thing.Thing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Stores the state of the panels. @@ -32,6 +34,7 @@ import org.openhab.core.thing.Thing; @NonNullByDefault public class PanelState { + private static final Logger logger = LoggerFactory.getLogger(PanelState.class); private final Map panelStates = new HashMap<>(); public PanelState(List panels) { @@ -40,13 +43,26 @@ public class PanelState { NanoleafPanelHandler panelHandler = (NanoleafPanelHandler) panel.getHandler(); if (panelHandler != null) { HSBType c = panelHandler.getColor(); + + if (c == null) { + logger.trace("Panel {}: Failed to get color", panelId); + } + HSBType color = (c == null) ? HSBType.BLACK : c; panelStates.put(panelId, color); + } else { + logger.trace("Panel {}: Couldn't find handler", panelId); } } } public HSBType getHSBForPanel(Integer panelId) { + if (logger.isTraceEnabled()) { + if (!panelStates.containsKey(panelId)) { + logger.trace("Failed to get color for panel {}, falling back to black", panelId); + } + } + return panelStates.getOrDefault(panelId, HSBType.BLACK); } } diff --git a/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/i18n/nanoleaf.properties b/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/i18n/nanoleaf.properties index a730c5089d6..f1cd2dac08e 100644 --- a/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/i18n/nanoleaf.properties +++ b/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/i18n/nanoleaf.properties @@ -40,8 +40,8 @@ channel-type.nanoleaf.swipe.label = Swipe channel-type.nanoleaf.swipe.description = Swipe over the panels channel-type.nanoleaf.layout.label = Layout channel-type.nanoleaf.layout.description = Layout of the panels -channel-type.nanoleaf.state.label = State -channel-type.nanoleaf.state.description = Current state of the panels +channel-type.nanoleaf.state.label = Visual State +channel-type.nanoleaf.state.description = Current visual state of the panels # error messages error.nanoleaf.controller.noIp = IP/host address and/or port are not configured for the controller. diff --git a/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/thing/lightpanels.xml b/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/thing/lightpanels.xml index d5ac6ea23e5..52228fb02bd 100644 --- a/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/thing/lightpanels.xml +++ b/bundles/org.openhab.binding.nanoleaf/src/main/resources/OH-INF/thing/lightpanels.xml @@ -19,7 +19,7 @@ - + @@ -115,7 +115,7 @@ @text/channel-type.nanoleaf.layout.description - + Image @text/channel-type.nanoleaf.state.description