Search in sources :

Example 1 with ZWaveAssociation

use of org.openhab.binding.zwave.internal.protocol.ZWaveAssociation in project org.openhab.binding.zwave by openhab.

the class ZWaveThingHandler method ZWaveIncomingEvent.

@Override
public void ZWaveIncomingEvent(ZWaveEvent incomingEvent) {
    // Check if this event is for this device
    if (incomingEvent.getNodeId() != nodeId) {
        return;
    }
    logger.debug("NODE {}: Got an event from Z-Wave network: {}", nodeId, incomingEvent.getClass().getSimpleName());
    // Handle command class value events.
    if (incomingEvent instanceof ZWaveCommandClassValueEvent) {
        // Cast to a command class event
        ZWaveCommandClassValueEvent event = (ZWaveCommandClassValueEvent) incomingEvent;
        String commandClass = event.getCommandClass().toString();
        logger.debug("NODE {}: Got a value event from Z-Wave network, endpoint={}, command class={}, value={}", nodeId, event.getEndpoint(), commandClass, event.getValue());
        // If this is a configuration parameter update, process it before the channels
        Configuration configuration = editConfiguration();
        boolean cfgUpdated = false;
        switch(event.getCommandClass()) {
            case COMMAND_CLASS_CONFIGURATION:
                ZWaveConfigurationParameter parameter = ((ZWaveConfigurationParameterEvent) event).getParameter();
                if (parameter == null) {
                    return;
                }
                logger.debug("NODE {}: Update CONFIGURATION {}/{} to {}", nodeId, parameter.getIndex(), parameter.getSize(), parameter.getValue());
                // Check for any sub parameter processing...
                // If we have requested the current state of a parameter and t's waiting to be updated, then we
                // check this here, update the value and send the request...
                // Do this first so we only process the data if we're not waiting to send
                ZWaveConfigSubParameter subParameter = subParameters.get(parameter.getIndex());
                if (subParameter != null) {
                    // Get the new value based on the sub-parameter bitmask
                    int value = subParameter.getValue(parameter.getValue());
                    logger.debug("NODE {}: Updating sub-parameter {} to {}", nodeId, parameter.getIndex(), value);
                    // Remove the sub parameter so we don't loop forever!
                    subParameters.remove(parameter.getIndex());
                    ZWaveNode node = controllerHandler.getNode(nodeId);
                    if (node == null) {
                        logger.warn("NODE {}: Error getting node for config update", nodeId);
                        return;
                    }
                    ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_CONFIGURATION);
                    if (configurationCommandClass == null) {
                        logger.debug("NODE {}: Error getting configurationCommandClass", nodeId);
                        return;
                    }
                    ZWaveConfigurationParameter cfgParameter = configurationCommandClass.getParameter(parameter.getIndex());
                    if (cfgParameter == null) {
                        cfgParameter = new ZWaveConfigurationParameter(parameter.getIndex(), value, parameter.getSize());
                    } else {
                        cfgParameter.setValue(value);
                    }
                    logger.debug("NODE {}: Setting parameter {} to {}", nodeId, cfgParameter.getIndex(), cfgParameter.getValue());
                    node.sendMessage(configurationCommandClass.setConfigMessage(cfgParameter));
                    node.sendMessage(configurationCommandClass.getConfigMessage(parameter.getIndex()));
                    // Don't process the data - it hasn't been updated yet!
                    break;
                }
                updateConfigurationParameter(configuration, parameter.getIndex(), parameter.getSize(), parameter.getValue());
                break;
            case COMMAND_CLASS_ASSOCIATION:
            case COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION:
                int groupId = ((ZWaveAssociationEvent) event).getGroupId();
                List<ZWaveAssociation> groupMembers = ((ZWaveAssociationEvent) event).getGroupMembers();
                // getAssociationConfigList(ZWaveAssociationGroup newMembers) ;
                // if (groupMembers != null) {
                // logger.debug("NODE {}: Update ASSOCIATION group_{}", nodeId, groupId);
                // List<String> group = new ArrayList<String>();
                // Build the configuration value
                // for (ZWaveAssociation groupMember : groupMembers) {
                // logger.debug("NODE {}: Update ASSOCIATION group_{}: Adding {}", nodeId, groupId,
                // groupMember);
                // group.add(groupMember.toString());
                // }
                // logger.debug("NODE {}: Update ASSOCIATION group_{}: {} members", nodeId, groupId, group.size());
                // cfgUpdated = true;
                configuration.put("group_" + groupId, getAssociationConfigList(groupMembers));
                removePendingConfig("group_" + groupId);
                // }
                break;
            case COMMAND_CLASS_SWITCH_ALL:
                cfgUpdated = true;
                configuration.put(ZWaveBindingConstants.CONFIGURATION_SWITCHALLMODE, event.getValue());
                removePendingConfig(ZWaveBindingConstants.CONFIGURATION_SWITCHALLMODE);
                break;
            case COMMAND_CLASS_NODE_NAMING:
                switch((ZWaveNodeNamingCommandClass.Type) event.getType()) {
                    case NODENAME_LOCATION:
                        cfgUpdated = true;
                        configuration.put(ZWaveBindingConstants.CONFIGURATION_NODELOCATION, event.getValue());
                        removePendingConfig(ZWaveBindingConstants.CONFIGURATION_NODELOCATION);
                        break;
                    case NODENAME_NAME:
                        cfgUpdated = true;
                        configuration.put(ZWaveBindingConstants.CONFIGURATION_NODENAME, event.getValue());
                        removePendingConfig(ZWaveBindingConstants.CONFIGURATION_NODENAME);
                        break;
                }
                break;
            case COMMAND_CLASS_DOOR_LOCK:
                switch((ZWaveDoorLockCommandClass.Type) event.getType()) {
                    case DOOR_LOCK_TIMEOUT:
                        cfgUpdated = true;
                        configuration.put(ZWaveBindingConstants.CONFIGURATION_DOORLOCKTIMEOUT, event.getValue());
                        removePendingConfig(ZWaveBindingConstants.CONFIGURATION_DOORLOCKTIMEOUT);
                        break;
                    default:
                        break;
                }
                break;
            case COMMAND_CLASS_USER_CODE:
                ZWaveUserCodeValueEvent codeEvent = (ZWaveUserCodeValueEvent) event;
                cfgUpdated = true;
                String codeParameterName = ZWaveBindingConstants.CONFIGURATION_USERCODE_CODE + codeEvent.getId();
                if (codeEvent.getStatus() == UserIdStatusType.OCCUPIED) {
                    configuration.put(codeParameterName, codeEvent.getCode());
                } else {
                    configuration.put(codeParameterName, "");
                }
                removePendingConfig(codeParameterName);
                break;
            default:
                break;
        }
        if (cfgUpdated == true) {
            logger.debug("NODE {}: Config updated", nodeId);
            updateConfiguration(configuration);
        }
        if (thingChannelsState == null) {
            logger.debug("NODE {}: No state handlers!", nodeId);
            return;
        }
        // Process the channels to see if we're interested
        for (ZWaveThingChannel channel : thingChannelsState) {
            logger.trace("NODE {}: Checking channel={}, cmdClass={}, endpoint={}", nodeId, channel.getUID(), channel.getCommandClass(), channel.getEndpoint());
            if (channel.getEndpoint() != event.getEndpoint()) {
                continue;
            }
            // Is this command class associated with this channel?
            if (!channel.getCommandClass().equals(commandClass)) {
                continue;
            }
            if (channel.getConverter() == null) {
                logger.warn("NODE {}: No state converter set for channel {}", nodeId, channel.getUID());
                return;
            }
            // logger.debug("NODE {}: Processing event as channel {} {}", nodeId, channel.getUID(),
            // channel.dataType);
            State state = channel.getConverter().handleEvent(channel, event);
            if (state != null) {
                logger.debug("NODE {}: Updating channel state {} to {} [{}]", nodeId, channel.getUID(), state, state.getClass().getSimpleName());
                updateState(channel.getUID(), state);
            }
        }
        return;
    }
    // Handle transaction complete events.
    if (incomingEvent instanceof ZWaveTransactionCompletedEvent) {
        return;
    }
    // Handle wakeup notification events.
    if (incomingEvent instanceof ZWaveWakeUpEvent) {
        ZWaveNode node = controllerHandler.getNode(nodeId);
        if (node == null) {
            return;
        }
        switch(((ZWaveWakeUpEvent) incomingEvent).getEvent()) {
            case ZWaveWakeUpCommandClass.WAKE_UP_INTERVAL_REPORT:
                ZWaveWakeUpCommandClass commandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_WAKE_UP);
                Configuration configuration = editConfiguration();
                configuration.put(ZWaveBindingConstants.CONFIGURATION_WAKEUPINTERVAL, commandClass.getInterval());
                removePendingConfig(ZWaveBindingConstants.CONFIGURATION_WAKEUPINTERVAL);
                configuration.put(ZWaveBindingConstants.CONFIGURATION_WAKEUPNODE, commandClass.getTargetNodeId());
                removePendingConfig(ZWaveBindingConstants.CONFIGURATION_WAKEUPNODE);
                updateConfiguration(configuration);
                break;
        }
        return;
    }
    // Handle node state change events.
    if (incomingEvent instanceof ZWaveNodeStatusEvent) {
        // Cast to a command class event
        ZWaveNodeStatusEvent event = (ZWaveNodeStatusEvent) incomingEvent;
        switch(event.getState()) {
            case AWAKE:
                Map<String, String> properties = editProperties();
                properties.put(ZWaveBindingConstants.PROPERTY_LASTWAKEUP, getISO8601StringForCurrentDate());
                updateProperties(properties);
                break;
            case ASLEEP:
                break;
            case INITIALIZING:
            case ALIVE:
                logger.debug("NODE {}: Setting ONLINE", nodeId);
                updateStatus(ThingStatus.ONLINE);
                break;
            case DEAD:
            case FAILED:
                logger.debug("NODE {}: Setting OFFLINE", nodeId);
                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, ZWaveBindingConstants.OFFLINE_NODE_DEAD);
                break;
        }
        return;
    }
    if (incomingEvent instanceof ZWaveInitializationStateEvent) {
        ZWaveInitializationStateEvent initEvent = (ZWaveInitializationStateEvent) incomingEvent;
        switch(initEvent.getStage()) {
            case STATIC_END:
                // Update some properties first...
                updateNodeProperties();
                // Do we need to change type?
                if (finalTypeSet == false) {
                    if (updateThingType() == true) {
                        // The thing will have already been disposed of so let's get the hell out of here!
                        return;
                    }
                }
                if (finalTypeSet) {
                    // Now that this node is initialised, we want to re-process all channels
                    initialiseNode();
                }
                break;
            case HEAL_START:
                break;
            case HEAL_END:
                Map<String, String> properties = editProperties();
                properties.put(ZWaveBindingConstants.PROPERTY_LASTHEAL, getISO8601StringForCurrentDate());
                updateProperties(properties);
                break;
            // Don't update the thing state for dynamic updates - this is just polling
            case DYNAMIC_VALUES:
            case DYNAMIC_END:
                break;
            // Don't update the thing state when doing a heal
            case UPDATE_NEIGHBORS:
            case GET_NEIGHBORS:
            case DELETE_SUC_ROUTES:
            case SUC_ROUTE:
            case DELETE_ROUTES:
            case RETURN_ROUTES:
                break;
            case DONE:
                updateStatus(ThingStatus.ONLINE);
                break;
            default:
                if (finalTypeSet) {
                    updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "Node initialising: " + initEvent.getStage().toString());
                }
                break;
        }
    }
    if (incomingEvent instanceof ZWaveNetworkEvent) {
        ZWaveNetworkEvent networkEvent = (ZWaveNetworkEvent) incomingEvent;
        if (networkEvent.getEvent() == ZWaveNetworkEvent.Type.NodeRoutingInfo) {
            updateNodeNeighbours();
        }
        if (networkEvent.getEvent() == ZWaveNetworkEvent.Type.DeleteNode) {
            // TODO: Update to THING_GONE
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE);
        }
    }
    if (incomingEvent instanceof ZWaveDelayedPollEvent) {
        long delay = ((ZWaveDelayedPollEvent) incomingEvent).getDelay();
        TimeUnit unit = ((ZWaveDelayedPollEvent) incomingEvent).getUnit();
        // Don't create a poll beyond our max value
        if (unit.toSeconds(delay) > DELAYED_POLLING_PERIOD_MAX) {
            delay = DELAYED_POLLING_PERIOD_MAX;
            unit = TimeUnit.SECONDS;
        }
        startPolling(unit.toMillis(delay));
    }
    // Handle exclusion of this node
    if (incomingEvent instanceof ZWaveInclusionEvent) {
        ZWaveInclusionEvent incEvent = (ZWaveInclusionEvent) incomingEvent;
        if (incEvent.getNodeId() != nodeId) {
            return;
        }
        switch(incEvent.getEvent()) {
            case ExcludeDone:
                // Let our users know we're gone!
                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Node was excluded from the controller");
                // Remove the XML file
                ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
                nodeSerializer.deleteNode(controllerHandler.getHomeId(), nodeId);
                // Stop polling
                synchronized (pollingSync) {
                    if (pollingJob != null) {
                        pollingJob.cancel(true);
                        pollingJob = null;
                    }
                }
                break;
            default:
                break;
        }
    }
}
Also used : Configuration(org.openhab.core.config.core.Configuration) ZWaveConfigurationParameter(org.openhab.binding.zwave.internal.protocol.ZWaveConfigurationParameter) ZWaveAssociationEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveAssociationEvent) ZWaveWakeUpCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass) ZWaveNetworkEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent) ZWaveNodeSerializer(org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeSerializer) ZWaveConfigurationCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass) ZWaveDelayedPollEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveDelayedPollEvent) TimeUnit(java.util.concurrent.TimeUnit) ZWaveCommandClassValueEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent) ZWaveAssociation(org.openhab.binding.zwave.internal.protocol.ZWaveAssociation) ZWaveNodeStatusEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveNodeStatusEvent) ZWaveTransactionCompletedEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent) ZWaveInclusionEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveInclusionEvent) ZWaveUserCodeValueEvent(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveUserCodeCommandClass.ZWaveUserCodeValueEvent) ZWaveWakeUpEvent(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) ZWaveConfigurationParameterEvent(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass.ZWaveConfigurationParameterEvent) UserIdStatusType(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveUserCodeCommandClass.UserIdStatusType) ThingType(org.openhab.core.thing.type.ThingType) RefreshType(org.openhab.core.types.RefreshType) DataType(org.openhab.binding.zwave.handler.ZWaveThingChannel.DataType) ZWaveNode(org.openhab.binding.zwave.internal.protocol.ZWaveNode) ZWaveNodeState(org.openhab.binding.zwave.internal.protocol.ZWaveNodeState) State(org.openhab.core.types.State) ZWaveInitializationStateEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveInitializationStateEvent)

Example 2 with ZWaveAssociation

use of org.openhab.binding.zwave.internal.protocol.ZWaveAssociation in project org.openhab.binding.zwave by openhab.

the class ZWaveAssociationCommandClass method handleAssociationReport.

/**
 * Processes a ASSOCIATIONCMD_REPORT message.
 *
 * @param serialMessage
 *            the incoming message to process.
 * @param offset
 *            the offset position from which to start message processing.
 * @throws ZWaveSerialMessageException
 */
@ZWaveResponseHandler(id = ASSOCIATIONCMD_REPORT, name = "ASSOCIATIONCMD_REPORT")
public void handleAssociationReport(ZWaveCommandClassPayload payload, int endpoint) {
    // Extract the group index
    int group = payload.getPayloadByte(2);
    // The max associations supported (0 if the requested group is not supported)
    int maxAssociations = payload.getPayloadByte(3);
    // Number of outstanding requests (if the group is large, it may come in multiple frames)
    int following = payload.getPayloadByte(4);
    if (maxAssociations == 0) {
        // Unsupported association group. Nothing to do!
        if (updateAssociationsNode == group) {
            logger.debug("NODE {}: All association groups acquired.", getNode().getNodeId());
            updateAssociationsNode = 0;
            // This is used for network management, so send a network event
            getController().notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssociationUpdate, getNode().getNodeId(), ZWaveNetworkEvent.State.Success));
        }
        return;
    }
    logger.debug("NODE {}: association group {} has max associations {}", getNode().getNodeId(), group, maxAssociations);
    // Are we waiting to synchronise the start of a new group?
    if (pendingAssociation == null) {
        pendingAssociation = new ZWaveAssociationGroup(group);
    }
    if (payload.getPayloadLength() > 4) {
        logger.debug("NODE {}: association group {} includes the following nodes:", getNode().getNodeId(), group);
        int numAssociations = payload.getPayloadLength() - (5);
        for (int cnt = 0; cnt < numAssociations; cnt++) {
            int node = payload.getPayloadByte(5 + cnt);
            logger.debug("Node {}", node);
            // Add the node to the group
            pendingAssociation.addAssociation(new ZWaveAssociation(node));
        }
    }
    // If this is the end of the group, update the list then let the listeners know
    if (following == 0) {
        // Update the group in the list
        getNode().getAssociationGroup(pendingAssociation.getIndex()).setAssociations(pendingAssociation.getAssociations());
        // Send an event to the users
        ZWaveAssociationEvent zEvent = new ZWaveAssociationEvent(getNode().getNodeId(), pendingAssociation);
        pendingAssociation = null;
        getController().notifyEventListeners(zEvent);
    }
    // Is this the end of the list
    if (following == 0 && group == updateAssociationsNode) {
        // so we need to request the next group
        if (updateAssociationsNode < maxGroups) {
            updateAssociationsNode++;
            ZWaveCommandClassTransactionPayload outputMessage = getAssociationMessage(updateAssociationsNode);
            if (outputMessage != null) {
                getController().sendData(outputMessage);
            }
        } else {
            logger.debug("NODE {}: All association groups acquired.", getNode().getNodeId());
            // We have reached our maxNodes, notify listeners we are done.
            updateAssociationsNode = 0;
            // This is used for network management, so send a network event
            getController().notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssociationUpdate, getNode().getNodeId(), ZWaveNetworkEvent.State.Success));
        }
    }
}
Also used : ZWaveNetworkEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent) ZWaveCommandClassTransactionPayload(org.openhab.binding.zwave.internal.protocol.transaction.ZWaveCommandClassTransactionPayload) ZWaveAssociationGroup(org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup) ZWaveAssociationEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveAssociationEvent) ZWaveEndpoint(org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint) ZWaveAssociation(org.openhab.binding.zwave.internal.protocol.ZWaveAssociation)

Example 3 with ZWaveAssociation

use of org.openhab.binding.zwave.internal.protocol.ZWaveAssociation in project org.openhab.binding.zwave by openhab.

the class ZWaveMultiAssociationCommandClass method handleMultiAssociationReport.

/**
 * Processes a MULTI_ASSOCIATIONCMD_REPORT message.
 *
 * @param serialMessage
 *            the incoming message to process.
 * @param offset
 *            the offset position from which to start message processing.
 * @throws ZWaveSerialMessageException
 */
@ZWaveResponseHandler(id = MULTI_ASSOCIATIONCMD_REPORT, name = "MULTI_ASSOCIATIONCMD_REPORT")
public void handleMultiAssociationReport(ZWaveCommandClassPayload payload, int endpoint) {
    // Extract the group index
    int group = payload.getPayloadByte(2);
    // The max associations supported (0 if the requested group is not supported)
    int maxAssociations = payload.getPayloadByte(3);
    // Number of outstanding requests (if the group is large, it may come in multiple frames)
    int following = payload.getPayloadByte(4);
    if (maxAssociations == 0) {
        // Unsupported association group. Nothing to do!
        if (updateAssociationsNode == group) {
            logger.debug("NODE {}: All association groups acquired.", getNode().getNodeId());
            updateAssociationsNode = 0;
            // This is used for network management, so send a network event
            getController().notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssociationUpdate, getNode().getNodeId(), ZWaveNetworkEvent.State.Success));
        }
        return;
    }
    logger.debug("NODE {}: association group {} has max associations {}", getNode().getNodeId(), group, maxAssociations);
    // Are we waiting to synchronise the start of a new group?
    if (pendingAssociation == null) {
        pendingAssociation = new ZWaveAssociationGroup(group);
    }
    if (payload.getPayloadLength() > 5) {
        logger.debug("NODE {}: Association group {} includes the following nodes:", getNode().getNodeId(), group);
        int dataLength = payload.getPayloadLength() - 5;
        int dataPointer = 0;
        // Process the root associations
        for (; dataPointer < dataLength; dataPointer++) {
            int node = payload.getPayloadByte(5 + dataPointer);
            if (node == MULTI_INSTANCE_MARKER) {
                break;
            }
            logger.debug("NODE {}: Associated with Node {} in group {}", getNode().getNodeId(), node, group);
            // Add the node to the group
            pendingAssociation.addAssociation(new ZWaveAssociation(node));
        }
        // Process the multi instance associations
        if (dataPointer < dataLength) {
            logger.trace("NODE {}: Includes multi_instance associations", getNode().getNodeId());
            // Step over the marker
            dataPointer++;
            for (; dataPointer < dataLength; dataPointer += 2) {
                int node = payload.getPayloadByte(5 + dataPointer);
                int endpointId = payload.getPayloadByte(6 + dataPointer);
                if (node == MULTI_INSTANCE_MARKER) {
                    break;
                }
                logger.debug("NODE {}: Associated with Node {} endpoint {} in group", getNode().getNodeId(), node, endpointId, group);
                // Add the node to the group
                pendingAssociation.addAssociation(new ZWaveAssociation(node, endpointId));
            }
        }
    }
    // If this is the end of the group, update the list then let the listeners know
    if (following == 0) {
        // Clear the current information for this group
        ZWaveAssociationGroup associationGroup = getNode().getAssociationGroup(group);
        if (associationGroup != null) {
            // Update the group in the list
            getNode().getAssociationGroup(pendingAssociation.getIndex()).setAssociations(pendingAssociation.getAssociations());
        }
        // Send an event to the users
        ZWaveAssociationEvent zEvent = new ZWaveAssociationEvent(getNode().getNodeId(), pendingAssociation);
        pendingAssociation = null;
        getController().notifyEventListeners(zEvent);
    }
    // Is this the end of the list
    if (following == 0 && group == updateAssociationsNode) {
        // so we need to request the next group
        if (updateAssociationsNode < maxGroups) {
            updateAssociationsNode++;
            ZWaveCommandClassTransactionPayload transaction = getAssociationMessage(updateAssociationsNode);
            if (transaction != null) {
                getController().sendData(transaction);
            }
        } else {
            logger.debug("NODE {}: All association groups acquired.", getNode().getNodeId());
            // We have reached our maxNodes, notify listeners we are done.
            updateAssociationsNode = 0;
            // This is used for network management, so send a network event
            getController().notifyEventListeners(new ZWaveNetworkEvent(ZWaveNetworkEvent.Type.AssociationUpdate, getNode().getNodeId(), ZWaveNetworkEvent.State.Success));
        }
    }
}
Also used : ZWaveNetworkEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent) ZWaveCommandClassTransactionPayload(org.openhab.binding.zwave.internal.protocol.transaction.ZWaveCommandClassTransactionPayload) ZWaveAssociationGroup(org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup) ZWaveAssociationEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveAssociationEvent) ZWaveEndpoint(org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint) ZWaveAssociation(org.openhab.binding.zwave.internal.protocol.ZWaveAssociation)

Example 4 with ZWaveAssociation

use of org.openhab.binding.zwave.internal.protocol.ZWaveAssociation in project org.openhab.binding.zwave by openhab.

the class ZWaveThingHandler method updateNodeProperties.

private void updateNodeProperties() {
    if (controllerHandler == null) {
        logger.debug("NODE {}: Updating node properties. Controller not found.", nodeId);
        return;
    }
    ZWaveNode node = controllerHandler.getNode(nodeId);
    if (node == null) {
        logger.debug("NODE {}: Updating node properties. Node not found.", nodeId);
        return;
    }
    logger.debug("NODE {}: Updating node properties.", nodeId);
    // Update property information about this device
    Map<String, String> properties = editProperties();
    updateProperty(ZWaveBindingConstants.PROPERTY_NODEID, Integer.toString(nodeId));
    logger.debug("NODE {}: Updating node properties. MAN={}", nodeId, node.getManufacturer());
    if (node.getManufacturer() != Integer.MAX_VALUE) {
        logger.debug("NODE {}: Updating node properties. MAN={}. SET. Was {}", nodeId, node.getManufacturer(), properties.get(ZWaveBindingConstants.PROPERTY_MANUFACTURER));
        properties.put(ZWaveBindingConstants.PROPERTY_MANUFACTURER, Integer.toString(node.getManufacturer()));
    }
    if (node.getDeviceType() != Integer.MAX_VALUE) {
        properties.put(ZWaveBindingConstants.PROPERTY_DEVICETYPE, Integer.toString(node.getDeviceType()));
    }
    if (node.getDeviceId() != Integer.MAX_VALUE) {
        properties.put(ZWaveBindingConstants.PROPERTY_DEVICEID, Integer.toString(node.getDeviceId()));
    }
    properties.put(ZWaveBindingConstants.PROPERTY_VERSION, node.getApplicationVersion());
    properties.put(ZWaveBindingConstants.PROPERTY_CLASS_BASIC, node.getDeviceClass().getBasicDeviceClass().toString());
    properties.put(ZWaveBindingConstants.PROPERTY_CLASS_GENERIC, node.getDeviceClass().getGenericDeviceClass().toString());
    properties.put(ZWaveBindingConstants.PROPERTY_CLASS_SPECIFIC, node.getDeviceClass().getSpecificDeviceClass().toString());
    properties.put(ZWaveBindingConstants.PROPERTY_LISTENING, Boolean.toString(node.isListening()));
    properties.put(ZWaveBindingConstants.PROPERTY_FREQUENT, Boolean.toString(node.isFrequentlyListening()));
    properties.put(ZWaveBindingConstants.PROPERTY_BEAMING, Boolean.toString(node.isBeaming()));
    properties.put(ZWaveBindingConstants.PROPERTY_ROUTING, Boolean.toString(node.isRouting()));
    properties.put(ZWaveBindingConstants.PROPERTY_USINGSECURITY, Boolean.toString(node.isSecure()));
    // If this is a Z-Wave Plus device, then also add its class
    ZWavePlusCommandClass cmdClassZWavePlus = (ZWavePlusCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_ZWAVEPLUS_INFO);
    if (cmdClassZWavePlus != null) {
        properties.put(ZWaveBindingConstants.PROPERTY_ZWPLUS_DEVICETYPE, cmdClassZWavePlus.getNodeType());
        properties.put(ZWaveBindingConstants.PROPERTY_ZWPLUS_ROLETYPE, cmdClassZWavePlus.getRoleType());
    }
    // Must loop over the new properties since we might have added data
    boolean update = false;
    Map<String, String> originalProperties = editProperties();
    for (String property : properties.keySet()) {
        if ((originalProperties.get(property) == null || originalProperties.get(property).equals(properties.get(property)) == false)) {
            update = true;
            break;
        }
    }
    update = true;
    if (update == true) {
        logger.debug("NODE {}: Properties synchronised", nodeId);
        updateProperties(properties);
    }
    // We need to synchronise the configuration between the ZWave library and ESH.
    // This is especially important when the device is first added as the ESH representation of the config
    // will be set to defaults. We will also not have any defaults for association groups, wakeup etc.
    Configuration config = editConfiguration();
    // Process CONFIGURATION
    ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_CONFIGURATION);
    if (configurationCommandClass != null) {
        // Iterate over all parameters and process
        for (int paramId : configurationCommandClass.getParameters().keySet()) {
            ZWaveConfigurationParameter parameter = configurationCommandClass.getParameter(paramId);
            updateConfigurationParameter(config, parameter.getIndex(), parameter.getSize(), parameter.getValue());
        }
    }
    // Process ASSOCIATION
    for (ZWaveAssociationGroup group : node.getAssociationGroups().values()) {
        List<String> members = new ArrayList<String>();
        // Build the configuration value
        for (ZWaveAssociation groupMember : group.getAssociations()) {
            if (groupMember.getNode() == controllerHandler.getOwnNodeId()) {
                logger.debug("NODE {}: Update ASSOCIATION group_{}: Adding Controller ({})", nodeId, group, groupMember);
                members.add(ZWaveBindingConstants.GROUP_CONTROLLER);
            } else {
                logger.debug("NODE {}: Update ASSOCIATION group_{}: Adding {}", nodeId, group, groupMember);
                members.add(groupMember.toString());
            }
        }
        config.put("group_" + group.getIndex(), members);
    }
    // Process WAKE_UP
    ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_WAKE_UP);
    if (wakeupCommandClass != null) {
        config.put(ZWaveBindingConstants.CONFIGURATION_WAKEUPINTERVAL, wakeupCommandClass.getInterval());
        config.put(ZWaveBindingConstants.CONFIGURATION_WAKEUPNODE, wakeupCommandClass.getTargetNodeId());
    }
    // Process SWITCH_ALL
    ZWaveSwitchAllCommandClass switchallCommandClass = (ZWaveSwitchAllCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_SWITCH_ALL);
    if (switchallCommandClass != null) {
        if (switchallCommandClass.getMode() != null) {
            config.put(ZWaveBindingConstants.CONFIGURATION_SWITCHALLMODE, switchallCommandClass.getMode().getMode());
        }
    }
    // Process NODE_NAMING
    ZWaveNodeNamingCommandClass nodenamingCommandClass = (ZWaveNodeNamingCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_NODE_NAMING);
    if (nodenamingCommandClass != null) {
        if (nodenamingCommandClass.getLocation() != null) {
            config.put(ZWaveBindingConstants.CONFIGURATION_NODELOCATION, nodenamingCommandClass.getLocation());
        }
        if (nodenamingCommandClass.getName() != null) {
            config.put(ZWaveBindingConstants.CONFIGURATION_NODENAME, nodenamingCommandClass.getName());
        }
    }
    // Only update if configuration has changed
    Configuration originalConfig = editConfiguration();
    update = false;
    for (String property : config.getProperties().keySet()) {
        if (config.get(property) != null && config.get(property).equals(originalConfig.get(property)) == false) {
            update = true;
            break;
        }
    }
    if (update == true) {
        logger.debug("NODE {}: Configuration synchronised", nodeId);
        updateConfiguration(config);
    }
}
Also used : Configuration(org.openhab.core.config.core.Configuration) ArrayList(java.util.ArrayList) ZWaveSwitchAllCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveSwitchAllCommandClass) ZWaveConfigurationParameter(org.openhab.binding.zwave.internal.protocol.ZWaveConfigurationParameter) ZWaveAssociationGroup(org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup) ZWaveWakeUpCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass) ZWaveNodeNamingCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveNodeNamingCommandClass) ZWaveNode(org.openhab.binding.zwave.internal.protocol.ZWaveNode) ZWavePlusCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWavePlusCommandClass) ZWaveConfigurationCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass) ZWaveAssociation(org.openhab.binding.zwave.internal.protocol.ZWaveAssociation)

Example 5 with ZWaveAssociation

use of org.openhab.binding.zwave.internal.protocol.ZWaveAssociation in project org.openhab.binding.zwave by openhab.

the class ZWaveThingHandler method handleConfigurationUpdate.

@Override
public void handleConfigurationUpdate(Map<String, Object> configurationParameters) throws ConfigValidationException {
    logger.debug("NODE {}: Configuration update received", nodeId);
    // Perform checking on the configuration
    validateConfigurationParameters(configurationParameters);
    if (controllerHandler == null) {
        logger.debug("NODE {}: Configuration update not processed as controller not found", nodeId);
        return;
    }
    ZWaveNode node = controllerHandler.getNode(nodeId);
    if (node == null) {
        logger.debug("NODE {}: Configuration update not processed as node not found", nodeId);
        return;
    }
    // Wakeup targets are not set immediately during the config as we need to correlate multiple settings
    // Record them in these variables and set them at the end if one or both are configured
    Integer wakeupNode = null;
    Integer wakeupInterval = null;
    Configuration configuration = editConfiguration();
    for (Entry<String, Object> configurationParameter : configurationParameters.entrySet()) {
        Object valueObject = configurationParameter.getValue();
        // Ignore any configuration parameters that have not changed
        if (Objects.equals(configurationParameter.getValue(), configuration.get(configurationParameter.getKey()))) {
            logger.debug("NODE {}: Configuration update ignored {} to {} ({})", nodeId, configurationParameter.getKey(), valueObject, valueObject == null ? "null" : valueObject.getClass().getSimpleName());
            continue;
        }
        logger.debug("NODE {}: Configuration update set {} to {} ({})", nodeId, configurationParameter.getKey(), valueObject, valueObject == null ? "null" : valueObject.getClass().getSimpleName());
        String[] cfg = configurationParameter.getKey().split("_");
        switch(cfg[0]) {
            case "config":
                if (cfg.length < 3) {
                    logger.warn("NODE {}: Configuration invalid {}", nodeId, configurationParameter.getKey());
                    continue;
                }
                ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_CONFIGURATION);
                if (configurationCommandClass == null) {
                    logger.debug("NODE {}: Error getting configurationCommandClass", nodeId);
                    continue;
                }
                // Get the size
                int size = Integer.parseInt(cfg[2]);
                if (size == 0 || size > 4) {
                    logger.debug("NODE {}: Size error ({}) from {}", nodeId, size, configurationParameter.getKey());
                    continue;
                }
                // Convert to integer
                Integer value;
                if (configurationParameter.getValue() instanceof BigDecimal) {
                    value = ((BigDecimal) configurationParameter.getValue()).intValue();
                } else if (configurationParameter.getValue() instanceof String) {
                    value = Integer.parseInt((String) configurationParameter.getValue());
                } else {
                    logger.debug("NODE {}: Error converting config value from {}", nodeId, configurationParameter.getValue().getClass());
                    continue;
                }
                Integer parameterIndex = Integer.valueOf(cfg[1]);
                boolean writeOnly = false;
                if (Arrays.asList(cfg).contains("wo")) {
                    writeOnly = true;
                }
                // If we have specified a bitmask, then we need to process this and save for later
                if (cfg.length >= 4 && cfg[3].length() == 8) {
                    int bitmask = 0xffffffff;
                    try {
                        bitmask = Integer.parseInt(cfg[3], 16);
                    } catch (NumberFormatException e) {
                        logger.debug("NODE {}: Error parsing bitmask for {}", nodeId, configurationParameter.getKey());
                    }
                    boolean requestUpdate = false;
                    ZWaveConfigSubParameter subParameter = subParameters.get(parameterIndex);
                    if (subParameter == null) {
                        subParameter = new ZWaveConfigSubParameter();
                        requestUpdate = true;
                    }
                    logger.debug("NODE {}: Set sub-parameter {} from {} / {}", nodeId, parameterIndex, value, String.format("%08X", bitmask));
                    logger.debug("NODE {}: Parameter {} set value {} mask {}", nodeId, parameterIndex, String.format("%08X", value), String.format("%08X", bitmask));
                    subParameter.addBitmask(bitmask, value);
                    subParameters.put(parameterIndex, subParameter);
                    // Only send the request if there's not already a request outstanding
                    if (requestUpdate == true) {
                        node.sendMessage(configurationCommandClass.getConfigMessage(parameterIndex));
                    }
                } else {
                    ZWaveConfigurationParameter cfgParameter = configurationCommandClass.getParameter(parameterIndex);
                    if (cfgParameter == null) {
                        cfgParameter = new ZWaveConfigurationParameter(parameterIndex, value, size);
                    } else {
                        cfgParameter.setValue(value);
                    }
                    // Set the parameter and request a read-back if it's not a write only parameter
                    node.sendMessage(configurationCommandClass.setConfigMessage(cfgParameter));
                    if (writeOnly == false) {
                        node.sendMessage(configurationCommandClass.getConfigMessage(parameterIndex));
                    }
                }
                addPendingConfig(configurationParameter.getKey(), valueObject);
                break;
            case "group":
                if (cfg.length < 2) {
                    logger.debug("NODE {}: Association invalid {}", nodeId, configurationParameter.getKey());
                    continue;
                }
                Integer groupIndex = Integer.valueOf(cfg[1]);
                // Get the configuration information.
                // This should be an array of nodes, and/or nodes and endpoints
                ArrayList<String> paramValues = new ArrayList<String>();
                Object parameter = configurationParameter.getValue();
                if (parameter instanceof List) {
                    paramValues.addAll((List) configurationParameter.getValue());
                } else if (parameter instanceof String) {
                    String strParam = ((String) parameter).trim();
                    // It's a kludge, but let's try and handle this format...
                    if (strParam.startsWith("[") && strParam.endsWith("]")) {
                        strParam = strParam.substring(1, strParam.length() - 1);
                        if (strParam.contains(",")) {
                            String[] splits = strParam.split(",");
                            for (String split : splits) {
                                paramValues.add(split.trim());
                            }
                        }
                    } else {
                        paramValues.add(strParam);
                    }
                }
                logger.debug("NODE {}: Association {} consolidated to {}", nodeId, groupIndex, paramValues);
                ZWaveAssociationGroup currentMembers = node.getAssociationGroup(groupIndex);
                if (currentMembers == null) {
                    logger.debug("NODE {}: Unknown association group {}", nodeId, groupIndex);
                    continue;
                }
                logger.debug("NODE {}: Current members before update {}", nodeId, currentMembers);
                ZWaveAssociationGroup newMembers = new ZWaveAssociationGroup(groupIndex);
                // Loop over all the values
                for (String paramValue : paramValues) {
                    // Check if this is the controller
                    if (paramValue.equals(ZWaveBindingConstants.GROUP_CONTROLLER)) {
                        newMembers.addAssociation(new ZWaveAssociation(controllerHandler.getOwnNodeId(), 1));
                    } else {
                        String[] groupCfg = paramValue.split("_");
                        // Make sure this is a correctly formatted option
                        if (!"node".equals(groupCfg[0])) {
                            logger.debug("NODE {}: Invalid association {} ({})", nodeId, paramValue, groupCfg[0]);
                            continue;
                        }
                        int groupNode = Integer.parseInt(groupCfg[1]);
                        if (groupNode == controllerHandler.getOwnNodeId()) {
                            logger.debug("NODE {}: Association is for controller", nodeId);
                            newMembers.addAssociation(new ZWaveAssociation(controllerHandler.getOwnNodeId(), 1));
                            continue;
                        }
                        // Get the node Id and endpoint Id
                        if (groupCfg.length == 2) {
                            newMembers.addAssociation(new ZWaveAssociation(groupNode));
                        } else {
                            newMembers.addAssociation(new ZWaveAssociation(groupNode, Integer.parseInt(groupCfg[2])));
                        }
                    }
                }
                logger.debug("NODE {}: Members after config update {}", nodeId, newMembers);
                if (controllerHandler.isControllerMaster()) {
                    logger.debug("NODE {}: Controller is master - forcing associations", nodeId);
                    // Check if this is the lifeline profile
                    if (newMembers.getProfile1() == 0x00 && newMembers.getProfile2() == 0x01) {
                        logger.debug("NODE {}: Group is lifeline - forcing association", nodeId);
                        newMembers.addAssociation(new ZWaveAssociation(controllerHandler.getOwnNodeId(), 1));
                    }
                    ThingType thingType = ZWaveConfigProvider.getThingType(node);
                    if (thingType == null) {
                        logger.debug("NODE {}: Thing type not found for association check", node.getNodeId());
                    } else {
                        String associations = thingType.getProperties().get(ZWaveBindingConstants.PROPERTY_XML_ASSOCIATIONS);
                        if (associations == null || associations.length() == 0) {
                            logger.debug("NODE {}: Thing has no default associations", node.getNodeId());
                        } else {
                            String[] defaultGroups = associations.split(",");
                            if (Arrays.asList(defaultGroups).contains(cfg[1])) {
                                logger.debug("NODE {}: Group is controller - forcing association", nodeId);
                                newMembers.addAssociation(new ZWaveAssociation(controllerHandler.getOwnNodeId(), 1));
                            }
                        }
                    }
                    logger.debug("NODE {}: Members after controller update {}", nodeId, newMembers);
                }
                // This ensures we don't end up with strange ghost associations
                if (newMembers.getAssociationCnt() == 0) {
                    logger.debug("NODE {}: Association group {} contains no members. Clearing.", nodeId, groupIndex);
                    node.sendMessage(node.clearAssociation(groupIndex));
                } else {
                    // Loop through the current members and remove anything that's not in the new members list
                    for (ZWaveAssociation member : currentMembers.getAssociations()) {
                        // Is the current association still in the newMembers list?
                        if (newMembers.isAssociated(member) == false) {
                            logger.debug("NODE {}: Removing {} from association group {}", nodeId, member, groupIndex);
                            // No - so it needs to be removed
                            node.sendMessage(node.removeAssociation(groupIndex, member));
                        }
                    }
                    // Now loop through the new members and add anything not in the current members list
                    for (ZWaveAssociation member : newMembers.getAssociations()) {
                        // Is the new association still in the currentMembers list?
                        if (currentMembers.isAssociated(member) == false) {
                            logger.debug("NODE {}: Adding {} to association group {}", nodeId, member, groupIndex);
                            // No - so it needs to be added
                            node.sendMessage(node.setAssociation(groupIndex, member));
                        }
                    }
                }
                // Request an update to the association group
                node.sendMessage(node.getAssociation(groupIndex));
                addPendingConfig(configurationParameter.getKey(), valueObject);
                // Create a clean association list
                valueObject = getAssociationConfigList(newMembers.getAssociations());
                break;
            case "wakeup":
                if (configurationParameter.getValue() == null) {
                    logger.debug("NODE {}: Error converting wakeup value null", nodeId);
                    continue;
                }
                Integer wakeupValue = null;
                try {
                    wakeupValue = ((BigDecimal) configurationParameter.getValue()).intValue();
                } catch (NumberFormatException e) {
                    logger.debug("NODE {}: Error converting wakeup value {} from {}", nodeId, cfg[1], configurationParameter.getValue());
                    continue;
                }
                switch(cfg[1]) {
                    case "node":
                        wakeupNode = wakeupValue;
                        logger.debug("NODE {}: Set wakeup node to '{}'", nodeId, wakeupNode);
                        break;
                    case "interval":
                        wakeupInterval = wakeupValue;
                        logger.debug("NODE {}: Set wakeup interval to '{}'", nodeId, wakeupInterval);
                        break;
                    default:
                        logger.debug("NODE {}: Unknown wakeup command {}", nodeId, cfg[1]);
                        break;
                }
                addPendingConfig(configurationParameter.getKey(), valueObject);
                break;
            case "nodename":
                ZWaveNodeNamingCommandClass nameCommandClass = (ZWaveNodeNamingCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_NODE_NAMING);
                if (nameCommandClass == null) {
                    logger.debug("NODE {}: Error getting NodeNamingCommandClass", nodeId);
                    continue;
                }
                if (configurationParameter.getValue() == null || !(configurationParameter.getValue() instanceof String)) {
                    logger.debug("NODE {}: Error setting NodeNamingCommandClass {} to invalid value {}", nodeId, cfg[1], configurationParameter.getValue(), configurationParameter.getValue());
                    continue;
                }
                if ("name".equals(cfg[1])) {
                    node.sendMessage(nameCommandClass.setNameMessage(configurationParameter.getValue().toString()));
                }
                if ("location".equals(cfg[1])) {
                    node.sendMessage(nameCommandClass.setLocationMessage(configurationParameter.getValue().toString()));
                }
                addPendingConfig(configurationParameter.getKey(), valueObject);
                break;
            case "switchall":
                ZWaveSwitchAllCommandClass switchallCommandClass = (ZWaveSwitchAllCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_SWITCH_ALL);
                if (switchallCommandClass == null) {
                    logger.debug("NODE {}: Error getting SwitchAllCommandClass", nodeId);
                    continue;
                }
                if ("mode".equals(cfg[1])) {
                    controllerHandler.sendData(node.encapsulate(switchallCommandClass.setValueMessage(Integer.parseInt(configurationParameter.getValue().toString())), 0));
                }
                addPendingConfig(configurationParameter.getKey(), valueObject);
                break;
            case "doorlock":
                ZWaveDoorLockCommandClass commandClass = (ZWaveDoorLockCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_DOOR_LOCK);
                if (commandClass == null) {
                    logger.debug("NODE {}: Error getting ZWaveDoorLockCommandClass", nodeId);
                    continue;
                }
                if ("timeout".equals(cfg[1])) {
                    boolean timeoutEnabled;
                    try {
                        int doorlockValue = ((BigDecimal) valueObject).intValue();
                        if (doorlockValue == 0) {
                            timeoutEnabled = false;
                        } else {
                            timeoutEnabled = true;
                        }
                        controllerHandler.sendData(node.encapsulate(commandClass.setConfigMessage(timeoutEnabled, doorlockValue), 0));
                        controllerHandler.sendData(node.encapsulate(commandClass.getConfigMessage(), 0));
                        addPendingConfig(ZWaveBindingConstants.CONFIGURATION_DOORLOCKTIMEOUT, valueObject);
                    } catch (NumberFormatException e) {
                        logger.debug("Number format exception parsing doorlock_timeout '{}'", valueObject);
                    }
                }
                break;
            case "usercode":
                ZWaveUserCodeCommandClass userCodeCommandClass = (ZWaveUserCodeCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_USER_CODE);
                if (userCodeCommandClass == null) {
                    logger.debug("NODE {}: Error getting ZWaveUserCodeCommandClass", nodeId);
                    continue;
                }
                if ("code".equals(cfg[1])) {
                    try {
                        int code = Integer.parseInt(cfg[2]);
                        if (code == 0 || code > userCodeCommandClass.getNumberOfSupportedCodes()) {
                            logger.debug("NODE {}: Attempt to set code ID outside of range", nodeId);
                            continue;
                        }
                        if (valueObject instanceof String) {
                            controllerHandler.sendData(node.encapsulate(userCodeCommandClass.setUserCode(code, (String) valueObject), 0));
                            controllerHandler.sendData(node.encapsulate(userCodeCommandClass.getUserCode(code), 0));
                            addPendingConfig(configurationParameter.getKey(), valueObject);
                        } else {
                            logger.warn("Value format error processing user code {}", valueObject);
                        }
                    } catch (NumberFormatException e) {
                        logger.warn("Number format exception parsing user code ID '{}'", configurationParameter.getKey());
                    }
                }
                break;
            case "binding":
                if ("pollperiod".equals(cfg[1])) {
                    pollingPeriod = POLLING_PERIOD_DEFAULT;
                    try {
                        pollingPeriod = ((BigDecimal) configurationParameter.getValue()).intValue();
                    } catch (final NumberFormatException ex) {
                        logger.debug("NODE {}: pollingPeriod ({}) cannot be set - using default", nodeId, configurationParameter.getValue().toString());
                    }
                    if (pollingPeriod < POLLING_PERIOD_MIN) {
                        pollingPeriod = POLLING_PERIOD_MIN;
                    }
                    if (pollingPeriod > POLLING_PERIOD_MAX) {
                        pollingPeriod = POLLING_PERIOD_MAX;
                    }
                    valueObject = new BigDecimal(pollingPeriod);
                    // Restart polling so we use the new value
                    startPolling();
                }
                if ("cmdrepollperiod".equals(cfg[1])) {
                    commandPollDelay = REPOLL_PERIOD_DEFAULT;
                    try {
                        commandPollDelay = ((BigDecimal) configurationParameter.getValue()).intValue();
                    } catch (final NumberFormatException ex) {
                        logger.debug("NODE {}: commandPollDelay ({}) cannot be set - using default", nodeId, configurationParameter.getValue().toString());
                    }
                    if (commandPollDelay != 0 && commandPollDelay < REPOLL_PERIOD_MIN) {
                        commandPollDelay = REPOLL_PERIOD_MIN;
                    }
                    if (commandPollDelay > REPOLL_PERIOD_MAX) {
                        commandPollDelay = REPOLL_PERIOD_MAX;
                    }
                    valueObject = new BigDecimal(commandPollDelay);
                }
                break;
            case "action":
                if ("failed".equals(cfg[1]) && valueObject instanceof Boolean && ((Boolean) valueObject) == true) {
                    controllerHandler.replaceFailedNode(nodeId);
                    controllerHandler.checkNodeFailed(nodeId);
                }
                if ("remove".equals(cfg[1]) && valueObject instanceof Boolean && ((Boolean) valueObject) == true) {
                    controllerHandler.removeFailedNode(nodeId);
                }
                if ("reinit".equals(cfg[1]) && valueObject instanceof Boolean && ((Boolean) valueObject) == true) {
                    logger.debug("NODE {}: Re-initialising node!", nodeId);
                    // Delete the saved XML
                    ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
                    nodeSerializer.deleteNode(node.getHomeId(), nodeId);
                    controllerHandler.reinitialiseNode(nodeId);
                }
                if ("heal".equals(cfg[1]) && valueObject instanceof Boolean && ((Boolean) valueObject) == true) {
                    logger.debug("NODE {}: Starting heal on node!", nodeId);
                    controllerHandler.healNode(nodeId);
                }
                // Don't save the value
                valueObject = false;
                break;
            default:
                logger.debug("NODE {}: Configuration invalid {}", nodeId, configurationParameter.getKey());
        }
        configuration.put(configurationParameter.getKey(), valueObject);
    }
    // Persist changes
    updateConfiguration(configuration);
    // so handle it here once we've processed all configuration
    if (wakeupInterval != null || wakeupNode != null) {
        ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.COMMAND_CLASS_WAKE_UP);
        if (wakeupCommandClass == null) {
            logger.debug("NODE {}: Error getting wakeupCommandClass", nodeId);
        } else {
            // Handle the situation where there is only part of the data defined in this update
            if (wakeupInterval == null) {
                // First try using the current wakeup interval from the thing config
                final BigDecimal cfgInterval = (BigDecimal) getConfig().get(ZWaveBindingConstants.CONFIGURATION_WAKEUPINTERVAL);
                if (cfgInterval != null) {
                    wakeupInterval = cfgInterval.intValue();
                }
                // Then try the existing value from the command class
                if (wakeupInterval == null) {
                    wakeupInterval = wakeupCommandClass.getInterval();
                }
                // Then try system default
                if (wakeupInterval == 0) {
                    wakeupInterval = controllerHandler.getDefaultWakeupPeriod();
                }
                // Then try device default
                if (wakeupInterval == 0) {
                    wakeupInterval = wakeupCommandClass.getDefaultInterval();
                }
                // If all else fails, use 1 hour!
                if (wakeupInterval == 0) {
                    wakeupInterval = 3600;
                }
                logger.debug("NODE {}: Wakeup interval not specified, using {}", nodeId, wakeupInterval);
            }
            if (wakeupNode == null) {
                // First try using the current wakeup node from the thing config
                final BigDecimal cfgNode = (BigDecimal) getConfig().get(ZWaveBindingConstants.CONFIGURATION_WAKEUPNODE);
                if (cfgNode != null) {
                    wakeupNode = cfgNode.intValue();
                }
                // Then try the existing value from the command class
                if (wakeupNode == null) {
                    wakeupNode = wakeupCommandClass.getTargetNodeId();
                }
                // Then just set it to our node ID
                if (wakeupNode == 0) {
                    wakeupNode = controllerHandler.getOwnNodeId();
                }
                logger.debug("NODE {}: Wakeup node not specified, using {}", nodeId, wakeupNode);
            }
            // Set the wake-up interval
            node.sendMessage(wakeupCommandClass.setInterval(wakeupNode, wakeupInterval));
            // And request a read-back
            node.sendMessage(wakeupCommandClass.getIntervalMessage());
        }
    }
}
Also used : Configuration(org.openhab.core.config.core.Configuration) ZWaveDoorLockCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveDoorLockCommandClass) ZWaveUserCodeCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveUserCodeCommandClass) ArrayList(java.util.ArrayList) ZWaveSwitchAllCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveSwitchAllCommandClass) ZWaveConfigurationParameter(org.openhab.binding.zwave.internal.protocol.ZWaveConfigurationParameter) ThingType(org.openhab.core.thing.type.ThingType) ZWaveWakeUpCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass) ZWaveNodeSerializer(org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeSerializer) ZWaveConfigurationCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass) List(java.util.List) ArrayList(java.util.ArrayList) ZWaveAssociation(org.openhab.binding.zwave.internal.protocol.ZWaveAssociation) ZWaveAssociationGroup(org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup) BigDecimal(java.math.BigDecimal) ZWaveNodeNamingCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveNodeNamingCommandClass) ZWaveNode(org.openhab.binding.zwave.internal.protocol.ZWaveNode)

Aggregations

ZWaveAssociation (org.openhab.binding.zwave.internal.protocol.ZWaveAssociation)6 ZWaveAssociationGroup (org.openhab.binding.zwave.internal.protocol.ZWaveAssociationGroup)5 ZWaveConfigurationCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass)4 ZWaveWakeUpCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass)4 ArrayList (java.util.ArrayList)3 ZWaveConfigurationParameter (org.openhab.binding.zwave.internal.protocol.ZWaveConfigurationParameter)3 ZWaveEndpoint (org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint)3 ZWaveNode (org.openhab.binding.zwave.internal.protocol.ZWaveNode)3 ZWaveAssociationEvent (org.openhab.binding.zwave.internal.protocol.event.ZWaveAssociationEvent)3 ZWaveNetworkEvent (org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent)3 ZWaveCommandClassTransactionPayload (org.openhab.binding.zwave.internal.protocol.transaction.ZWaveCommandClassTransactionPayload)3 Configuration (org.openhab.core.config.core.Configuration)3 ZWaveNodeNamingCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveNodeNamingCommandClass)2 ZWaveSwitchAllCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveSwitchAllCommandClass)2 ZWaveNodeSerializer (org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeSerializer)2 ThingType (org.openhab.core.thing.type.ThingType)2 BigDecimal (java.math.BigDecimal)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1