[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:
parent
6a16c889f2
commit
177ce2a217
@ -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.
|
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.
|
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.
|
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.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ public class NanoleafBindingConstants {
|
|||||||
public static final String CHANNEL_SWIPE_EVENT_LEFT = "LEFT";
|
public static final String CHANNEL_SWIPE_EVENT_LEFT = "LEFT";
|
||||||
public static final String CHANNEL_SWIPE_EVENT_RIGHT = "RIGHT";
|
public static final String CHANNEL_SWIPE_EVENT_RIGHT = "RIGHT";
|
||||||
public static final String CHANNEL_LAYOUT = "layout";
|
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
|
// List of light panel channels
|
||||||
public static final String CHANNEL_PANEL_COLOR = "color";
|
public static final String CHANNEL_PANEL_COLOR = "color";
|
||||||
|
|||||||
@ -669,7 +669,7 @@ public class NanoleafControllerHandler extends BaseBridgeHandler {
|
|||||||
updateProperties();
|
updateProperties();
|
||||||
updateConfiguration();
|
updateConfiguration();
|
||||||
updateLayout(controllerInfo.getPanelLayout());
|
updateLayout(controllerInfo.getPanelLayout());
|
||||||
updateState(controllerInfo.getPanelLayout());
|
updateVisualState(controllerInfo.getPanelLayout());
|
||||||
|
|
||||||
for (NanoleafControllerListener controllerListener : controllerListeners) {
|
for (NanoleafControllerListener controllerListener : controllerListeners) {
|
||||||
controllerListener.onControllerInfoFetched(getThing().getUID(), controllerInfo);
|
controllerListener.onControllerInfoFetched(getThing().getUID(), controllerInfo);
|
||||||
@ -711,16 +711,27 @@ public class NanoleafControllerHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateState(PanelLayout panelLayout) {
|
private void updateVisualState(PanelLayout panelLayout) {
|
||||||
ChannelUID stateChannel = new ChannelUID(getThing().getUID(), CHANNEL_STATE);
|
ChannelUID stateChannel = new ChannelUID(getThing().getUID(), CHANNEL_VISUAL_STATE);
|
||||||
|
|
||||||
Bridge bridge = getThing();
|
Bridge bridge = getThing();
|
||||||
List<Thing> things = bridge.getThings();
|
List<Thing> things = bridge.getThings();
|
||||||
|
if (things == null) {
|
||||||
|
logger.trace("No things to get state from!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LayoutSettings settings = new LayoutSettings(false, true, true, true);
|
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) {
|
if (bytes.length > 0) {
|
||||||
updateState(stateChannel, new RawType(bytes, "image/png"));
|
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;
|
previousPanelLayout = panelLayout;
|
||||||
@ -740,7 +751,8 @@ public class NanoleafControllerHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (previousPanelLayout.equals(panelLayout)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,6 +763,10 @@ public class NanoleafControllerHandler extends BaseBridgeHandler {
|
|||||||
byte[] bytes = NanoleafLayout.render(panelLayout, new PanelState(things), settings);
|
byte[] bytes = NanoleafLayout.render(panelLayout, new PanelState(things), settings);
|
||||||
if (bytes.length > 0) {
|
if (bytes.length > 0) {
|
||||||
updateState(layoutChannel, new RawType(bytes, "image/png"));
|
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;
|
previousPanelLayout = panelLayout;
|
||||||
|
|||||||
@ -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.Layout;
|
||||||
import org.openhab.binding.nanoleaf.internal.model.PanelLayout;
|
import org.openhab.binding.nanoleaf.internal.model.PanelLayout;
|
||||||
import org.openhab.binding.nanoleaf.internal.model.PositionDatum;
|
import org.openhab.binding.nanoleaf.internal.model.PositionDatum;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the Nanoleaf layout to an image.
|
* Renders the Nanoleaf layout to an image.
|
||||||
@ -40,6 +42,7 @@ import org.openhab.binding.nanoleaf.internal.model.PositionDatum;
|
|||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class NanoleafLayout {
|
public class NanoleafLayout {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(NanoleafLayout.class);
|
||||||
private static final Color COLOR_BACKGROUND = Color.WHITE;
|
private static final Color COLOR_BACKGROUND = Color.WHITE;
|
||||||
|
|
||||||
public static byte[] render(PanelLayout panelLayout, PanelState state, LayoutSettings settings) throws IOException {
|
public static byte[] render(PanelLayout panelLayout, PanelState state, LayoutSettings settings) throws IOException {
|
||||||
@ -51,11 +54,13 @@ public class NanoleafLayout {
|
|||||||
|
|
||||||
Layout layout = panelLayout.getLayout();
|
Layout layout = panelLayout.getLayout();
|
||||||
if (layout == null) {
|
if (layout == null) {
|
||||||
|
logger.warn("Returning no image as we don't have any layout to render");
|
||||||
return new byte[] {};
|
return new byte[] {};
|
||||||
}
|
}
|
||||||
|
|
||||||
List<PositionDatum> positionDatums = layout.getPositionData();
|
List<PositionDatum> positionDatums = layout.getPositionData();
|
||||||
if (positionDatums == null) {
|
if (positionDatums == null) {
|
||||||
|
logger.warn("Returning no image as we don't have any position datums to render");
|
||||||
return new byte[] {};
|
return new byte[] {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
import org.openhab.binding.nanoleaf.internal.handler.NanoleafPanelHandler;
|
import org.openhab.binding.nanoleaf.internal.handler.NanoleafPanelHandler;
|
||||||
import org.openhab.core.library.types.HSBType;
|
import org.openhab.core.library.types.HSBType;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the state of the panels.
|
* Stores the state of the panels.
|
||||||
@ -32,6 +34,7 @@ import org.openhab.core.thing.Thing;
|
|||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class PanelState {
|
public class PanelState {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PanelState.class);
|
||||||
private final Map<Integer, HSBType> panelStates = new HashMap<>();
|
private final Map<Integer, HSBType> panelStates = new HashMap<>();
|
||||||
|
|
||||||
public PanelState(List<Thing> panels) {
|
public PanelState(List<Thing> panels) {
|
||||||
@ -40,13 +43,26 @@ public class PanelState {
|
|||||||
NanoleafPanelHandler panelHandler = (NanoleafPanelHandler) panel.getHandler();
|
NanoleafPanelHandler panelHandler = (NanoleafPanelHandler) panel.getHandler();
|
||||||
if (panelHandler != null) {
|
if (panelHandler != null) {
|
||||||
HSBType c = panelHandler.getColor();
|
HSBType c = panelHandler.getColor();
|
||||||
|
|
||||||
|
if (c == null) {
|
||||||
|
logger.trace("Panel {}: Failed to get color", panelId);
|
||||||
|
}
|
||||||
|
|
||||||
HSBType color = (c == null) ? HSBType.BLACK : c;
|
HSBType color = (c == null) ? HSBType.BLACK : c;
|
||||||
panelStates.put(panelId, color);
|
panelStates.put(panelId, color);
|
||||||
|
} else {
|
||||||
|
logger.trace("Panel {}: Couldn't find handler", panelId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HSBType getHSBForPanel(Integer 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);
|
return panelStates.getOrDefault(panelId, HSBType.BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,8 +40,8 @@ channel-type.nanoleaf.swipe.label = Swipe
|
|||||||
channel-type.nanoleaf.swipe.description = Swipe over the panels
|
channel-type.nanoleaf.swipe.description = Swipe over the panels
|
||||||
channel-type.nanoleaf.layout.label = Layout
|
channel-type.nanoleaf.layout.label = Layout
|
||||||
channel-type.nanoleaf.layout.description = Layout of the panels
|
channel-type.nanoleaf.layout.description = Layout of the panels
|
||||||
channel-type.nanoleaf.state.label = State
|
channel-type.nanoleaf.state.label = Visual State
|
||||||
channel-type.nanoleaf.state.description = Current state of the panels
|
channel-type.nanoleaf.state.description = Current visual state of the panels
|
||||||
|
|
||||||
# error messages
|
# error messages
|
||||||
error.nanoleaf.controller.noIp = IP/host address and/or port are not configured for the controller.
|
error.nanoleaf.controller.noIp = IP/host address and/or port are not configured for the controller.
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
<channel id="rhythmMode" typeId="rhythmMode"/>
|
<channel id="rhythmMode" typeId="rhythmMode"/>
|
||||||
<channel id="swipe" typeId="swipe"/>
|
<channel id="swipe" typeId="swipe"/>
|
||||||
<channel id="layout" typeId="layout"/>
|
<channel id="layout" typeId="layout"/>
|
||||||
<channel id="currentState" typeId="state"/>
|
<channel id="visualState" typeId="visualState"/>
|
||||||
</channels>
|
</channels>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -115,7 +115,7 @@
|
|||||||
<description>@text/channel-type.nanoleaf.layout.description</description>
|
<description>@text/channel-type.nanoleaf.layout.description</description>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="state">
|
<channel-type id="visualState">
|
||||||
<item-type>Image</item-type>
|
<item-type>Image</item-type>
|
||||||
<label>@text/channel-type.nanoleaf.state.label</label>
|
<label>@text/channel-type.nanoleaf.state.label</label>
|
||||||
<description>@text/channel-type.nanoleaf.state.description</description>
|
<description>@text/channel-type.nanoleaf.state.description</description>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user