Skip to content

Commit

Permalink
Implemented ability to skip and execute the device initialization (#409)
Browse files Browse the repository at this point in the history
- Introduced thing property 'zigbee_initialised'. The property will be
  checked before the channels are initialized and skips the device
  initialization when it is 'true'. On the first initialization the
  property will be set to 'true' after the channel initialization.
- Introduced class that provides thing config description
  parameters.
- Introduced thing config parameter 'zigbee_initialise_device' in order
  to allow the user to (re-)initialize the device by updating the
  config. The config parameter will be checked when the config is
  updated and executes a device initialization.

Signed-off-by: Tommaso Travaglino <[email protected]>
  • Loading branch information
TomTravaglino authored and cdjackson committed Apr 10, 2019
1 parent 54bf5bd commit 3e64c04
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 21 deletions.
1 change: 1 addition & 0 deletions org.openhab.binding.zigbee/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Import-Package: com.thoughtworks.xstream,
gnu.io,
javax.measure.quantity,
org.apache.commons.io,
org.apache.commons.lang;resolution:=optional,
org.eclipse.jdt.annotation;resolution:=optional,
org.eclipse.smarthome.config.core,
org.eclipse.smarthome.config.discovery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ public class ZigBeeBindingConstants {
public static final String THING_PROPERTY_ASSOCIATEDDEVICES = "zigbee_devices";
public static final String THING_PROPERTY_INSTALLCODE = "zigbee_installcode";
public static final String THING_PROPERTY_STACKCOMPLIANCE = "zigbee_stkcompliance";
public static final String THING_PROPERTY_DEVICE_INITIALIZED = "zigbee_device_initialised";

// List of all configuration parameters
public static final String CONFIGURATION_PANID = "zigbee_panid";
Expand All @@ -239,6 +240,7 @@ public class ZigBeeBindingConstants {
public static final String CONFIGURATION_LINKKEY = "zigbee_linkkey";
public static final String CONFIGURATION_PASSWORD = "zigbee_password";
public static final String CONFIGURATION_INITIALIZE = "zigbee_initialise";
public static final String CONFIGURATION_INITIALIZE_DEVICE = "zigbee_initialise_device";
public static final String CONFIGURATION_TRUSTCENTREMODE = "zigbee_trustcentremode";
public static final String CONFIGURATION_POWERMODE = "zigbee_powermode";
public static final String CONFIGURATION_TXPOWER = "zigbee_txpower";
Expand Down
83 changes: 62 additions & 21 deletions ...b.binding.zigbee/src/main/java/org/openhab/binding/zigbee/handler/ZigBeeThingHandler.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.openhab.binding.zigbee.converter.ZigBeeBaseChannelConverter;
import org.openhab.binding.zigbee.converter.ZigBeeChannelConverterFactory;
import org.openhab.binding.zigbee.discovery.ZigBeeNodePropertyDiscoverer;
import org.openhab.binding.zigbee.internal.ZigBeeConfigDescriptionParameters;
import org.openhab.binding.zigbee.internal.ZigBeeDeviceConfigHandler;
import org.openhab.binding.zigbee.internal.converter.config.ZclClusterConfigFactory;
import org.openhab.binding.zigbee.internal.converter.config.ZclClusterConfigHandler;
Expand Down Expand Up @@ -269,6 +270,9 @@ private synchronized void doNodeInitialisation() {

List<Channel> nodeChannels;

List<ConfigDescriptionParameter> parameters = new ArrayList<>(
ZigBeeConfigDescriptionParameters.getParameters());

if (getThing().getThingTypeUID().equals(ZigBeeBindingConstants.THING_TYPE_GENERIC_DEVICE)) {
// Dynamically create the channels from the device
// Process all the endpoints for this device and add all channels as derived from the supported clusters
Expand All @@ -279,23 +283,21 @@ private synchronized void doNodeInitialisation() {
}
logger.debug("{}: Dynamically created {} channels", nodeIeeeAddress, nodeChannels.size());

try {
List<ConfigDescriptionParameter> parameters = new ArrayList<ConfigDescriptionParameter>();

for (ZclClusterConfigHandler handler : configHandlers) {
parameters.addAll(handler.getConfiguration());
}

configDescription = new ConfigDescription(new URI("thing:" + getThing().getUID()), parameters);
} catch (IllegalArgumentException | URISyntaxException e) {
logger.debug("Error creating URI for thing description:", e);
for (ZclClusterConfigHandler handler : configHandlers) {
parameters.addAll(handler.getConfiguration());
}
} else {
// We already have the correct thing type so just use the channels
nodeChannels = getThing().getChannels();
logger.debug("{}: Using static definition with existing {} channels", nodeIeeeAddress, nodeChannels.size());
}

try {
configDescription = new ConfigDescription(new URI("thing:" + getThing().getUID()), parameters);
} catch (IllegalArgumentException | URISyntaxException e) {
logger.debug("Error creating URI for thing description:", e);
}

// Add statically defined endpoints and clusters
for (Channel channel : nodeChannels) {
// Process the channel properties
Expand Down Expand Up @@ -368,24 +370,23 @@ private synchronized void doNodeInitialisation() {
updateThing(thingBuilder.build());
}

boolean initializeDevice = !Boolean
.parseBoolean(thing.getProperties().get(ZigBeeBindingConstants.THING_PROPERTY_DEVICE_INITIALIZED));
if (initializeDevice) {
initializeDevice();
} else {
logger.debug("{}: Device initialization will be skipped as the device is already initialized",
nodeIeeeAddress);
}

// Create the channel map to simplify processing incoming events
for (Channel channel : getThing().getChannels()) {
// Process the channel properties
Map<String, String> properties = channel.getProperties();

ZigBeeBaseChannelConverter handler = channelFactory.createConverter(this, channel, coordinatorHandler,
node.getIeeeAddress(),
Integer.parseInt(properties.get(ZigBeeBindingConstants.CHANNEL_PROPERTY_ENDPOINT)));
ZigBeeBaseChannelConverter handler = createZigBeeBaseChannelConverter(channel);
if (handler == null) {
logger.debug("{}: No handler found for {}", nodeIeeeAddress, channel.getUID());
continue;
}

logger.debug("{}: Initializing channel {} with {}", nodeIeeeAddress, channel.getUID(), handler);
if (handler.initializeDevice() == false) {
logger.info("{}: Channel {} failed to initialise device", nodeIeeeAddress, channel.getUID());
continue;
}
if (handler.initializeConverter() == false) {
logger.info("{}: Channel {} failed to initialise converter", nodeIeeeAddress, channel.getUID());
continue;
Expand Down Expand Up @@ -463,6 +464,37 @@ public void aliveTimeoutReached() {
updateStatus(ThingStatus.OFFLINE);
}

private synchronized void initializeDevice() {
logger.debug("{}: Initializing device", nodeIeeeAddress);

getThing().setProperty(ZigBeeBindingConstants.THING_PROPERTY_DEVICE_INITIALIZED, Boolean.FALSE.toString());

boolean channelInitializationSuccessful = true;
for (Channel channel : getThing().getChannels()) {
ZigBeeBaseChannelConverter handler = createZigBeeBaseChannelConverter(channel);
if (handler == null) {
logger.debug("{}: No handler found for {}", nodeIeeeAddress, channel.getUID());
continue;
}

logger.debug("{}: Initializing channel {} with {}", nodeIeeeAddress, channel.getUID(), handler);
if (handler.initializeDevice() == false) {
logger.info("{}: Channel {} failed to initialise device", nodeIeeeAddress, channel.getUID());
channelInitializationSuccessful = false;
}
}

thing.setProperty(ZigBeeBindingConstants.THING_PROPERTY_DEVICE_INITIALIZED,
channelInitializationSuccessful ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
}

private ZigBeeBaseChannelConverter createZigBeeBaseChannelConverter(Channel channel) {
ZigBeeNode node = coordinatorHandler.getNode(nodeIeeeAddress);
Map<String, String> properties = channel.getProperties();
return channelFactory.createConverter(this, channel, coordinatorHandler, node.getIeeeAddress(),
Integer.parseInt(properties.get(ZigBeeBindingConstants.CHANNEL_PROPERTY_ENDPOINT)));
}

/**
* Process a static cluster list and add it to the existing list
*
Expand Down Expand Up @@ -608,6 +640,8 @@ public void handleRemoval() {
public void handleConfigurationUpdate(Map<String, Object> configurationParameters) {
logger.debug("{}: Configuration received: {}", nodeIeeeAddress, configurationParameters);

boolean initializeDevice = false;

Configuration configuration = editConfiguration();
for (Entry<String, Object> configurationParameter : configurationParameters.entrySet()) {
// Ignore any configuration parameters that have not changed
Expand All @@ -624,6 +658,9 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
case ZigBeeBindingConstants.CONFIGURATION_LEAVE:
coordinatorHandler.leave(nodeIeeeAddress);
break;
case ZigBeeBindingConstants.CONFIGURATION_INITIALIZE_DEVICE:
initializeDevice = true;
break;
default:
break;
}
Expand All @@ -639,6 +676,10 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter

// Persist changes
updateConfiguration(configuration);

if (initializeDevice) {
initializeDevice();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.openhab.binding.zigbee.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.smarthome.config.core.ConfigDescriptionParameter;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameterBuilder;
import org.openhab.binding.zigbee.ZigBeeBindingConstants;

/**
* Provides {@link ConfigDescriptionParameter}s which are supposed to exist in all things
*/
public class ZigBeeConfigDescriptionParameters {

private static final String PARAM_ZIGBEE_INITIALIZE_DEVICE_LABEL = "Initialize device";

private static List<ConfigDescriptionParameter> configDescriptionParameters = Collections
.unmodifiableList(createConfigDescriptionParameters());

/**
* Provides the list of {@link ConfigDescriptionParameter}
*
* @return list of {@link ConfigDescriptionParameter}
*/
public static List<ConfigDescriptionParameter> getParameters() {
return configDescriptionParameters;
}

private static List<ConfigDescriptionParameter> createConfigDescriptionParameters() {
List<ConfigDescriptionParameter> configDescriptionParameters = new ArrayList<>();

configDescriptionParameters.add(ConfigDescriptionParameterBuilder
.create(ZigBeeBindingConstants.CONFIGURATION_INITIALIZE_DEVICE, ConfigDescriptionParameter.Type.BOOLEAN)
.withLabel(PARAM_ZIGBEE_INITIALIZE_DEVICE_LABEL).withDefault(Boolean.FALSE.toString())
.withAdvanced(Boolean.TRUE).withRequired(Boolean.FALSE).build());

return configDescriptionParameters;
}

}
Loading

0 comments on commit 3e64c04

Please sign in to comment.