/**
* Copyright (c) 2014-2016 by the respective copyright holders.
*
* 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.io.ByteArrayOutputStream;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
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;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* Handles the clock command class.
*
* @author Chris Jackson
* @author Jorg de Jong
*
*/
@XStreamAlias("clockCommandClass")
public class ZWaveClockCommandClass extends ZWaveCommandClass
implements ZWaveGetCommands, ZWaveCommandClassDynamicState {
@XStreamOmitField
private static final Logger logger = LoggerFactory.getLogger(ZWaveClockCommandClass.class);
private static final int CLOCK_SET = 4;
private static final int CLOCK_GET = 5;
private static final int CLOCK_REPORT = 6;
/**
* Creates a new instance of the ZWaveClockCommandClass 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 ZWaveClockCommandClass(ZWaveNode node, ZWaveController controller, ZWaveEndpoint endpoint) {
super(node, controller, endpoint);
}
/**
* {@inheritDoc}
*/
@Override
public CommandClass getCommandClass() {
return CommandClass.CLOCK;
}
/**
* Gets a SerialMessage with the CLOCK_GET command
*
* @return the serial message.
*/
@Override
public SerialMessage getValueMessage() {
logger.debug("NODE {}: Creating new message for command CLOCK_GET", getNode().getNodeId());
SerialMessage result = new SerialMessage(getNode().getNodeId(), SerialMessageClass.SendData,
SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get);
ByteArrayOutputStream outputData = new ByteArrayOutputStream();
outputData.write(getNode().getNodeId());
outputData.write(2);
outputData.write(getCommandClass().getKey());
outputData.write(CLOCK_GET);
result.setMessagePayload(outputData.toByteArray());
return result;
}
/**
* Gets a SerialMessage with the CLOCK_SET command
*
* @return the serial message.
*/
public SerialMessage getSetMessage(Calendar cal) {
logger.debug("NODE {}: Creating new message for command CLOCK_SET", getNode().getNodeId());
int day = cal.get(Calendar.DAY_OF_WEEK) == 1 ? 7 : cal.get(Calendar.DAY_OF_WEEK) - 1;
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
SerialMessage result = new SerialMessage(getNode().getNodeId(), SerialMessageClass.SendData,
SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Immediate);
ByteArrayOutputStream outputData = new ByteArrayOutputStream();
outputData.write(getNode().getNodeId());
outputData.write(4);
outputData.write(getCommandClass().getKey());
outputData.write(CLOCK_SET);
outputData.write((day << 5) | hour);
outputData.write(minute);
result.setMessagePayload(outputData.toByteArray());
return result;
}
/**
* {@inheritDoc}
*
* @throws ZWaveSerialMessageException
*/
@Override
public void handleApplicationCommandRequest(SerialMessage serialMessage, int offset, int endpoint) {
logger.debug("NODE {}: Received CLOCK command V{}", getNode().getNodeId(), getVersion());
int command = serialMessage.getMessagePayloadByte(offset);
switch (command) {
case CLOCK_REPORT:
int day = serialMessage.getMessagePayloadByte(offset + 1) >> 5;
int hour = serialMessage.getMessagePayloadByte(offset + 1) & 0x1f;
int minute = serialMessage.getMessagePayloadByte(offset + 2);
String days[] = new DateFormatSymbols().getWeekdays();
int javaDay = day == 7 ? 1 : day + 1;
logger.debug(String.format("NODE %d: Received clock report: %s %02d:%02d", getNode().getNodeId(),
days[javaDay], hour, minute));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_WEEK, javaDay);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
Date nodeTime = cal.getTime();
ZWaveCommandClassValueEvent zEvent = new ZWaveCommandClassValueEvent(getNode().getNodeId(), endpoint,
getCommandClass(), nodeTime);
getController().notifyEventListeners(zEvent);
break;
default:
logger.warn(String.format("NODE %d: Unsupported Command %d for command class %s (0x%02X).",
getNode().getNodeId(), command, getCommandClass().getLabel(), getCommandClass().getKey()));
break;
}
}
@Override
public Collection<SerialMessage> getDynamicValues(boolean refresh) {
ArrayList<SerialMessage> result = new ArrayList<SerialMessage>();
if (refresh == true && getEndpoint() == null) {
result.add(getValueMessage());
}
return result;
}
}