[Nanolaef] Visual State Bugfix (#13880)

* 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 <jaustvik@acm.org>
This commit is contained in:
Jørgen Austvik
2022-12-08 21:00:11 +01:00
committed by GitHub
parent 6a16c889f2
commit 177ce2a217
7 changed files with 49 additions and 10 deletions

View File

@@ -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";

View File

@@ -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<Thing> 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;

View File

@@ -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<PositionDatum> positionDatums = layout.getPositionData();
if (positionDatums == null) {
logger.warn("Returning no image as we don't have any position datums to render");
return new byte[] {};
}

View File

@@ -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<Integer, HSBType> panelStates = new HashMap<>();
public PanelState(List<Thing> 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);
}
}

View File

@@ -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.

View File

@@ -19,7 +19,7 @@
<channel id="rhythmMode" typeId="rhythmMode"/>
<channel id="swipe" typeId="swipe"/>
<channel id="layout" typeId="layout"/>
<channel id="currentState" typeId="state"/>
<channel id="visualState" typeId="visualState"/>
</channels>
<properties>
@@ -115,7 +115,7 @@
<description>@text/channel-type.nanoleaf.layout.description</description>
</channel-type>
<channel-type id="state">
<channel-type id="visualState">
<item-type>Image</item-type>
<label>@text/channel-type.nanoleaf.state.label</label>
<description>@text/channel-type.nanoleaf.state.description</description>