From b7d0fdb30df0f5d28df53deac0c9eb44470c0f3c Mon Sep 17 00:00:00 2001 From: Matthew Skinner Date: Mon, 28 Sep 2020 21:46:16 +1000 Subject: [PATCH] rgbw and fetch fx and palletes Signed-off-by: Matthew Skinner --- .../wled/internal/WLedBindingConstants.java | 2 + .../binding/wled/internal/WLedHandler.java | 113 +++++++--- .../wled/internal/WLedHandlerFactory.java | 9 +- .../WledDynamicStateDescriptionProvider.java | 37 +++ .../resources/ESH-INF/thing/thing-types.xml | 210 ++---------------- target/classes/ESH-INF/thing/thing-types.xml | 210 ++---------------- target/classes/META-INF/MANIFEST.MF | 32 ++- ...nding.wled.internal.WLedHandlerFactory.xml | 3 +- .../wled/internal/WLedBindingConstants.class | Bin 1829 -> 1949 bytes .../binding/wled/internal/WLedHandler.class | Bin 13939 -> 16423 bytes .../wled/internal/WLedHandlerFactory.class | Bin 2340 -> 2630 bytes 11 files changed, 189 insertions(+), 427 deletions(-) create mode 100644 src/main/java/org/openhab/binding/wled/internal/WledDynamicStateDescriptionProvider.java diff --git a/src/main/java/org/openhab/binding/wled/internal/WLedBindingConstants.java b/src/main/java/org/openhab/binding/wled/internal/WLedBindingConstants.java index 9159efb..fefe571 100644 --- a/src/main/java/org/openhab/binding/wled/internal/WLedBindingConstants.java +++ b/src/main/java/org/openhab/binding/wled/internal/WLedBindingConstants.java @@ -44,6 +44,8 @@ public class WLedBindingConstants { public static final String CHANNEL_MASTER_CONTROLS = "masterControls"; public static final String CHANNEL_PRIMARY_COLOR = "primaryColor"; public static final String CHANNEL_SECONDARY_COLOR = "secondaryColor"; + public static final String CHANNEL_PRIMARY_WHITE = "primaryWhite"; + public static final String CHANNEL_SECONDARY_WHITE = "secondaryWhite"; public static final String CHANNEL_PALETTES = "palettes"; public static final String CHANNEL_PRESETS = "presets"; public static final String CHANNEL_PRESET_DURATION = "presetDuration"; diff --git a/src/main/java/org/openhab/binding/wled/internal/WLedHandler.java b/src/main/java/org/openhab/binding/wled/internal/WLedHandler.java index ae8e7be..9eb646a 100644 --- a/src/main/java/org/openhab/binding/wled/internal/WLedHandler.java +++ b/src/main/java/org/openhab/binding/wled/internal/WLedHandler.java @@ -16,6 +16,8 @@ import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -42,6 +44,7 @@ import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; import org.eclipse.smarthome.core.types.Command; import org.eclipse.smarthome.core.types.RefreshType; +import org.eclipse.smarthome.core.types.StateOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,17 +59,21 @@ public class WLedHandler extends BaseThingHandler { private final Logger logger = LoggerFactory.getLogger(getClass()); private final HttpClient httpClient; + private final WledDynamicStateDescriptionProvider stateDescriptionProvider; private @Nullable ScheduledFuture pollingFuture = null; private ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1); private BigDecimal masterBrightness = new BigDecimal(0); private HSBType primaryColor = new HSBType(); + private BigDecimal primaryWhite = new BigDecimal(0); private HSBType secondaryColor = new HSBType(); + private BigDecimal secondaryWhite = new BigDecimal(0); private WLedConfiguration config; - private boolean hasWhite = false; - public WLedHandler(Thing thing, HttpClient httpClient) { + public WLedHandler(Thing thing, HttpClient httpClient, + WledDynamicStateDescriptionProvider stateDescriptionProvider) { super(thing); this.httpClient = httpClient; + this.stateDescriptionProvider = stateDescriptionProvider; config = getConfigAs(WLedConfiguration.class); } @@ -103,21 +110,26 @@ private HSBType parseToHSBType(String message, String element) { return new HSBType(); } int endIndex = message.indexOf("<", startIndex + element.length()); - int r = Integer.parseInt(message.substring(startIndex + element.length(), endIndex)); - // look for second element - startIndex = message.indexOf(element, endIndex); - if (startIndex == -1) { - return new HSBType(); - } - endIndex = message.indexOf("<", startIndex + element.length()); - int g = Integer.parseInt(message.substring(startIndex + element.length(), endIndex)); - // look for third element called - startIndex = message.indexOf(element, endIndex); - if (startIndex == -1) { - return new HSBType(); + int r = 0, g = 0, b = 0; + try { + r = Integer.parseInt(message.substring(startIndex + element.length(), endIndex)); + // look for second element + startIndex = message.indexOf(element, endIndex); + if (startIndex == -1) { + return new HSBType(); + } + endIndex = message.indexOf("<", startIndex + element.length()); + g = Integer.parseInt(message.substring(startIndex + element.length(), endIndex)); + // look for third element called + startIndex = message.indexOf(element, endIndex); + if (startIndex == -1) { + return new HSBType(); + } + endIndex = message.indexOf("<", startIndex + element.length()); + b = Integer.parseInt(message.substring(startIndex + element.length(), endIndex)); + } catch (NumberFormatException e) { + logger.warn("NumberFormatException when parsing the WLED color fields."); } - endIndex = message.indexOf("<", startIndex + element.length()); - int b = Integer.parseInt(message.substring(startIndex + element.length(), endIndex)); return HSBType.fromRGB(r, g, b); } @@ -126,24 +138,56 @@ private void parseColours(String message) { updateState(CHANNEL_PRIMARY_COLOR, primaryColor); secondaryColor = parseToHSBType(message, ""); updateState(CHANNEL_SECONDARY_COLOR, secondaryColor); + try { + primaryWhite = new BigDecimal(getValue(message, "", "<")); + if (primaryWhite.intValue() > -1) { + updateState(CHANNEL_PRIMARY_WHITE, + new PercentType(primaryWhite.divide(new BigDecimal(2.55), RoundingMode.HALF_UP))); + secondaryWhite = new BigDecimal(getValue(message, "", "<")); + updateState(CHANNEL_SECONDARY_WHITE, + new PercentType(secondaryWhite.divide(new BigDecimal(2.55), RoundingMode.HALF_UP))); + } + } catch (NumberFormatException e) { + logger.warn("NumberFormatException when parsing the WLED white fields."); + } + } + + private void scrapeChannelOptions(String message) { + List fxOptions = new ArrayList<>(); + List palleteOptions = new ArrayList<>(); + int counter = 0; + for (String value : (getValue(message, "\"effects\":[", "]").replace("\"", "")).split(",")) { + fxOptions.add(new StateOption("" + counter++, value)); + } + stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_FX), fxOptions); + counter = 0; + for (String value : (getValue(message, "\"palettes\":[", "]").replace("\"", "")).split(",")) { + palleteOptions.add(new StateOption("" + counter++, value)); + } + stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), CHANNEL_PALETTES), palleteOptions); } private void processState(String message) { logger.trace("WLED states are:{}", message); if (thing.getStatus() != ThingStatus.ONLINE) { updateStatus(ThingStatus.ONLINE); + sendGetRequest("/json"); // fetch FX and Pallete names + } + if (message.contains("\"effects\":[")) {// JSON API reply + scrapeChannelOptions(message); + return; } if (message.contains("0")) { updateState(CHANNEL_MASTER_CONTROLS, OnOffType.OFF); } else { - masterBrightness = new BigDecimal(getValue(message, "")).divide(new BigDecimal(2.55), - RoundingMode.HALF_UP); - updateState(CHANNEL_MASTER_CONTROLS, new PercentType(masterBrightness)); + masterBrightness = new BigDecimal(getValue(message, "", "<")); + updateState(CHANNEL_MASTER_CONTROLS, + new PercentType(masterBrightness.divide(new BigDecimal(2.55), RoundingMode.HALF_UP))); } if (message.contains("0")) { updateState(CHANNEL_INTENSITY, OnOffType.OFF); } else { - BigDecimal bigTemp = new BigDecimal(getValue(message, "")).divide(new BigDecimal(2.55), + BigDecimal bigTemp = new BigDecimal(getValue(message, "", "<")).divide(new BigDecimal(2.55), RoundingMode.HALF_UP); updateState(CHANNEL_INTENSITY, new PercentType(bigTemp)); } @@ -158,20 +202,15 @@ private void processState(String message) { updateState(CHANNEL_SLEEP, OnOffType.OFF); } if (message.contains("")) { - updateState(CHANNEL_FX, new StringType(getValue(message, ""))); + updateState(CHANNEL_FX, new StringType(getValue(message, "", "<"))); } if (message.contains("")) { - BigDecimal bigTemp = new BigDecimal(getValue(message, "")).divide(new BigDecimal(2.55), + BigDecimal bigTemp = new BigDecimal(getValue(message, "", "<")).divide(new BigDecimal(2.55), RoundingMode.HALF_UP); updateState(CHANNEL_SPEED, new PercentType(bigTemp)); } if (message.contains("")) { - updateState(CHANNEL_PALETTES, new StringType(getValue(message, ""))); - } - if (message.contains("-1")) { - hasWhite = false; - } else { - hasWhite = true; + updateState(CHANNEL_PALETTES, new StringType(getValue(message, "", "<"))); } parseColours(message); } @@ -200,6 +239,16 @@ public void handleCommand(ChannelUID channelUID, Command command) { } logger.debug("command {} sent to {}", command, channelUID.getId()); switch (channelUID.getId()) { + case CHANNEL_PRIMARY_WHITE: + if (command instanceof PercentType) { + sendGetRequest("/win&W=" + new BigDecimal(command.toString()).multiply(new BigDecimal(2.55))); + } + break; + case CHANNEL_SECONDARY_WHITE: + if (command instanceof PercentType) { + sendGetRequest("/win&W2=" + new BigDecimal(command.toString()).multiply(new BigDecimal(2.55))); + } + break; case CHANNEL_MASTER_CONTROLS: if (command instanceof OnOffType) { if (OnOffType.OFF.equals(command)) { @@ -358,14 +407,14 @@ public void dispose() { } /** - * @return A string that starts after finding the element and terminates when it finds the first < char after the - * element. + * @return A string that starts after finding the element and terminates when it finds the first occurence of the + * end char after the element. */ - static private String getValue(String message, String element) { + static private String getValue(String message, String element, String end) { int startIndex = message.indexOf(element); if (startIndex != -1) // It was found, as -1 means "not found" { - int endIndex = message.indexOf('<', startIndex + element.length()); + int endIndex = message.indexOf(end, startIndex + element.length()); if (endIndex != -1)// , not found so make second check { return message.substring(startIndex + element.length(), endIndex); diff --git a/src/main/java/org/openhab/binding/wled/internal/WLedHandlerFactory.java b/src/main/java/org/openhab/binding/wled/internal/WLedHandlerFactory.java index 084c2be..df44681 100644 --- a/src/main/java/org/openhab/binding/wled/internal/WLedHandlerFactory.java +++ b/src/main/java/org/openhab/binding/wled/internal/WLedHandlerFactory.java @@ -37,11 +37,14 @@ @NonNullByDefault @Component(configurationPid = "binding.wled", service = ThingHandlerFactory.class) public class WLedHandlerFactory extends BaseThingHandlerFactory { - private HttpClient httpClient; + private final HttpClient httpClient; + private final WledDynamicStateDescriptionProvider stateDescriptionProvider;; @Activate - public WLedHandlerFactory(@Reference HttpClientFactory httpClientFactory) { + public WLedHandlerFactory(@Reference HttpClientFactory httpClientFactory, + final @Reference WledDynamicStateDescriptionProvider stateDescriptionProvider) { this.httpClient = httpClientFactory.getCommonHttpClient(); + this.stateDescriptionProvider = stateDescriptionProvider; } @Override @@ -56,7 +59,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { protected @Nullable ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (SUPPORTED_THING_TYPES.contains(thingTypeUID)) { - return new WLedHandler(thing, httpClient); + return new WLedHandler(thing, httpClient, stateDescriptionProvider); } return null; } diff --git a/src/main/java/org/openhab/binding/wled/internal/WledDynamicStateDescriptionProvider.java b/src/main/java/org/openhab/binding/wled/internal/WledDynamicStateDescriptionProvider.java new file mode 100644 index 0000000..a098332 --- /dev/null +++ b/src/main/java/org/openhab/binding/wled/internal/WledDynamicStateDescriptionProvider.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.wled.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.thing.binding.BaseDynamicStateDescriptionProvider; +import org.eclipse.smarthome.core.thing.i18n.ChannelTypeI18nLocalizationService; +import org.eclipse.smarthome.core.thing.type.DynamicStateDescriptionProvider; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * The {@link WledDynamicStateDescriptionProvider} Allows the dynamic updating of the FX and Palletes that WLED keep + * changing between firmware versions. + * + * @author Matthew Skinner - Initial contribution + */ +@Component(service = { DynamicStateDescriptionProvider.class, WledDynamicStateDescriptionProvider.class }) +@NonNullByDefault +public class WledDynamicStateDescriptionProvider extends BaseDynamicStateDescriptionProvider { + @Activate + public WledDynamicStateDescriptionProvider( + final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; + } +} diff --git a/src/main/resources/ESH-INF/thing/thing-types.xml b/src/main/resources/ESH-INF/thing/thing-types.xml index a69c942..85e7bce 100644 --- a/src/main/resources/ESH-INF/thing/thing-types.xml +++ b/src/main/resources/ESH-INF/thing/thing-types.xml @@ -79,183 +79,13 @@ String - Change the colours used by the FX. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Change the colours used by the FX. String Use the built in FX. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -263,25 +93,25 @@ Auto rotate or change to a saved preset. - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/target/classes/ESH-INF/thing/thing-types.xml b/target/classes/ESH-INF/thing/thing-types.xml index a69c942..85e7bce 100644 --- a/target/classes/ESH-INF/thing/thing-types.xml +++ b/target/classes/ESH-INF/thing/thing-types.xml @@ -79,183 +79,13 @@ String - Change the colours used by the FX. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Change the colours used by the FX. String Use the built in FX. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -263,25 +93,25 @@ Auto rotate or change to a saved preset. - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF index 98f375b..e28cc76 100644 --- a/target/classes/META-INF/MANIFEST.MF +++ b/target/classes/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 Automatic-Module-Name: org.openhab.binding.wled -Bnd-LastModified: 1601172214006 +Bnd-LastModified: 1601293549102 Bundle-Description: This project contains the official add-ons of open HAB Bundle-Developers: openhab;email="info@openhab.org";name=openHAB;organ @@ -20,28 +20,38 @@ Bundle-SCM: url="https://github.com/openhab/openhab-addons/org.openhab tor.bundles/org.openhab.binding.wled",tag=HEAD Bundle-SymbolicName: org.openhab.binding.wled Bundle-Vendor: openHAB.org -Bundle-Version: 2.5.9.202009270203 +Bundle-Version: 2.5.9.202009281145 Created-By: 1.8.0_231 (Oracle Corporation) Import-Package: org.eclipse.smarthome.config.discovery,org.eclipse.sma rthome.config.discovery.mdns,org.eclipse.smarthome.core.library.types ,org.eclipse.smarthome.core.thing,org.eclipse.smarthome.core.thing.bi - nding,org.eclipse.smarthome.core.types,org.eclipse.smarthome.io.net.h - ttp,javax.jmdns;version="[3.5,4)",org.eclipse.jetty.client;version="[ - 9.3,10)",org.eclipse.jetty.client.api;version="[9.3,10)",org.eclipse. - jetty.http;version="[9.3,10)",org.slf4j;version="[1.7,2)" + nding,org.eclipse.smarthome.core.thing.i18n,org.eclipse.smarthome.cor + e.thing.type,org.eclipse.smarthome.core.types,org.eclipse.smarthome.i + o.net.http,javax.jmdns;version="[3.5,4)",org.eclipse.jetty.client;ver + sion="[9.3,10)",org.eclipse.jetty.client.api;version="[9.3,10)",org.e + clipse.jetty.http;version="[9.3,10)",org.slf4j;version="[1.7,2)" Private-Package: ESH-INF.binding,ESH-INF.thing,org.openhab.binding.wle d.internal Provide-Capability: osgi.service;objectClass:List="org.eclipse .smarthome.config.discovery.mdns.MDNSDiscoveryParticipant";uses:="org .eclipse.smarthome.config.discovery.mdns",osgi.service;objectClass:Li st="org.eclipse.smarthome.core.thing.binding.ThingHandlerFact - ory";uses:="org.eclipse.smarthome.core.thing.binding" + ory";uses:="org.eclipse.smarthome.core.thing.binding",osgi.service;ob + jectClass:List="org.eclipse.smarthome.core.thing.type.Dynamic + StateDescriptionProvider,org.openhab.binding.wled.internal.WledDynami + cStateDescriptionProvider";uses:="org.eclipse.smarthome.core.thing.ty + pe,org.openhab.binding.wled.internal" Require-Capability: osgi.service;filter:="(objectClass=org.eclipse.sma - rthome.io.net.http.HttpClientFactory)";effective:=active,osgi.extende - r;filter:="(&(osgi.extender=osgi.component)(version>=1.4.0)(!(version - >=2.0.0)))",osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" + rthome.core.thing.i18n.ChannelTypeI18nLocalizationService)";effective + :=active,osgi.service;filter:="(objectClass=org.eclipse.smarthome.io. + net.http.HttpClientFactory)";effective:=active,osgi.service;filter:=" + (objectClass=org.openhab.binding.wled.internal.WledDynamicStateDescri + ptionProvider)";effective:=active,osgi.extender;filter:="(&(osgi.exte + nder=osgi.component)(version>=1.4.0)(!(version>=2.0.0)))",osgi.ee;fil + ter:="(&(osgi.ee=JavaSE)(version=1.8))" Service-Component: OSGI-INF/org.openhab.binding.wled.internal.WLedDisc overyService.xml,OSGI-INF/org.openhab.binding.wled.internal.WLedHandl - erFactory.xml + erFactory.xml,OSGI-INF/org.openhab.binding.wled.internal.WledDynamicS + tateDescriptionProvider.xml Tool: Bnd-4.3.0.201909301554 diff --git a/target/classes/OSGI-INF/org.openhab.binding.wled.internal.WLedHandlerFactory.xml b/target/classes/OSGI-INF/org.openhab.binding.wled.internal.WLedHandlerFactory.xml index 4c168c4..6fe181d 100644 --- a/target/classes/OSGI-INF/org.openhab.binding.wled.internal.WLedHandlerFactory.xml +++ b/target/classes/OSGI-INF/org.openhab.binding.wled.internal.WLedHandlerFactory.xml @@ -1,8 +1,9 @@ - + + diff --git a/target/classes/org/openhab/binding/wled/internal/WLedBindingConstants.class b/target/classes/org/openhab/binding/wled/internal/WLedBindingConstants.class index 3ca99a926c3df19f066c54ae05d8ef14069c7b59..ea707d94c07774ee2fb8447da14cc0c8124ccfbe 100644 GIT binary patch delta 516 zcmYk2%}*Lp6vfYdGs1{dKQP9yP}-(ZYhobUXw+hz!n7bCjtmv?i;jvBrD}j``8WEO zjfq{j*Rr4~(M6a1QN}k2(YLra=iJ{txp`OJ7d@`V{l7Z^@33>@a}Rl&;_vK|L+zzgfjf`XFD<5eD0&sRx%6p=azHLU$>*dvd(@MEAC7LyPID zlx`{*<$mU+ac-~?n&9VbjQsqPy`?GMU_+j10^9#Vc+p-o4P6f@nEfdY(|hg}^#fm! zUQ>u$(xei^Cl#L&=D(zwz>*3Vx}1m+`VOr#%lEyUFZjY%>A=jDT}Z%iVwuqUG}DSj zt5Q<2f+X*er<5pCcH9@fB)_CIKa%~94cpN8Z}~sLY+nY&8S6n>CBCqT8GWJOHkdW^@1m delta 439 zcmYL^%S!@L7{$+>8FiebQhIKb9-0cGU?gQ$HceTXTAFDEAu^OPRHPNH+O~}g?OFz{ z0&`*XTGXyhe@vU&MAxZka}FGS=Y02Gv|KhzuU~gh00yyMm26yFs~n3a5=wj{6^$#I zjFJ}7Lr*ye>8Dqmiww{=&P}}ZgY!6i1WkMUYFVww$3;ygkp8;UIS~Om!FQ4%&GB|J zM30yb({sL87$fkVUHc>n5lmPR#Uy>_L(VA+Bs7^YO<>(F92Wcsm6GO<70O#_wIU&g zITL1SQfTMr5vQ9%(4!#Hs3!@!-SPj5ysK$yu~ORI345|;5G>LcAz)l?uwnWsJQHi} z!C)pQ97K#D%!pC;|16A50oOeud7Eex>lm*=zK4<*9$CcSKu+IcrjCUgQdLHBSYp}% z1JgbYycPu{yd(Vo#kkd7fRpt$D G4fqBu`BY5+ diff --git a/target/classes/org/openhab/binding/wled/internal/WLedHandler.class b/target/classes/org/openhab/binding/wled/internal/WLedHandler.class index 2adb79c762d4363f8984a647361be128057994c9..9cf2119c8d76050dda1a3a370cec65582566b9cf 100644 GIT binary patch literal 16423 zcmcJ02Yg(`wf8x*d-q<+*G<9|406HPl5DvOTat?`$(9^hGLl?@z-o0Rty%4gEw)8* zs3G(k69b_I5G4gW_R5Nbfj~kYkPw;^-b*9pg}fvW@E+lbdO|oMQO`{_coX66x}Wqn)8HtHc)yTP4v>IX?ksjW=So$R1}p zlP3`B=&-^}dG!)XB+$NOM@hZvD`(2>j7Gbw0)8tPWja%hNUXENibi`%uqeKj)Fy{v z(&R|g8?~yfh%fB#j`~Bvjp5Kvf16xnodPk;?y%SDo}jnO?`u8@AS^PvI}`|DBWq*P zSlD8kUBAP-(_0dY`UBW_&=(7bC1TCKPOB{ji1s*4%xU&_1ikj8xg(lXQMeNG&S;7S zqy8?dF1XVl@wW!7mY!~_G8ha2N9-{&h(2x65^wTzNkc3U@M0Dq@@0 zc85_5_f&-fA&`Gj8V55ZCE#xjV`xbf`-+s*Hm{KzOo6eb(;o$)$3!g9w`~CEK!-EJ zgYWJB4yL6e;WlKsN{x?&6(O;rr@|lfM^`f4J!dF{ZP8ZZT%I=WWTH6|bVeY2b2l@& zt3qv7F1e_{q|<0RQ_+Y~ox3@gX408D%>pl#&<4Cv(Z<#tmM?13Y&wg{=&+(y0k7n3 z{v1b2)hN|jo=bD7NT))kNtsH!*6V|`^q5pk^C0YiV=FVnbB-+~DRAa0ilpg$4nZbO z(#Rug3r!kDW-cwJr8+HPIz6kBC1f;WQYoDcaSU3!l8V=oBJ7Li)D5R{30Mhvmsl(} zX*}iW1kpG}A&?>Hxl~3gBp)C$ZY;4`PFihJKAob|8m0w9*vG6=pG%cgEdkarx#rmL z)|oVcCQ8V4CQYJKWbHF1O}6_sm^8)iYcxqGLw-HSq#VlCshMf9#9$b+m#GN30I|uW z&9sGSl#~ahC6&_9WaDI}B$Z1PwwW}QPGuTf?+;oHv94At+#;=zGWR}jV6!*umu;uh z4V40X*#8ls>o^gxMN_)SG-4%Cb|l!g&Wbi!7ssp!+{=X2T{TC;Fz)4ZH|yksln-pq z{;($I55S@1P!m}uwG)hu?rm!eD{GjSBIgdAT=LUJI_*f)IQyGP0qVl^o!&sqYHWum zNyWp~%JNhdOoD8skdzT`F16CdCWQ&4^LV@Ay4&E!Q=vFh219Z70fla*m`OWn7j!=w zvd2T(({w+%a1ULo(kat|3y9f4Mny zC0(u4RZP>e+JqLk%1yB1CS60e`R6A$=Fe}(rFKZl=y44)InQqnT7N+Tg5s`6`ih4F!2)5cxx{Yp!tyovn z0=8svMj7MPF7GtyF8U&5rc1$qIZ0O^o1>XCM~wa5v`?om4UK&*;t(rr(mix9j6`Ks zRn5kh3u+pw8msFX)(x{0dv3WwUxwA~xWwNrIro4`57I-}Q>TK=bpDWga$pQr*b(m1 zps&C~HbdiJEef{O*HjmP1!b3BK8hZtUY#C;!b|3*x;T>_rzc>t+N{d9V{SDU@Qd+hC7N_w8@HeBTlry`~CDyoenS+ zf0}tF9i&6HOP6tR4Aus|sZK)cGwHB29eK8!kgHWjY;z&K$hS;7LS7XOhI}xQDy%l> z87QM7S=ctg1?^rx!k>a&{%B{xnQdhSXGU`AS$bZl=a|M1nBY2W2PuOzoZo@7Px^Ef zSU4ZmCSNq^yAmxKg)~{-NGK@n@Jl9rpZ*OZ(jE%Kk;A=b;lR0BSdh}?m_mbIVOl0l z2UNdix6e}PMwu-LyS$MCMCS#FwSCB?0#-pNSkM!Sg$sgKbXO>RkwHHI`gXv92tH-L z-1uwsx=ufWd}K9mgJ+rahTLl|_PPNy_I6kXy@g~*5+odsbw{nXj1`W_6@Huus*=>p z9GpY%(0}Ok?-}Bf5xu7b!?tvo^i%p73}fTkwe@uk2xR7`N$GIY5kCBa-qq=s$Qn|m zbhvrdRuocX(y!>((9EjF4I4H!)Kyis)HOC-P}9`Z*u=EtQz2plgokAMtx5k$zk?jd zy4#RpCbVEzx``PM!}MHXxY5q?gJn;KCcj54mQ_45MG~qS3nSap9aWS0YARLJoOh}d zLg)wS359L-fsICPm1;~f**XYNrtx87M1N=5`^n6fGtow5canI0u>50eK?;?!i9Lpl z2Ge{OZSZzG5$Bk0Zx}}sAt&8r+M2}}q=0o4Ki%SH@Gxsg4*~MiKTP^3eFQe(SjE~c zgT1UlXPrUEL8l5iYXYeT4MLS?$tITB5b`U;`Z z$ACk~iYFH8vh5&hR>10lQ-XPnL~%S-C&>>A*I~=>p@}9=C>S1@TM@LRkTxrL$dak3 zC66{@;fTQn*lUF^uo9MnXPER?`kO%$WaCVeXY*Omqye)56$9yjKtD$kQns8F^Ff1Tt{cJ+FE)9J z6imY(jH+b}nxymDFs~!#=SC~+16SlZk7u>JUHwVWjog=4@@kz|L4Xx9 zD)(**#Z<_(0jD4)S2Bc2udS?Kd%>oSaC!Dd1`UJ?mT|SoHM|!3)aI9Gf=p{2+GOPP zm0ipZq(56(2p4gM@vD3&W+XtGx-nHK2| z_@R{9Lg2Zn5tt*6IwP?y9zwiQbi}5H%xkOh!yU+vxs&O%^k~rroXmpR$2%ksFUpQn z%5D=1vUwDDaY*MN4ipAxF3D|jH(w0Di(`QdGoJ|Qx9f};x@f5VsKaxIznki?6Xux7 zI~jqVJfc%)k4%Lb89;^+O$p7)M{y5dsxy-J*~6}@pqqRdBY*c`H6S3*6^1m}DQjUk znEp8?(Y`yE!+fQr>{U1z8)>*C0c0b2E?>i+*ZEqe8o7sIj?z zgN^O&(nFejnEPQ*kWUSh!kh#El<|mkJ_+8vHCo5susnM*PtpgP)fJ z)rS}4Kwr9WO zt#Q$b6DMR){VS7y&A$P;q9H74??QTlY(coe{|V=~z~J{#z)iV2Bk+%|PKoMhxOZH& zR)xB{P+{6WBM<>$Yd{CDXQJqRAW0R+td1j|Zx`GW?347&L2{S{n#c>&I~q6N_q zsxp!I7Y@w$lkCSdDel4Xs)Ku=?E=aBXc(kmM4tJ`EYlDI@?i^d#1L+2YL!%1JJ*1Q zK>DOh^k#2aAur5gh#p0bDRKo;Bcm%8i2Az&J;;Ag7VO!W42lz}Rg6Y3BF1E#(I=vU zlntauCx#e@g>8%$t;mJq{ml^h@LQ^@rDes^1q)`ktXN=(2{?63bS_$;dKcw;2aBDh7jOUdgTF;Pr0#Z+-B@ThC3YO1Mhu3=g=a!twxwLDi$lsh>cE+q}= z$`yMSE;R(ws?7dHOVK|AzA1D3JUL-j=I$$3EP$Sh*`_#4%z+?4Oj9qfmksTW(&>_t zvXtj=sVFo>k&xNf_L`>-?DQVyhPG@6gb)yDTs82Vu7}TSi~wwcTNR9JB@(K zi851^tK8imYzIm!5^@Iw41r9nJd=^10={HLr76~kDm$vIl?m#n;(_zLK#C-Ur-ov> zkS=k=vYj$tB2#OMx`bRb%ZC~28Gs>>sTsu%-3+lINrOe80a$Ho;@XX9A>ndbThVGx zw3=mWQ=(NTTU!z~rJ>po+u(B*ryJ^})}EUfxlyvYOq`DlLX0xR1PFx+Q`gA<7392VDxYiZBOtG6M10%Vx^cbVWCE_w&Tne*2kmw;w9Q4vB z;{|~!E*Ek_1>=5HZKNx+ntvv;x=(R#0i(2i7uvBQ;F`(w1L}#5t&sV3SAWI&XRwo za4T)1GDrWbkM@$OOAQ8`DyPoZDx`+ZI1efx>k&7NBbgD2FPfs8YQ}2fE_5LEti!=j zSiRY?BD%OIab2KfEp3tXZR_H`v}>VkLm?YBjc7WeD;MtMM^T=9w}V=qe1f7%JU~Gy zB_6q`5>H%Ii8m!EM`PX7Xc~S` zN9%Xw#y_G^VNoBQQCJwK8HZ`kA(~&vhiE~e`!Fp!M9T_~P}w$DA5|QpRj5~P>!Yee zv^J%?cA$HGN_Tx>@gZs`oOg&e78d3;#i`{vYC1$)_bY_9uSOl9sV?tXe2_pkK*2Wf1fY$1Q` zqyGJQ-`1X?ncG~>fWvgOd7B#j0#oy0`d&jXm6o~lUPd_|<*ROIbew+Ze4d2vHwU`k zR^5dM=qCs0=kwz9oBa@`CcJC8o8F@c-YUpawjaRdsBFtpw&Qe6wPood$&1aPKG8W; zfba9Dna-vba9}evg8EIg4P&-b2Phu~#Ur5g7eMXXP~HW~?!%ek1LUKJs11-U+-$eg z%hXA4<2FX}s!56Vu_UjK(SHFJW34#-f&K_yHQ~+4pU@|9DWm_U_rcwLXnjC`M(rU8 z`v>$ts2x_dzo7OZ;LaoM6N>0`olbt8_Mbq`;ns;&OZLg?d+T(14HtjM^05qV7#uNp z79er};%HHEoc_LYns|^#Il}#PQQpVX(EG0o!M0Mjt5kE9dR(P?k=;4L9cR~J)=Rab zVp*r5CTGs^{4eI{y)?eekg}G~x&3SknxIYaOwbSW*r!3FLa^vD7>12>wJNWnuc*>y zYXhFt5w86`)CG$YM5`Ot=VHu?P&viG;+<4WyD+;4%)A83a~WEf<982Oas}N%R|4Ku zcz|&=9y464*m<5!xg|X3;%76*Y~{qPzK2 z)I7lAE*1fTuxFBx9$OcAWD01nh#5U?^_!@JF=Rt8@Nnyt~GMg~QBsKuBtN zys)q+pU>#y>C!;u^GpzJZJcMR?m4P^J-Q3gyp_wm@NV%&i1kevaSN>Ct+0T%K}&B3OK$_S?f_fv!~>VR=wXzP z(q4K3I)4bdBlWJprb?1gafeY)IK&o;*f}KrPLG4A@HdQeIftlkfm2dLK0d-5xAk$; z2B&OrmAXN+=6v1+s^#;RyeH$lEuYVi^99?=jH9JG)TNh7rWg}Ei^{a(BkbEI?Q9=g z6WrIhahBH(3p+*YV}CyfU{SB}uoUNqPW%W|*?5G*+X~|x?Pnb1jU!X_mo8ZCQ zD1Sk{^bv$wa-kOD4KgOV@Ug=MgZ{!d^DR)9ar6hi6*U*&zQ?yIby-O>_;x6h2AEEb z?*N>M7;n$KGdc54%(T_UeFBC%$59#X(s9*-^H!bjA}acrYKt%h?}}^=iyLjV;X7<; z+*{PoUxGb3$oKa1ml>~}9(7ov#sS0L7p#rbi`_&7hgk8%(*@YnaF{j_S2!+-+^ z_#m{RmzF0q>stegu}Thb6k}C(#Q?BxCxIPJ09)*6>2nEKnUgmF@=*!7*w#vb`A!nd ziwF373a8N+g@!~B1O6>J;FZ(?XgC9Ypax9Eq&-LYHEAV&;H>|;4dD$nAc5Q)Lm~H8 zI&#O7pl@_QA4>r(>G~5Xc(y5cnC77V6auBMB69m0Ou^S-HJ?U!w4avK0XWNp2$B$I z!IhqaAVWG|KlQ_QABI^t0z>g_x|g1T$R0({v*MO<{K#g=(%qGk5PW)xt=hNjd2Y%ccPp)?S;vUQO+uVefd_Di>A2Y zdnK}3N3Zt2Y{4S`^&au}UhQ4ks#hC1)~mfKTQk+S8NJ$fWoxPWc1^F=CtEMdmUeru z_JnNN1bC}gyB941Pw>}!+?V%iH_LB(WXsjwt9?$kUQyqwdbNvX>n-)IwO8}Wc`o(s z{9bL7{B~4*i}z~lWa~!NGJ3V;;7RE|Z4oRHWJYKZ3~4ut<3fj{A21z8jeSIYpRRiQ@f{S$$Zr%sPnG*9TKpVU#>JTj z#N5ZEWT};v0d_vbg^X>|wwy@i6gk9vJDrnsD#4Crc(k@pEQE^Xi^cd=cqEBLXWPKD zP|^k~;VhMKb5EAfLiH* z+OA+oZcFszVs%_p+c}*KP1GjPyAH%q`&y4*0PGufy-$O<%zowW>m9_`+f@7%h_BCz zIC`@pKID4)9b_7S4EUUoadC#zzcHg>Xgz49j@26;#3A6^Zym)i^Inh|gwVNw@s}UGKuo^-fQ2L{gRgm{D}iv1`L@+9#BPZlro6!CkMf8?p+eLmGSicfRR@9?bR zfTxbTJk1>RT*x6$fV({*4tw@;)bmx2dA`BBJjkOw&vB3E1-``dGVf7Q&o%Pg&GSkk z>hZiH+C>L~8uW=y;V0pK6aR-xhHaX*o?K4Nm#keuQ=GnEC;N^kYM$ANub$>)Um#iA zoA|22z?*6Hahiq5%KQkS)CuITnoM3etcx8GJwJ{t)Bct&otkr2&V-z)NT(Llge4O` zmIqgMF=^6qnyFLSvSo2X-mOpofe^ zAc%S@wChRd8x%Ct9_K(~ad8sH1xN!WjCpB?tI~NdEBuxS<3D_%y7i#gd96If6g@h! zgard?jPId2 z&T-Xb968v>RT5PX@o|75x3~^1A-*84w|m76Xx@lA*dy*Bm$*~x6?cm-p-0{+>=XBj IFVmF&1Hf4?;Q#;t literal 13939 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 SUTHv&xIkR4G%BlT!v6yM32xQ^ diff --git a/target/classes/org/openhab/binding/wled/internal/WLedHandlerFactory.class b/target/classes/org/openhab/binding/wled/internal/WLedHandlerFactory.class index 84d0400d6800a12c1f0756dae5cb89faf943ce47..324c3b2572ea3433e1074707d211eda624256353 100644 GIT binary patch delta 825 zcma)(OHUI~6vzMf-f4$E9fuJs6_AIu^g&T8R4Em;O4Xt!1QTOo(v&X7U@`4T;>IR^ zgL)Uly(_~471H>KOBXKGPv8gOGZ5mrQ_`K$N$z>&p7Z;kJ8#TymjC;~r>_9AxZC!3 zh9XU;;?#<@X0>5Ib?o)}y~g^6y;^H9ESB5GcxJ7(T6|uwJh7|Gf4Mow;LY20+bJ-# zYegGB*bR3hvSWX;ALB(tDnj}X>`a{lJW-Sg= zDW~T)m2UEamhiz(K0uk5vLN}8I-HU)1zmfDqDSC#5wH>+7>VRZ^fT<@L?X3|=sT)& z43RaVkxh}EqW%o}F^yrWoI=ZO#t4P#voMM=8m}UyMghk$K~}+5DCgvj_c%?cB*$xb zv@NkkHQ|E7u9z$-zCfT^7c$W8=`jqP#W|XIUUjv=!Xzt8_qoe>L9d}S#RxFNutccT zA)p%(ZcxOr=-QI|GX^QYN%<}Ew;zHvQN|MaD(?INE{clx delta 632 zcmYk2O-~b17=_P!XF3Et z4RdLs@OX%Dt#LrH#G)*-)Hm(WwpGEH>p658*geOlfjvDluHD056=is-=N z6IGBdL;kd2quIb{zGLN|qVgh_{fblz^T%@Bb&YcfnB(KjqaRh~z1Mb5U!c0q8TJ?H ztl0@NsCI@P$Umet?&BdTR0-e_PYRE@k0~s*-+PFSWj0n=pS*;;$10w(zQVKr1outt