diff --git a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/AwtrixLightBindingConstants.java b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/AwtrixLightBindingConstants.java index 11cc13511da8..50dd9cb97fa7 100644 --- a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/AwtrixLightBindingConstants.java +++ b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/AwtrixLightBindingConstants.java @@ -155,7 +155,10 @@ public class AwtrixLightBindingConstants { public static final String CHANNEL_FADE_TEXT = "fadeText"; public static final String CHANNEL_GRADIENT_COLOR = "gradientColor"; public static final String CHANNEL_ICON = "icon"; + public static final String CHANNEL_LIFETIME = "lifetime"; + public static final String CHANNEL_LIFETIME_MODE = "lifetimeMode"; public static final String CHANNEL_LINE = "line"; + public static final String CHANNEL_OVERLAY = "overlay"; public static final String CHANNEL_PROGRESS = "progress"; public static final String CHANNEL_PROGRESSC = "progressColor"; public static final String CHANNEL_PROGRESSBC = "progressBackground"; diff --git a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/Helper.java b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/Helper.java index 74aa4939ce03..ac7c8a75b1ec 100644 --- a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/Helper.java +++ b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/Helper.java @@ -164,4 +164,15 @@ private static BigDecimal[] decodeJsonPrimitiveArray(JsonArray jsonArray) { } return array; } + + public static BigDecimal[] leftTrim(BigDecimal[] data, int length) { + if (length < data.length) { + BigDecimal[] trimmed = new BigDecimal[length]; + for (int i = data.length - length; i < data.length; i++) { + trimmed[i - (data.length - length)] = data[i]; + } + return trimmed; + } + return data; + } } diff --git a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/app/AwtrixApp.java b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/app/AwtrixApp.java index f6b4129b64b3..96777dfc4874 100644 --- a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/app/AwtrixApp.java +++ b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/app/AwtrixApp.java @@ -47,8 +47,11 @@ public class AwtrixApp { public static final BigDecimal DEFAULT_PUSHICON = BigDecimal.ZERO; public static final BigDecimal DEFAULT_DURATION = new BigDecimal(7); public static final BigDecimal[] DEFAULT_LINE = {}; + public static final BigDecimal DEFAULT_LIFETIME = BigDecimal.ZERO; + public static final BigDecimal DEFAULT_LIFETIME_MODE = BigDecimal.ZERO; public static final BigDecimal[] DEFAULT_BAR = {}; public static final boolean DEFAULT_AUTOSCALE = true; + public static final String DEFAULT_OVERLAY = "Clear"; public static final BigDecimal DEFAULT_PROGRESS = MINUSONE; public static final BigDecimal[] DEFAULT_PROGRESSC = {}; public static final BigDecimal[] DEFAULT_PROGRESSBC = {}; @@ -73,8 +76,11 @@ public class AwtrixApp { private BigDecimal pushIcon = DEFAULT_PUSHICON; private BigDecimal duration = DEFAULT_DURATION; private BigDecimal[] line = DEFAULT_LINE; + private BigDecimal lifetime = DEFAULT_LIFETIME; + private BigDecimal lifetimeMode = DEFAULT_LIFETIME_MODE; private BigDecimal[] bar = DEFAULT_BAR; private boolean autoscale = DEFAULT_AUTOSCALE; + private String overlay = DEFAULT_OVERLAY; private BigDecimal progress = DEFAULT_PROGRESS; private BigDecimal[] progressC = DEFAULT_PROGRESSC; private BigDecimal[] progressBC = DEFAULT_PROGRESSBC; @@ -102,8 +108,11 @@ public void updateFields(Map params) { this.pushIcon = getNumberValue(params, "pushIcon", DEFAULT_PUSHICON); this.duration = getNumberValue(params, "duration", DEFAULT_DURATION); this.line = getNumberArrayValue(params, "line", DEFAULT_LINE); + this.lifetime = getNumberValue(params, "lifetime", DEFAULT_LIFETIME); + this.lifetimeMode = getNumberValue(params, "lifetimeMode", DEFAULT_LIFETIME_MODE); this.bar = getNumberArrayValue(params, "bar", DEFAULT_BAR); this.autoscale = getBoolValue(params, "autoscale", DEFAULT_AUTOSCALE); + this.overlay = getStringValue(params, "overlay", DEFAULT_OVERLAY); this.progress = getNumberValue(params, "progress", DEFAULT_PROGRESS); this.progressC = getNumberArrayValue(params, "progressC", DEFAULT_PROGRESSC); this.progressBC = getNumberArrayValue(params, "progressBC", DEFAULT_PROGRESSBC); @@ -120,29 +129,6 @@ public void updateFields(Map params) { this.effectBlend = getBoolValue(params, "effectBlend", DEFAULT_EFFECTBLEND); } - protected Map getAppParams() { - Map fields = new HashMap(); - fields.put("text", this.text); - fields.put("textCase", this.textCase); - fields.put("topText", this.topText); - fields.put("textOffset", this.textOffset); - fields.put("center", this.center); - fields.putAll(getColorConfig()); - fields.putAll(getTextEffectConfig()); - fields.putAll(getBackgroundConfig()); - fields.putAll(getIconConfig()); - fields.put("duration", this.duration); - fields.putAll(getGraphConfig()); - fields.putAll(getProgressConfig()); - if (this.scrollSpeed.compareTo(BigDecimal.ZERO) == 0) { - fields.put("noScroll", true); - } else { - fields.put("scrollSpeed", this.scrollSpeed); - } - fields.putAll(getEffectConfig()); - return fields; - } - public String getAppConfig() { Map fields = getAppParams(); return Helper.encodeJson(fields); @@ -268,6 +254,22 @@ public void setLine(BigDecimal[] line) { this.line = line; } + public BigDecimal getLifetime() { + return this.lifetime; + } + + public void setLifetime(BigDecimal lifetime) { + this.lifetime = lifetime; + } + + public BigDecimal getLifetimeMode() { + return this.lifetimeMode; + } + + public void setLifetimeMode(BigDecimal lifetimeMode) { + this.lifetimeMode = lifetimeMode; + } + public BigDecimal[] getBar() { return this.bar; } @@ -284,6 +286,14 @@ public void setAutoscale(Boolean autoscale) { this.autoscale = autoscale; } + public String getOverlay() { + return this.overlay; + } + + public void setOverlay(String overlay) { + this.overlay = overlay; + } + public BigDecimal getProgress() { return this.progress; } @@ -358,13 +368,40 @@ public String toString() { + textOffset + ", center=" + center + ", color=" + Arrays.toString(color) + ", gradient=" + Arrays.toString(gradient) + ", blinkText=" + blinkText + ", fadeText=" + fadeText + ", background=" + Arrays.toString(background) + ", rainbow=" + rainbow + ", icon=" + icon + ", pushIcon=" + pushIcon - + ", duration=" + duration + ", line=" + Arrays.toString(line) + ", bar=" + Arrays.toString(bar) - + ", autoscale=" + autoscale + ", progress=" + progress + ", progressC=" + Arrays.toString(progressC) + + ", duration=" + duration + ", line=" + Arrays.toString(line) + ", lifetime=" + lifetime + + ", lifetimeMode=" + lifetimeMode + ", bar=" + Arrays.toString(bar) + ", autoscale=" + autoscale + + ", overlay=" + overlay + ", progress=" + progress + ", progressC=" + Arrays.toString(progressC) + ", progressBC=" + Arrays.toString(progressBC) + ", scrollSpeed=" + scrollSpeed + ", effect=" + effect + ", effectSpeed=" + effectSpeed + ", effectPalette=" + effectPalette + ", effectBlend=" + effectBlend + "]"; } + protected Map getAppParams() { + Map fields = new HashMap(); + fields.put("text", this.text); + fields.put("textCase", this.textCase); + fields.put("topText", this.topText); + fields.put("textOffset", this.textOffset); + fields.put("center", this.center); + fields.put("lifetime", this.lifetime); + fields.put("lifetimeMode", this.lifetimeMode); + fields.put("overlay", this.overlay); + fields.putAll(getColorConfig()); + fields.putAll(getTextEffectConfig()); + fields.putAll(getBackgroundConfig()); + fields.putAll(getIconConfig()); + fields.put("duration", this.duration); + fields.putAll(getGraphConfig()); + fields.putAll(getProgressConfig()); + if (this.scrollSpeed.compareTo(BigDecimal.ZERO) == 0) { + fields.put("noScroll", true); + } else { + fields.put("scrollSpeed", this.scrollSpeed); + } + fields.putAll(getEffectConfig()); + return fields; + } + private boolean getBoolValue(Map params, String key, boolean defaultValue) { if (params.containsKey(key)) { Object value = params.get(key); @@ -501,16 +538,16 @@ private Map getGraphConfig() { if (this.bar.length > 0) { graphType = "bar"; if ("None".equals(this.icon)) { - data = leftTrim(this.bar, 16); + data = Helper.leftTrim(this.bar, 16); } else { - data = leftTrim(this.bar, 11); + data = Helper.leftTrim(this.bar, 11); } } else if (this.line.length > 0) { graphType = "line"; if ("None".equals(this.icon)) { - data = leftTrim(this.line, 16); + data = Helper.leftTrim(this.line, 16); } else { - data = leftTrim(this.line, 11); + data = Helper.leftTrim(this.line, 11); } } if (graphType != null && data != null) { @@ -520,17 +557,6 @@ private Map getGraphConfig() { return fields; } - private BigDecimal[] leftTrim(BigDecimal[] data, int length) { - if (length < data.length) { - BigDecimal[] trimmed = new BigDecimal[length]; - for (int i = data.length - length; i <= data.length; i++) { - trimmed[i - data.length - length] = data[i]; - } - return trimmed; - } - return data; - } - private Map getProgressConfig() { Map fields = new HashMap(); if (progress.compareTo(MINUSONE) > 0 && progress.compareTo(ONEHUNDRED) <= 0) { diff --git a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/handler/AwtrixLightAppHandler.java b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/handler/AwtrixLightAppHandler.java index d217e89fd3ec..5de3e8919d89 100644 --- a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/handler/AwtrixLightAppHandler.java +++ b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/java/org/openhab/binding/mqtt/awtrixlight/internal/handler/AwtrixLightAppHandler.java @@ -31,7 +31,10 @@ import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_FADE_TEXT; import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_GRADIENT_COLOR; import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_ICON; +import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_LIFETIME; +import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_LIFETIME_MODE; import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_LINE; +import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_OVERLAY; import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_PROGRESS; import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_PROGRESSBC; import static org.openhab.binding.mqtt.awtrixlight.internal.AwtrixLightBindingConstants.CHANNEL_PROGRESSC; @@ -285,6 +288,23 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } break; + case CHANNEL_LIFETIME: + if (command instanceof QuantityType) { + this.app.setLifetime(((QuantityType) command).toBigDecimal()); + } + break; + case CHANNEL_LIFETIME_MODE: + if (command instanceof StringType) { + switch (command.toString()) { + case "DELETE": + this.app.setLifetimeMode(new BigDecimal(0)); + break; + case "STALE": + this.app.setLifetimeMode(new BigDecimal(1)); + break; + } + } + break; case CHANNEL_BAR: if (command instanceof StringType) { try { @@ -305,6 +325,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { this.app.setAutoscale(command.equals(OnOffType.ON)); } break; + case CHANNEL_OVERLAY: + if (command instanceof StringType) { + this.app.setOverlay(((StringType) command).toString()); + } + break; case CHANNEL_PROGRESS: if (command instanceof QuantityType) { this.app.setProgress(((QuantityType) command).toBigDecimal()); @@ -392,12 +417,21 @@ public void channelUnlinked(ChannelUID channelUID) { case CHANNEL_LINE: this.app.setLine(AwtrixApp.DEFAULT_LINE); break; + case CHANNEL_LIFETIME: + this.app.setLifetime(AwtrixApp.DEFAULT_LIFETIME); + break; + case CHANNEL_LIFETIME_MODE: + this.app.setLifetimeMode(AwtrixApp.DEFAULT_LIFETIME_MODE); + break; case CHANNEL_BAR: this.app.setBar(AwtrixApp.DEFAULT_BAR); break; case CHANNEL_AUTOSCALE: this.app.setAutoscale(AwtrixApp.DEFAULT_AUTOSCALE); break; + case CHANNEL_OVERLAY: + this.app.setOverlay(AwtrixApp.DEFAULT_OVERLAY); + break; case CHANNEL_PROGRESS: this.app.setProgress(AwtrixApp.DEFAULT_PROGRESS); break; @@ -414,6 +448,7 @@ public void channelUnlinked(ChannelUID channelUID) { @Override public void channelLinked(ChannelUID channelUID) { + // TODO: Do not update all channels when any channel is linked initStates(); } @@ -625,6 +660,12 @@ private void initStates() { String lineString = Arrays.stream(line).map(BigDecimal::toString).collect(Collectors.joining(",")); updateState(new ChannelUID(channelPrefix + CHANNEL_LINE), new StringType(lineString)); + updateState(new ChannelUID(channelPrefix + CHANNEL_LIFETIME), + new QuantityType<>(this.app.getLifetime(), Units.SECOND)); + + String lifetimeMode = this.app.getLifetimeMode().equals(BigDecimal.ZERO) ? "DELETE" : "STALE"; + updateState(new ChannelUID(channelPrefix + CHANNEL_LIFETIME_MODE), new StringType(lifetimeMode)); + BigDecimal[] bar = this.app.getBar().length > 0 ? this.app.getBar() : new BigDecimal[] { BigDecimal.ZERO }; String barString = Arrays.stream(bar).map(BigDecimal::toString).collect(Collectors.joining(",")); updateState(new ChannelUID(channelPrefix + CHANNEL_BAR), new StringType(barString)); @@ -632,6 +673,8 @@ private void initStates() { updateState(new ChannelUID(channelPrefix + CHANNEL_AUTOSCALE), this.app.getAutoscale() ? OnOffType.ON : OnOffType.OFF); + updateState(new ChannelUID(channelPrefix + CHANNEL_OVERLAY), new StringType(this.app.getOverlay())); + BigDecimal progress = this.app.getProgress().compareTo(BigDecimal.ZERO) > 0 ? this.app.getProgress() : BigDecimal.ZERO; updateState(new ChannelUID(channelPrefix + CHANNEL_PROGRESS), new QuantityType<>(progress, Units.PERCENT)); diff --git a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/resources/OH-INF/thing/thing-types.xml index 6fa59a0a715b..4159f576171a 100644 --- a/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.mqtt.awtrixlight/src/main/resources/OH-INF/thing/thing-types.xml @@ -71,8 +71,11 @@ + + + @@ -420,7 +423,6 @@ - @@ -428,12 +430,38 @@ Draw a line graph (format: "value1,value2,value3", last 16 entries will be displayed, last 11 with icon) qualityofservice + + Control + + + + + Number:Time + + Remove the app if there was no update within specified seconds + time Control Duration + + String + + Delete the app or mark as stale after lifetime + screen + + Control + + + + + + + + + String @@ -454,6 +482,27 @@ + + String + + Overlay effect (overriden by global clock overlay) + screen + + Control + + + + + + + + + + + + + + Number:Dimensionless diff --git a/bundles/org.openhab.binding.mqtt.awtrixlight/src/test/java/org/openhab/binding/mqtt/awtrixlight/internal/HelperTest.java b/bundles/org.openhab.binding.mqtt.awtrixlight/src/test/java/org/openhab/binding/mqtt/awtrixlight/internal/HelperTest.java index 278701d243a4..046b31257cae 100644 --- a/bundles/org.openhab.binding.mqtt.awtrixlight/src/test/java/org/openhab/binding/mqtt/awtrixlight/internal/HelperTest.java +++ b/bundles/org.openhab.binding.mqtt.awtrixlight/src/test/java/org/openhab/binding/mqtt/awtrixlight/internal/HelperTest.java @@ -148,4 +148,14 @@ public void mappingRoundTrip() { String appConfig6 = app.getAppConfig(); assertEquals(appConfig, appConfig6); } + + @Test + public void trimArray() { + BigDecimal[] untrimmed = { BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN, new BigDecimal(1000) }; + BigDecimal[] trimmed = Helper.leftTrim(untrimmed, 2); + + assertTrue(trimmed.length == 2); + assertEquals(trimmed[0], untrimmed[untrimmed.length - 2]); + assertEquals(trimmed[1], untrimmed[untrimmed.length - 1]); + } }