]> git.basschouten.com Git - openhab-addons.git/blob
befa1e6118c1585300f0fcebbff3d47862b3a54a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.konnected.internal.handler;
14
15 import static org.openhab.binding.konnected.internal.KonnectedBindingConstants.*;
16
17 import java.math.BigDecimal;
18 import java.util.Map;
19 import java.util.Map.Entry;
20 import java.util.concurrent.TimeUnit;
21
22 import org.openhab.binding.konnected.internal.KonnectedConfiguration;
23 import org.openhab.binding.konnected.internal.KonnectedHTTPUtils;
24 import org.openhab.binding.konnected.internal.KonnectedHttpRetryExceeded;
25 import org.openhab.binding.konnected.internal.gson.KonnectedModuleGson;
26 import org.openhab.binding.konnected.internal.gson.KonnectedModulePayload;
27 import org.openhab.core.config.core.Configuration;
28 import org.openhab.core.config.core.validation.ConfigValidationException;
29 import org.openhab.core.library.types.OnOffType;
30 import org.openhab.core.library.types.QuantityType;
31 import org.openhab.core.library.unit.SIUnits;
32 import org.openhab.core.library.unit.Units;
33 import org.openhab.core.thing.Channel;
34 import org.openhab.core.thing.ChannelUID;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingStatus;
37 import org.openhab.core.thing.ThingStatusDetail;
38 import org.openhab.core.thing.binding.BaseThingHandler;
39 import org.openhab.core.types.Command;
40 import org.openhab.core.types.RefreshType;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import com.google.gson.Gson;
45 import com.google.gson.GsonBuilder;
46
47 /**
48  * The {@link KonnectedHandler} is responsible for handling commands, which are
49  * sent to one of the channels.
50  *
51  * @author Zachary Christiansen - Initial contribution
52  */
53 public class KonnectedHandler extends BaseThingHandler {
54     private final Logger logger = LoggerFactory.getLogger(KonnectedHandler.class);
55     private KonnectedConfiguration config;
56     private final String konnectedServletPath;
57     private final KonnectedHTTPUtils http = new KonnectedHTTPUtils(30);
58     private String callbackIpAddress = null;
59     private String baseUrl;
60     private final Gson gson = new GsonBuilder().create();
61     private int retryCount;
62     private final String thingID;
63     public String authToken;
64
65     /**
66      * This is the constructor of the Konnected Handler.
67      *
68      * @param thing the instance of the Konnected thing
69      * @param webHookServlet the instance of the callback servlet that is running for communication with the Konnected
70      *            Module
71      * @param hostAddress the webaddress of the openHAB server instance obtained by the runtime
72      * @param port the port on which the openHAB instance is running that was obtained by the runtime.
73      */
74     public KonnectedHandler(Thing thing, String path, String hostAddress, String port) {
75         super(thing);
76         this.konnectedServletPath = path;
77         callbackIpAddress = hostAddress + ":" + port;
78         logger.debug("The callback ip address is: {}", callbackIpAddress);
79         retryCount = 2;
80         thingID = getThing().getThingTypeUID().getId();
81         authToken = getThing().getUID().getAsString();
82     }
83
84     @Override
85     public void handleCommand(ChannelUID channelUID, Command command) {
86         // get the zone number in integer form
87         Channel channel = this.getThing().getChannel(channelUID.getId());
88         String channelType = channel.getChannelTypeUID().getAsString();
89         String zone = (String) channel.getConfiguration().get(CHANNEL_ZONE);
90         logger.debug("The channelUID is: {} and the zone is : {}", channelUID.getAsString(), zone);
91         // if the command is OnOfftype
92         if (command instanceof OnOffType) {
93             if (channelType.contains(CHANNEL_SWITCH)) {
94                 logger.debug("A command was sent to a sensor type so we are ignoring the command");
95             } else {
96                 int sendCommand = (OnOffType.OFF.compareTo((OnOffType) command));
97                 logger.debug("The command being sent to zone {} for channel:{}  is {}", zone, channelUID.getAsString(),
98                         sendCommand);
99                 sendActuatorCommand(Integer.toString(sendCommand), zone, channelUID);
100             }
101         } else if (command instanceof RefreshType) {
102             // check to see if handler has been initialized before attempting to get state of pin, else wait one minute
103             if (this.isInitialized()) {
104                 getSwitchState(zone, channelUID);
105             } else {
106                 scheduler.schedule(() -> {
107                     handleCommand(channelUID, command);
108                 }, 1, TimeUnit.MINUTES);
109             }
110         }
111     }
112
113     /**
114      * Process a {@link WebHookEvent} that has been received by the Servlet from a Konnected module with respect to a
115      * sensor event or status update request
116      *
117      * @param event the {@link KonnectedModuleGson} event that contains the state and pin information to be processed
118      */
119     public void handleWebHookEvent(KonnectedModuleGson event) {
120         // if we receive a command update the thing status to being online
121         updateStatus(ThingStatus.ONLINE);
122         // get the zone number based off of the index location of the pin value
123         // String sentZone = Integer.toString(Arrays.asList(PIN_TO_ZONE).indexOf(event.getPin()));
124         String zone = event.getZone(thingID);
125         // check that the zone number is in one of the channelUID definitions
126         logger.debug("Looping Through all channels on thing: {} to find a match for {}", thing.getUID().getAsString(),
127                 zone);
128         getThing().getChannels().forEach(channel -> {
129             ChannelUID channelId = channel.getUID();
130             String zoneNumber = (String) channel.getConfiguration().get(CHANNEL_ZONE);
131             // if the string zone that was sent equals the last digit of the channelId found process it as the
132             // channelId else do nothing
133             if (zone.equalsIgnoreCase(zoneNumber)) {
134                 logger.debug(
135                         "The configrued zone of channelID: {}  was a match for the zone sent by the alarm panel: {} on thing: {}",
136                         channelId, zone, this.getThing().getUID().getId());
137                 String channelType = channel.getChannelTypeUID().getAsString();
138                 logger.debug("The channeltypeID is: {}", channelType);
139                 // check if the itemType has been defined for the zone received
140                 // check the itemType of the Zone, if Contact, send the State if Temp send Temp, etc.
141                 if (channelType.contains(CHANNEL_SWITCH) || channelType.contains(CHANNEL_ACTUATOR)) {
142                     OnOffType onOffType = event.getState().equalsIgnoreCase(getOnState(channel)) ? OnOffType.ON
143                             : OnOffType.OFF;
144                     updateState(channelId, onOffType);
145                 } else if (channelType.contains(CHANNEL_HUMIDITY)) {
146                     // if the state is of type number then this means it is the humidity channel of the dht22
147                     updateState(channelId, new QuantityType<>(Double.parseDouble(event.getHumi()), Units.PERCENT));
148                 } else if (channelType.contains(CHANNEL_TEMPERATURE)) {
149                     Configuration configuration = channel.getConfiguration();
150                     if (((Boolean) configuration.get(CHANNEL_TEMPERATURE_TYPE))) {
151                         updateState(channelId,
152                                 new QuantityType<>(Double.parseDouble(event.getTemp()), SIUnits.CELSIUS));
153                     } else {
154                         // need to check to make sure right dsb1820 address
155                         logger.debug("The address of the DSB1820 sensor received from modeule {} is: {}",
156                                 this.thing.getUID(), event.getAddr());
157                         if (event.getAddr()
158                                 .equalsIgnoreCase((String) (configuration.get(CHANNEL_TEMPERATURE_DS18B20_ADDRESS)))) {
159                             updateState(channelId,
160                                     new QuantityType<>(Double.parseDouble(event.getTemp()), SIUnits.CELSIUS));
161                         } else {
162                             logger.debug("The address of {} does not match {} not updating this channel",
163                                     event.getAddr(), (configuration.get(CHANNEL_TEMPERATURE_DS18B20_ADDRESS)));
164                         }
165                     }
166                 }
167             } else {
168                 logger.trace(
169                         "The zone number sent by the alarm panel: {} was not a match the configured zone for channelId: {} for thing {}",
170                         zone, channelId, getThing().getThingTypeUID().toString());
171             }
172         });
173     }
174
175     private void checkConfiguration() throws ConfigValidationException {
176         logger.debug("Checking configuration on thing {}", this.getThing().getUID().getAsString());
177         Configuration testConfig = this.getConfig();
178         String testRetryCount = testConfig.get(RETRY_COUNT).toString();
179         String testRequestTimeout = testConfig.get(REQUEST_TIMEOUT).toString();
180         baseUrl = testConfig.get(BASE_URL).toString();
181         logger.debug("The RequestTimeout Parameter is Configured as: {}", testRequestTimeout);
182         logger.debug("The Retry Count Parameter is Configured as: {}", testRetryCount);
183         logger.debug("Base URL is Configured as: {}", baseUrl);
184         try {
185             this.retryCount = Integer.parseInt(testRetryCount);
186         } catch (NumberFormatException e) {
187             logger.debug(
188                     "Please check your configuration of the Retry Count as it is not an Integer. It is configured as: {}, will contintue to configure the binding with the default of 2",
189                     testRetryCount);
190             this.retryCount = 2;
191         }
192         try {
193             this.http.setRequestTimeout(Integer.parseInt(testRequestTimeout));
194         } catch (NumberFormatException e) {
195             logger.debug(
196                     "Please check your configuration of the Request Timeout as it is not an Integer. It is configured as: {}, will contintue to configure the binding with the default of 30",
197                     testRequestTimeout);
198         }
199
200         if ((callbackIpAddress == null)) {
201             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
202                     "Unable to obtain hostaddress from OSGI service, please configure hostaddress");
203         }
204
205         else {
206             this.config = getConfigAs(KonnectedConfiguration.class);
207         }
208     }
209
210     @Override
211     public void handleConfigurationUpdate(Map<String, Object> configurationParameters)
212             throws ConfigValidationException {
213         this.validateConfigurationParameters(configurationParameters);
214         for (Entry<String, Object> configurationParameter : configurationParameters.entrySet()) {
215             Object value = configurationParameter.getValue();
216             logger.debug("Controller Configuration update {} to {}", configurationParameter.getKey(), value);
217
218             if (value == null) {
219                 continue;
220             }
221             // this is a nonstandard implementation to to address the configuration of the konnected alarm panel (as
222             // opposed to the handler) until
223             // https://github.com/eclipse/smarthome/issues/3484 has been implemented in the framework
224             String[] cfg = configurationParameter.getKey().split("_");
225             if ("controller".equals(cfg[0])) {
226                 if (cfg[1].equals("softreset") && value instanceof Boolean && (Boolean) value) {
227                     scheduler.execute(() -> {
228                         try {
229                             http.doGet(baseUrl + "/settings?restart=true", null, retryCount);
230                         } catch (KonnectedHttpRetryExceeded e) {
231                             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
232                         }
233                     });
234                     value = false;
235                 } else if (cfg[1].equals("removewifi") && value instanceof Boolean && (Boolean) value) {
236                     scheduler.execute(() -> {
237                         try {
238                             http.doGet(baseUrl + "/settings?restore=true", null, retryCount);
239                         } catch (KonnectedHttpRetryExceeded e) {
240                             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
241                         }
242                     });
243                     value = false;
244                 } else if (cfg[1].equals("sendConfig") && value instanceof Boolean && (Boolean) value) {
245                     scheduler.execute(() -> {
246                         try {
247                             String response = updateKonnectedModule();
248                             logger.trace("The response from the konnected module with thingID {} was {}",
249                                     getThing().getUID().toString(), response);
250                             if (response == null) {
251                                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
252                                         "Unable to communicate with Konnected Module.");
253                             } else {
254                                 updateStatus(ThingStatus.ONLINE);
255                             }
256                         } catch (KonnectedHttpRetryExceeded e) {
257                             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
258                         }
259                     });
260                     value = false;
261                 }
262             }
263         }
264
265         super.handleConfigurationUpdate(configurationParameters);
266         try
267
268         {
269             String response = updateKonnectedModule();
270             logger.trace("The response from the konnected module with thingID {} was {}",
271                     getThing().getUID().toString(), response);
272             if (response == null) {
273                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
274                         "Unable to communicate with Konnected Module confirm settings.");
275             } else {
276                 updateStatus(ThingStatus.ONLINE);
277             }
278         } catch (KonnectedHttpRetryExceeded e) {
279             logger.trace("The number of retries was exceeeded during the HandleConfigurationUpdate(): {}",
280                     e.getMessage());
281             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
282         }
283     }
284
285     @Override
286     public void initialize() {
287         updateStatus(ThingStatus.UNKNOWN);
288         try {
289             checkConfiguration();
290         } catch (ConfigValidationException e) {
291             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
292         }
293         scheduler.execute(() -> {
294             try {
295                 String response = updateKonnectedModule();
296                 if (response == null) {
297                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
298                             "Unable to communicate with Konnected Module confirm settings or readd thing.");
299                 } else {
300                     updateStatus(ThingStatus.ONLINE);
301                 }
302             } catch (KonnectedHttpRetryExceeded e) {
303                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
304             }
305         });
306     }
307
308     @Override
309     public void dispose() {
310         logger.debug("Running dispose()");
311         super.dispose();
312     }
313
314     /**
315      * This method constructs the payload that will be sent
316      * to the Konnected module via the put request
317      * it adds the appropriate sensors and actuators to the {@link KonnectedModulePayload}
318      * as well as the location of the callback {@link KonnectedJTTPServlet}
319      * and auth_token which can be used for validation
320      *
321      * @return a json settings payload which can be sent to the Konnected Module based on the Thing
322      */
323     private String constructSettingsPayload() {
324         String apiUrl = (String) getThing().getConfiguration().get(CALLBACK_URL);
325         if (apiUrl == null) {
326             apiUrl = "http://" + callbackIpAddress + this.konnectedServletPath;
327         }
328
329         logger.debug("The Auth_Token is: {}", authToken);
330         KonnectedModulePayload payload = new KonnectedModulePayload(authToken, apiUrl);
331         payload.setBlink(config.blink);
332         payload.setDiscovery(config.discovery);
333         this.getThing().getChannels().forEach(channel -> {
334             // ChannelUID channelId = channel.getUID();
335             if (isLinked(channel.getUID())) {
336                 // adds linked channels to list based on last value of Channel ID
337                 // which is set to a number
338                 // get the zone number in integer form
339                 String zone = (String) channel.getConfiguration().get(CHANNEL_ZONE);
340                 // if the pin is an actuator add to actuator string
341                 // else add to sensor string
342                 // This is determined based off of the accepted item type, contact types are sensors
343                 // switch types are actuators
344                 String channelType = channel.getChannelTypeUID().getAsString();
345                 logger.debug("The channeltypeID is: {}", channelType);
346                 KonnectedModuleGson module = new KonnectedModuleGson();
347                 module.setZone(thingID, zone);
348                 if (channelType.contains(CHANNEL_SWITCH)) {
349                     payload.addSensor(module);
350                     logger.trace("Channel {} will be configured on the konnected alarm panel as a switch",
351                             channel.toString());
352                 } else if (channelType.contains(CHANNEL_ACTUATOR)) {
353                     payload.addActuators(module);
354                     logger.trace("Channel {} will be configured on the konnected alarm panel as an actuator",
355                             channel.toString());
356                 } else if (channelType.contains(CHANNEL_HUMIDITY)) {
357                     // the humidity channels do not need to be added because the supported sensor (dht22) is added under
358                     // the temp sensor
359                     logger.trace("Channel {} is a humidity channel.", channel.toString());
360                 } else if (channelType.contains(CHANNEL_TEMPERATURE)) {
361                     logger.trace("Channel {} will be configured on the konnected alarm panel as a temperature sensor",
362                             channel.toString());
363                     Configuration configuration = channel.getConfiguration();
364                     if (configuration.get(CHANNEL_TEMPERATRUE_POLL) == null) {
365                         module.setPollInterval(3);
366                     } else {
367                         module.setPollInterval(((BigDecimal) configuration.get(CHANNEL_TEMPERATRUE_POLL)).intValue());
368                     }
369                     logger.trace("The Temperature Sensor Type is: {} ",
370                             configuration.get(CHANNEL_TEMPERATURE_TYPE).toString());
371                     if ((boolean) configuration.get(CHANNEL_TEMPERATURE_TYPE)) {
372                         // add it as a dht22 module
373                         payload.addDht22(module);
374                         logger.trace(
375                                 "Channel {} will be configured on the konnected alarm panel as a DHT22 temperature sensor",
376                                 channel.toString());
377                     } else {
378                         // add to payload as a DS18B20 module if the parameter is false
379                         payload.addDs18b20(module);
380                         logger.trace(
381                                 "Channel {} will be configured on the konnected alarm panel as a DS18B20 temperature sensor",
382                                 channel.toString());
383                     }
384                 } else {
385                     logger.debug("Channel {} is of type {} which is not supported by the konnected binding",
386                             channel.toString(), channelType);
387                 }
388             } else {
389                 logger.debug("The Channel {} is not linked to an item", channel.getUID());
390             }
391         });
392         // Create Json to Send to Konnected Module
393
394         String payloadString = gson.toJson(payload);
395         logger.debug("The payload is: {}", payloadString);
396         return payloadString;
397     }
398
399     /*
400      * Prepares and sends the {@link KonnectedModulePayload} via the {@link KonnectedHttpUtils}
401      *
402      * @return response obtained from sending the settings payload to Konnected module defined by the thing
403      *
404      * @throws KonnectedHttpRetryExceeded if unable to communicate with the Konnected module defined by the Thing
405      */
406     private String updateKonnectedModule() throws KonnectedHttpRetryExceeded {
407         String payload = constructSettingsPayload();
408         String response = http.doPut(baseUrl + "/settings", payload, retryCount);
409         logger.debug("The response of the put request was: {}", response);
410         return response;
411     }
412
413     /**
414      * Sends a command to the module via {@link KonnectedHTTPUtils}
415      *
416      * @param scommand the string command, either 0 or 1 to send to the actutor pin on the Konnected module
417      * @param zone the zone to send the command to on the Konnected Module
418      */
419     private void sendActuatorCommand(String scommand, String zone, ChannelUID channelId) {
420         try {
421             Channel channel = getThing().getChannel(channelId.getId());
422             if (!(channel == null)) {
423                 logger.debug("getasstring: {} getID: {} getGroupId: {} toString:{}", channelId.getAsString(),
424                         channelId.getId(), channelId.getGroupId(), channelId.toString());
425                 Configuration configuration = channel.getConfiguration();
426                 KonnectedModuleGson payload = new KonnectedModuleGson();
427                 payload.setState(scommand);
428
429                 payload.setZone(thingID, zone);
430
431                 // check to see if this is an On Command type, if so add the momentary, pause, times to the payload if
432                 // they exist on the configuration.
433                 if (scommand.equals(getOnState(channel))) {
434                     if (configuration.get(CHANNEL_ACTUATOR_TIMES) == null) {
435                         logger.debug(
436                                 "The times configuration was not set for channelID: {}, not adding it to the payload.",
437                                 channelId.toString());
438                     } else {
439                         payload.setTimes(configuration.get(CHANNEL_ACTUATOR_TIMES).toString());
440                         logger.debug("The times configuration was set to: {} for channelID: {}.",
441                                 configuration.get(CHANNEL_ACTUATOR_TIMES).toString(), channelId.toString());
442                     }
443                     if (configuration.get(CHANNEL_ACTUATOR_MOMENTARY) == null) {
444                         logger.debug(
445                                 "The momentary configuration was not set for channelID: {}, not adding it to the payload.",
446                                 channelId.toString());
447                     } else {
448                         payload.setMomentary(configuration.get(CHANNEL_ACTUATOR_MOMENTARY).toString());
449                         logger.debug("The momentary configuration set to: {} channelID: {}.",
450                                 configuration.get(CHANNEL_ACTUATOR_MOMENTARY).toString(), channelId.toString());
451                     }
452                     if (configuration.get(CHANNEL_ACTUATOR_PAUSE) == null) {
453                         logger.debug(
454                                 "The pause configuration was not set for channelID: {}, not adding it to the payload.",
455                                 channelId.toString());
456                     } else {
457                         payload.setPause(configuration.get(CHANNEL_ACTUATOR_PAUSE).toString());
458                         logger.debug("The pause configuration was set to: {} for channelID: {}.",
459                                 configuration.get(CHANNEL_ACTUATOR_PAUSE).toString(), channelId.toString());
460                     }
461                 }
462                 String payloadString = gson.toJson(payload);
463                 logger.debug("The command payload  is: {}", payloadString);
464                 String path = "";
465                 switch (this.thingID) {
466                     case PRO_MODULE:
467                         path = "/zone";
468                         break;
469                     case WIFI_MODULE:
470                         path = "/device";
471                         break;
472                 }
473                 http.doPut(baseUrl + path, payloadString, retryCount);
474             } else {
475                 logger.debug("The channel {} returned null for channelId.getID(): {}", channelId.toString(),
476                         channelId.getId());
477             }
478         } catch (KonnectedHttpRetryExceeded e) {
479             logger.debug("Attempting to set the state of the actuator on thing {} failed: {}",
480                     this.thing.getUID().getId(), e.getMessage());
481             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
482                     "Unable to communicate with Konnected Alarm Panel confirm settings, and that module is online.");
483         }
484     }
485
486     private void getSwitchState(String zone, ChannelUID channelId) {
487         Channel channel = getThing().getChannel(channelId.getId());
488         if (!(channel == null)) {
489             logger.debug("getasstring: {} getID: {} getGroupId: {} toString:{}", channelId.getAsString(),
490                     channelId.getId(), channelId.getGroupId(), channelId.toString());
491             KonnectedModuleGson payload = new KonnectedModuleGson();
492             payload.setZone(thingID, zone);
493             String payloadString = gson.toJson(payload);
494             logger.debug("The command payload  is: {}", payloadString);
495             try {
496                 sendSetSwitchState(thingID, payloadString);
497             } catch (KonnectedHttpRetryExceeded e) {
498                 // try to get the state of the device one more time 30 seconds later. This way it can be confirmed if
499                 // the device was simply in a reboot loop when device state was attempted the first time
500                 scheduler.schedule(() -> {
501                     try {
502                         sendSetSwitchState(thingID, payloadString);
503                     } catch (KonnectedHttpRetryExceeded ex) {
504                         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
505                                 "Unable to communicate with Konnected Alarm Panel confirm settings, and that module is online.");
506                         logger.debug("Attempting to get the state of the zone on thing {} failed for channel: {} : {}",
507                                 this.thing.getUID().getId(), channelId.getAsString(), ex.getMessage());
508                     }
509                 }, 2, TimeUnit.MINUTES);
510             }
511         } else {
512             logger.debug("The channel {} returned null for channelId.getID(): {}", channelId.toString(),
513                     channelId.getId());
514         }
515     }
516
517     private void sendSetSwitchState(String thingId, String payloadString) throws KonnectedHttpRetryExceeded {
518         String path = thingId.equals(WIFI_MODULE) ? "/device" : "/zone";
519         String response = http.doGet(baseUrl + path, payloadString, retryCount);
520         KonnectedModuleGson[] events = gson.fromJson(response, KonnectedModuleGson[].class);
521         for (KonnectedModuleGson event : events) {
522             this.handleWebHookEvent(event);
523         }
524     }
525
526     private String getOnState(Channel channel) {
527         String config = (String) channel.getConfiguration().get(CHANNEL_ONVALUE);
528         if (config == null) {
529             return "1";
530         } else {
531             return config;
532         }
533     }
534 }