Search in sources :

Example 1 with SerialMessage

use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.

the class ZWaveConfiguration method doSet.

@Override
public void doSet(String domain, String value) {
    logger.debug("doSet domain '{}' to '{}'", domain, value);
    String[] splitDomain = domain.split("/");
    // If the controller isn't ready, then ignore any requests
    if (zController.isConnected() == false) {
        logger.debug("Controller not ready - Ignoring request to '{}'", domain);
        return;
    }
    // There must be at least 2 components to the domain
    if (splitDomain.length < 2) {
        logger.error("Error malformed domain in doSet '{}'", domain);
        return;
    }
    if (splitDomain[0].equals("nodes")) {
        int nodeId = Integer.parseInt(splitDomain[1].substring(4));
        ZWaveNode node = zController.getNode(nodeId);
        if (node == null) {
            logger.error("Error finding node in doSet '{}'", domain);
            return;
        }
        // TODO: Should we check that the node is finished initialising
        ZWaveProductDatabase database = new ZWaveProductDatabase();
        if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) {
            logger.error("NODE {}: Error in doSet - no database found", nodeId);
            return;
        }
        if (splitDomain.length == 3) {
            if (splitDomain[2].equals("Name")) {
                node.setName(value);
            }
            if (splitDomain[2].equals("Location")) {
                node.setLocation(value);
            }
            if (splitDomain[2].equals("SwitchAll")) {
                ZWaveSwitchAllCommandClass switchAllCommandClass = (ZWaveSwitchAllCommandClass) node.getCommandClass(CommandClass.SWITCH_ALL);
                if (switchAllCommandClass == null) {
                    logger.error("NODE {}: Error getting switchAllCommandClass in doSet", nodeId);
                    return;
                }
                // Set the switch all mode
                int mode = Integer.parseInt(value);
                PendingCfg.Add(ZWaveSwitchAllCommandClass.CommandClass.SWITCH_ALL.getKey(), node.getNodeId(), 0, mode);
                SerialMessage msg = switchAllCommandClass.setValueMessage(mode);
                this.zController.sendData(msg);
                // And request a read-back
                this.zController.sendData(switchAllCommandClass.getValueMessage());
            }
            // Write the node to disk
            ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
            nodeSerializer.SerializeNode(node);
        } else if (splitDomain.length == 4) {
            if (splitDomain[2].equals("parameters")) {
                ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.CONFIGURATION);
                if (configurationCommandClass == null) {
                    logger.error("NODE {}: Error getting configurationCommandClass in doSet", nodeId);
                    return;
                }
                int paramIndex = Integer.parseInt(splitDomain[3].substring(13));
                List<ZWaveDbConfigurationParameter> configList = database.getProductConfigParameters();
                // Get the size
                int size = 1;
                for (ZWaveDbConfigurationParameter parameter : configList) {
                    if (parameter.Index == paramIndex) {
                        size = parameter.Size;
                        break;
                    }
                }
                logger.debug("Set parameter index '{}' to '{}'", paramIndex, value);
                PendingCfg.Add(ZWaveCommandClass.CommandClass.CONFIGURATION.getKey(), nodeId, paramIndex, Integer.valueOf(value));
                ConfigurationParameter configurationParameter = new ConfigurationParameter(paramIndex, Integer.valueOf(value), size);
                // Set the parameter
                this.zController.sendData(configurationCommandClass.setConfigMessage(configurationParameter));
                // And request a read-back
                this.zController.sendData(configurationCommandClass.getConfigMessage(paramIndex));
            }
            if (splitDomain[2].equals("wakeup")) {
                ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
                if (wakeupCommandClass == null) {
                    logger.error("NODE {}: Error getting wakeupCommandClass in doSet", nodeId);
                    return;
                }
                logger.debug("NODE {}: Set wakeup interval to '{}'", nodeId, value);
                // Add this as a pending transaction
                PendingCfg.Add(ZWaveCommandClass.CommandClass.WAKE_UP.getKey(), node.getNodeId(), Integer.parseInt(value));
                // Set the wake-up interval
                this.zController.sendData(wakeupCommandClass.setInterval(Integer.parseInt(value)));
                // And request a read-back
                this.zController.sendData(wakeupCommandClass.getIntervalMessage());
            }
            if (splitDomain[2].equals("controller")) {
                if (splitDomain[3].equals("Type")) {
                    ZWaveDeviceType type = ZWaveDeviceType.fromString(value);
                    logger.error("NODE {}: Setting controller type to {}", nodeId, type.toString());
                // ZW_EnableSUC and ZW_SetSUCNodeID
                }
            }
        } else if (splitDomain.length == 5) {
            if (splitDomain[2].equals("associations")) {
                ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.ASSOCIATION);
                if (associationCommandClass == null) {
                    logger.error("NODE {}: Error getting associationCommandClass in doSet", nodeId);
                    return;
                }
                int assocId = Integer.parseInt(splitDomain[3].substring(11));
                int assocArg = Integer.parseInt(splitDomain[4].substring(4));
                if (value.equalsIgnoreCase("true")) {
                    PendingCfg.Add(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), nodeId, assocId, assocArg, 1);
                    logger.debug("Add association index '{}' to '{}'", assocId, assocArg);
                    this.zController.sendData(associationCommandClass.setAssociationMessage(assocId, assocArg));
                } else {
                    PendingCfg.Add(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), nodeId, assocId, assocArg, 0);
                    logger.debug("Remove association index '{}' to '{}'", assocId, assocArg);
                    this.zController.sendData(associationCommandClass.removeAssociationMessage(assocId, assocArg));
                }
                // Request an update to the group
                this.zController.sendData(associationCommandClass.getAssociationMessage(assocId));
                // So, let's start a network heal - just for this node right now
                if (networkMonitor != null) {
                    networkMonitor.startNodeHeal(nodeId);
                }
            }
        }
    }
}
Also used : ZWaveDeviceType(org.openhab.binding.zwave.internal.protocol.ZWaveDeviceType) ConfigurationParameter(org.openhab.binding.zwave.internal.protocol.ConfigurationParameter) ZWaveSwitchAllCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveSwitchAllCommandClass) SerialMessage(org.openhab.binding.zwave.internal.protocol.SerialMessage) ZWaveWakeUpCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass) ZWaveAssociationCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveAssociationCommandClass) ZWaveNodeSerializer(org.openhab.binding.zwave.internal.protocol.initialization.ZWaveNodeSerializer) ZWaveNode(org.openhab.binding.zwave.internal.protocol.ZWaveNode) ZWaveConfigurationCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass) ArrayList(java.util.ArrayList) List(java.util.List)

Example 2 with SerialMessage

use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.

the class ZWaveDoorLockConverter method receiveCommand.

/**
     * {@inheritDoc}
     */
@Override
public void receiveCommand(Item item, Command command, ZWaveNode node, ZWaveDoorLockCommandClass commandClass, int endpointId, Map<String, String> arguments) {
    ZWaveCommandConverter<?, ?> converter = this.getCommandConverter(command.getClass());
    if (converter == null) {
        logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring command.", node.getNodeId(), item.getName(), endpointId);
        return;
    }
    SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage((Integer) converter.convertFromCommandToValue(item, command)), commandClass, endpointId);
    if (serialMessage == null) {
        logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId);
        return;
    }
    this.getController().sendData(serialMessage);
    if (command instanceof State) {
        this.getEventPublisher().postUpdate(item.getName(), (State) command);
    }
    // Queue a status message since we just sent a door lock command
    serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId);
    this.getController().sendData(serialMessage);
}
Also used : State(org.openhab.core.types.State) SerialMessage(org.openhab.binding.zwave.internal.protocol.SerialMessage)

Example 3 with SerialMessage

use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.

the class ZWaveIndicatorConverter method handleEvent.

/**
     * {@inheritDoc}
     *
     * Process Z-Wave Indicator Report events. Apply any pending changes (see receiveCommand) and if
     * indicator is changed in any way issue an INDICATOR_SET message to update the node's indicator value
     */
@Override
public void handleEvent(ZWaveCommandClassValueEvent event, Item item, Map<String, String> arguments) {
    ZWaveStateConverter<?, ?> converter = this.getStateConverter(item, event.getValue());
    if (converter == null) {
        logger.warn("NODE {}: No converter found for item = {}, ignoring event.", event.getNodeId(), item.getName());
        return;
    }
    if (!arguments.containsKey("bit")) {
        logger.error("NODE {}: You must specify an Indicator bit for item = {}, ignoring event.", event.getNodeId(), item.getName());
        return;
    }
    int bit = Integer.parseInt(arguments.get("bit"));
    ZWaveIndicatorCommandClassChangeEvent e = (ZWaveIndicatorCommandClassChangeEvent) event;
    // Get INDICATOR Command Class to check if node supports it and later to generate the INDICATOR_SET message
    // to the node to set the new indicator value
    ZWaveNode node = this.getController().getNode(event.getNodeId());
    ZWaveIndicatorCommandClass commandClass = (ZWaveIndicatorCommandClass) node.getCommandClass(CommandClass.INDICATOR);
    if (commandClass == null) {
        logger.warn("NODE {}: Indicator command Class not supported for Item = {}, ignoring event.", event.getNodeId(), item.getName());
        return;
    }
    // Assume no changes and get the actual indicator value just received from the node
    boolean madeChanges = false;
    int indicator = (Integer) e.getValue();
    logger.warn(String.format("NODE %d: Processing Indicator Event for Item %s indicator = 0x%02X, bit = %d.", event.getNodeId(), item.getName(), indicator, bit));
    // Check if the bound bit is ON (1) or OFF (0)
    int isOn = (((byte) indicator) >> bit) & 0x01;
    // Check for pending changes from previous receiveCommand() method calls
    if (pending.containsKey(item.getName())) {
        if (pending.get(item.getName()).containsKey(bit)) {
            logger.warn(String.format("NODE %d: There are pending changes to Item %s bit = %d", event.getNodeId(), item.getName(), bit));
            // check if there are any pending set to ON for the bound bit, and if the current bit value is OFF
            if (pending.get(item.getName()).get(bit) == PENDING_ON && isOn == OFF) {
                // Set bit to ON in current indicator value
                byte buttonMask = (byte) (0x01 << bit);
                indicator = (byte) (indicator | buttonMask);
                HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
                h.put(bit, NO_PENDING_CHANGES);
                pending.put(item.getName(), h);
                madeChanges = true;
                logger.warn(String.format("NODE %d: Item %s indicator = 0x%02X, Set bit = %d to ON - DONE", event.getNodeId(), item.getName(), indicator, bit));
            }
            if (pending.get(item.getName()).get(bit) == PENDING_OFF && isOn == ON) {
                // Set bit to OFF in current indicator value
                byte buttonMask = (byte) ~(0x01 << bit);
                indicator = (byte) (indicator & buttonMask);
                HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
                h.put(bit, NO_PENDING_CHANGES);
                pending.put(item.getName(), h);
                madeChanges = true;
                logger.warn(String.format("NODE %d: Item %s indicator = 0x%02X, Set bit = %d to OFF - DONE", event.getNodeId(), item.getName(), indicator, bit));
            }
            // Check if changes were made send an INDICATOR_SET message to update the node's indicator value
            if (madeChanges) {
                // recalculate because we made changes to Indicator
                isOn = (((byte) indicator) >> bit) & 0x01;
                // Create an Indicator SET message and send it to the node
                SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage(indicator), commandClass, 0);
                if (serialMessage == null) {
                    logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel());
                    return;
                }
                this.getController().sendData(serialMessage);
                logger.warn(String.format("NODE %d: Item %s indicator = 0x%02X, Send pending operations to node", event.getNodeId(), item.getName(), indicator, bit));
            }
        } else {
            logger.warn(String.format("NODE %d: No pending indicator changes to Item %s bit = %d", event.getNodeId(), item.getName(), bit));
        }
    } else {
        logger.warn(String.format("NODE %d: No pending Indicator changes to Item %s bit = %d", event.getNodeId(), item.getName(), bit));
    }
    if (isOn == ON) {
        this.getEventPublisher().postUpdate(item.getName(), converter.convertFromValueToState(0xFF));
    } else {
        this.getEventPublisher().postUpdate(item.getName(), converter.convertFromValueToState(0x00));
    }
}
Also used : ZWaveIndicatorCommandClassChangeEvent(org.openhab.binding.zwave.internal.protocol.event.ZWaveIndicatorCommandClassChangeEvent) ZWaveNode(org.openhab.binding.zwave.internal.protocol.ZWaveNode) HashMap(java.util.HashMap) ZWaveIndicatorCommandClass(org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveIndicatorCommandClass) SerialMessage(org.openhab.binding.zwave.internal.protocol.SerialMessage)

Example 4 with SerialMessage

use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.

the class ZWaveIndicatorConverter method receiveCommand.

/**
     * {@inheritDoc}
     *
     * The node's indicator status can change at any time, and without the knowledge of the Z-Wave binding so
     * before any changes are made to the indicator we need to get its actual value from the device.
     * Hence the receiveCommand method adds the desired command to a "pending" list, and issues an INDICATOR_GET
     * it does not change the actual device Indicator value.
     *
     * When the node responds with the INDICATOR_REPORT pending commands are applied to the indicator value
     * and the result is then sent to the node. This is performed in the handleEvent() method.
     *
     * Pending changes are stored in a hash of hashes with the following keys "ItemName" and "bit" value is 1
     * for turn bit ON, -1 to turn the bound bit OFF, 0 no change.
     *
     * HashMap<ItemName, HashMap<bit, pendingOperationCode>>
     */
@Override
public void receiveCommand(Item item, Command command, ZWaveNode node, ZWaveIndicatorCommandClass commandClass, int endpointId, Map<String, String> arguments) {
    ZWaveCommandConverter<?, ?> converter = this.getCommandConverter(command.getClass());
    if (converter == null) {
        logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring command.", node.getNodeId(), item.getName(), endpointId);
        return;
    }
    if (!arguments.containsKey("bit")) {
        logger.error("NODE {}: You must specify an Indicator bit for item = {}, endpoint = {}, ignoring command.", node.getNodeId(), item.getName(), endpointId);
        return;
    }
    int bit = Integer.parseInt(arguments.get("bit"));
    if (!(command instanceof OnOffType)) {
        return;
    }
    if (command == OnOffType.ON) {
        HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
        h.put(bit, PENDING_ON);
        pending.put(item.getName(), h);
        logger.warn(String.format("NODE %d: Item %s Set bit = %d to ON - PENDING", node.getNodeId(), item.getName(), bit));
    } else {
        logger.warn(String.format("NODE %d: Item %s Set bit = %d to OFF - PENDING", node.getNodeId(), item.getName(), bit));
        HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
        h.put(bit, PENDING_OFF);
        pending.put(item.getName(), h);
    }
    // Issue a INDICATOR_GET message to the node to get the updated indicator value
    SerialMessage serialMessage = node.encapsulate(commandClass.getValueMessage(), commandClass, endpointId);
    if (serialMessage == null) {
        logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel(), endpointId);
        return;
    }
    this.getController().sendData(serialMessage);
    logger.warn(String.format("NODE %d: Item %s bit = %d Get current Indicator State", node.getNodeId(), item.getName(), bit));
    if (command instanceof State) {
        this.getEventPublisher().postUpdate(item.getName(), (State) command);
    }
}
Also used : OnOffType(org.openhab.core.library.types.OnOffType) HashMap(java.util.HashMap) State(org.openhab.core.types.State) SerialMessage(org.openhab.binding.zwave.internal.protocol.SerialMessage)

Example 5 with SerialMessage

use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.

the class ZWaveMultiLevelSwitchConverter method receiveCommand.

/**
     * {@inheritDoc}
     */
@Override
public void receiveCommand(Item item, Command command, ZWaveNode node, ZWaveMultiLevelSwitchCommandClass commandClass, int endpointId, Map<String, String> arguments) {
    SerialMessage serialMessage = null;
    String restoreLastValue = null;
    if (command instanceof StopMoveType && (StopMoveType) command == StopMoveType.STOP) {
        // special handling for the STOP command
        serialMessage = commandClass.stopLevelChangeMessage();
    } else {
        ZWaveCommandConverter<?, ?> converter = null;
        if (command instanceof OnOffType) {
            restoreLastValue = arguments.get("restore_last_value");
            if ("true".equalsIgnoreCase(restoreLastValue)) {
                converter = this.restoreValueOnOffConverter;
            } else {
                converter = this.normalOnOffConverter;
            }
        } else {
            converter = this.getCommandConverter(command.getClass());
        }
        if (converter == null) {
            logger.warn("NODE {}: No converter found for item = {}, endpoint = {}, ignoring command.", node.getNodeId(), item.getName(), endpointId);
            return;
        }
        // Allow inversion of roller shutter UP/DOWN
        if (converter instanceof MultiLevelUpDownCommandConverter) {
            logger.debug("Multilevel Switch MultiLevelUpDownCommandConverter");
            if ("true".equalsIgnoreCase(arguments.get("invert_state"))) {
                logger.trace("Multilevel Switch MultiLevelUpDownCommandConverter - invert");
                if (command == UpDownType.UP) {
                    command = UpDownType.DOWN;
                } else {
                    command = UpDownType.UP;
                }
                logger.trace("Multilevel Switch MultiLevelUpDownCommandConverter - inverted: {}", command);
            }
        }
        // Allow inversion of roller shutter PERCENT value
        if (converter instanceof MultiLevelPercentCommandConverter) {
            logger.debug("Multilevel Switch MultiLevelPercentCommandConverter");
            if ("true".equalsIgnoreCase(arguments.get("invert_percent"))) {
                logger.trace("Multilevel Switch MultiLevelPercentCommandConverter - invert");
                command = new PercentType(100 - ((DecimalType) command).intValue());
                logger.trace("Multilevel Switch MultiLevelPercentCommandConverter - inverted: {}", command);
            }
        }
        Integer value = (Integer) converter.convertFromCommandToValue(item, command);
        logger.trace("NODE {}: Converted command '{}' to value {} for item = {}, endpoint = {}.", node.getNodeId(), command.toString(), value, item.getName(), endpointId);
        serialMessage = commandClass.setValueMessage(value);
    }
    // encapsulate the message in case this is a multi-instance node
    serialMessage = node.encapsulate(serialMessage, commandClass, endpointId);
    if (serialMessage == null) {
        logger.warn("Generating message failed for command class = {}, node = {}, endpoint = {}", commandClass.getCommandClass().getLabel(), node.getNodeId(), endpointId);
        return;
    }
    this.getController().sendData(serialMessage);
    // update the bus in case of normal dimming. schedule refresh in case of restore to last value dimming.
    if (!"true".equalsIgnoreCase(restoreLastValue) && command instanceof OnOffType && (OnOffType) command == OnOffType.ON) {
        executeRefresh(node, commandClass, endpointId, arguments);
    } else if (command instanceof State) {
        this.getEventPublisher().postUpdate(item.getName(), (State) command);
    }
}
Also used : MultiLevelUpDownCommandConverter(org.openhab.binding.zwave.internal.converter.command.MultiLevelUpDownCommandConverter) OnOffType(org.openhab.core.library.types.OnOffType) State(org.openhab.core.types.State) SerialMessage(org.openhab.binding.zwave.internal.protocol.SerialMessage) PercentType(org.openhab.core.library.types.PercentType) StopMoveType(org.openhab.core.library.types.StopMoveType) MultiLevelPercentCommandConverter(org.openhab.binding.zwave.internal.converter.command.MultiLevelPercentCommandConverter)

Aggregations

SerialMessage (org.openhab.binding.zwave.internal.protocol.SerialMessage)125 State (org.openhab.core.types.State)12 ZWaveEndpoint (org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint)8 ByteArrayOutputStream (java.io.ByteArrayOutputStream)7 HashMap (java.util.HashMap)5 ZWaveNode (org.openhab.binding.zwave.internal.protocol.ZWaveNode)5 ZWaveWakeUpCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass)4 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 ConfigurationParameter (org.openhab.binding.zwave.internal.protocol.ConfigurationParameter)3 SecurityEncapsulatedSerialMessage (org.openhab.binding.zwave.internal.protocol.SecurityEncapsulatedSerialMessage)3 ZWaveCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveCommandClass)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ZWaveDbConfigurationParameter (org.openhab.binding.zwave.internal.config.ZWaveDbConfigurationParameter)2 ZWaveProductDatabase (org.openhab.binding.zwave.internal.config.ZWaveProductDatabase)2 MultiLevelPercentCommandConverter (org.openhab.binding.zwave.internal.converter.command.MultiLevelPercentCommandConverter)2 ZWaveAssociationCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveAssociationCommandClass)2 ZWaveConfigurationCommandClass (org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveConfigurationCommandClass)2 ZWaveNetworkEvent (org.openhab.binding.zwave.internal.protocol.event.ZWaveNetworkEvent)2