/**
* Copyright (c) 2010-2015, openHAB.org and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.zwave.internal.protocol.commandclass;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.openhab.binding.zwave.internal.protocol.SerialMessage;
import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageClass;
import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessagePriority;
import org.openhab.binding.zwave.internal.protocol.SerialMessage.SerialMessageType;
import org.openhab.binding.zwave.internal.protocol.ZWaveController;
import org.openhab.binding.zwave.internal.protocol.ZWaveEndpoint;
import org.openhab.binding.zwave.internal.protocol.ZWaveNode;
import org.openhab.binding.zwave.internal.protocol.event.ZWaveCommandClassValueEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* Handles the Lock command class.
*
* @author Dave Badia
* @since TODO
*/
@XStreamAlias("lockCommandClass")
public class ZWaveLockCommandClass extends ZWaveCommandClass implements ZWaveGetCommands, ZWaveSetCommands {
private static final Logger logger = LoggerFactory.getLogger(ZWaveLockCommandClass.class);
private static final int LOCK_SET = 0x01;
/**
* Request the state of the lock, ie {@link #LOCK_REPORT}
*/
private static final int LOCK_GET = 0x02;
/**
* Details about the state of the lock (locked, unlocked)
*/
private static final int LOCK_REPORT = 0x03;
/**
* Creates a new instance of the ZWaveAlarmCommandClass class.
*
* @param node the node this command class belongs to
* @param controller the controller to use
* @param endpoint the endpoint this Command class belongs to
*/
public ZWaveLockCommandClass(ZWaveNode node, ZWaveController controller, ZWaveEndpoint endpoint) {
super(node, controller, endpoint);
}
/**
* {@inheritDoc}
*/
@Override
public CommandClass getCommandClass() {
return CommandClass.LOCK;
}
/**
* {@inheritDoc}
*/
@Override
public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) {
logger.trace("Handle Message Lock Request");
logger.debug(String.format("NODE %d: Received Lock Request", this.getNode().getNodeId()));
int command = serialMessage.getMessagePayloadByte(offset);
switch (command) {
case LOCK_GET:
case LOCK_SET:
logger.warn(String.format("Command 0x%02X not implemented.", command));
return;
case LOCK_REPORT:
logger.trace("Process Lock Report");
int lockState = serialMessage.getMessagePayloadByte(offset + 1);
logger.debug(String.format("NODE %d: Lock report - lockState = 0x%02x,", this.getNode().getNodeId(),
lockState));
ZWaveLockValueEvent zEvent = new ZWaveLockValueEvent(this.getNode().getNodeId(), endpoint, lockState);
this.getController().notifyEventListeners(zEvent);
break;
default:
logger.warn(String.format("Unsupported Command 0x%02X for command class %s (0x%02X).", command,
this.getCommandClass().getLabel(), this.getCommandClass().getKey()));
break;
}
}
/**
* Gets a SerialMessage with the LOCK_GET command
*
* @return the serial message
*/
@Override
public SerialMessage getValueMessage() {
logger.debug("NODE {}: Creating new message for application command LOCK_GET", this.getNode().getNodeId());
SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData,
SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get);
byte[] newPayload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(),
(byte) LOCK_GET, };
result.setMessagePayload(newPayload);
return result;
}
@Override
public SerialMessage setValueMessage(int value) {
logger.debug("NODE {}: Creating new message for application command LOCK_SET", this.getNode().getNodeId());
SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData,
SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set);
byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), (byte) LOCK_SET,
(byte) value };
result.setMessagePayload(newPayload);
return result;
}
/**
* Z-Wave LockState enumeration. The lock state type indicates
* the state of the lock that is reported.
*/
@XStreamAlias("lockState")
enum LockStateType {
UNLOCKED(0x00, "Unlocked"),
LOCKED(0xFF, "Locked"),;
/**
* A mapping between the integer code and its corresponding door
* lock state type to facilitate lookup by code.
*/
private static Map<Integer, LockStateType> codeToLockStateTypeMapping;
private int key;
private String label;
private static void initMapping() {
codeToLockStateTypeMapping = new ConcurrentHashMap<Integer, LockStateType>();
for (LockStateType d : values()) {
codeToLockStateTypeMapping.put(d.key, d);
}
}
/**
* Lookup function based on the fan mode type code.
* Returns null if the code does not exist.
*
* @param i the code to lookup
* @return enumeration value of the fan mode type.
*/
public static LockStateType getLockStateType(int i) {
if (codeToLockStateTypeMapping == null) {
initMapping();
}
return codeToLockStateTypeMapping.get(i);
}
LockStateType(int key, String label) {
this.key = key;
this.label = label;
}
/**
* @return the key
*/
public int getKey() {
return key;
}
/**
* @return the label
*/
public String getLabel() {
return label;
}
}
/**
* Z-Wave Door Lock Event class. Indicates that a door lcok value
* changed.
*/
public class ZWaveLockValueEvent extends ZWaveCommandClassValueEvent {
/**
* Constructor. Creates a instance of the ZWaveAlarmValueEvent class.
*
* @param nodeId the nodeId of the event
* @param endpoint the endpoint of the event.
* @param value the value for the event.
*/
private ZWaveLockValueEvent(int nodeId, int endpoint, Object value) {
super(nodeId, endpoint, CommandClass.LOCK, value);
}
}
}