Some Zwave progress
This commit is contained in:
parent
04dec80d9a
commit
ca3de56e60
10 changed files with 397 additions and 139 deletions
34
Hal.iml
34
Hal.iml
|
|
@ -15,6 +15,24 @@
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="wzwave" exported="" />
|
||||||
|
<orderEntry type="module" module-name="Zutil" exported="" />
|
||||||
|
<orderEntry type="module-library" exported="">
|
||||||
|
<library name="ZWave lib">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="file://$MODULE_DIR$/plugins/zwave/lib" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<NATIVE>
|
||||||
|
<root url="file://$MODULE_DIR$/plugins/zwave/lib" />
|
||||||
|
</NATIVE>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.ideaLibSources/netty-all-4.0.46.Final-sources.jar!/" />
|
||||||
|
<root url="jar://$USER_HOME$/.ideaLibSources/wzwave-0.0.3-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
<jarDirectory url="file://$MODULE_DIR$/plugins/zwave/lib" recursive="false" />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
<orderEntry type="module-library" exported="">
|
<orderEntry type="module-library" exported="">
|
||||||
<library name="lib">
|
<library name="lib">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
|
|
@ -25,15 +43,12 @@
|
||||||
<root url="file://$MODULE_DIR$/lib" />
|
<root url="file://$MODULE_DIR$/lib" />
|
||||||
</NATIVE>
|
</NATIVE>
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/jSerialComm-1.3.10-sources.jar!/" />
|
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/zwave4j-0.3-sources.jar!/" />
|
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/wzwave-0.0.3-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.ideaLibSources/wzwave-0.0.3-sources.jar!/" />
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/netty-all-4.0.46.Final-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.ideaLibSources/netty-all-4.0.46.Final-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
<jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
|
<jarDirectory url="file://$MODULE_DIR$/lib" recursive="false" />
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</orderEntry>
|
||||||
<orderEntry type="module" module-name="Zutil" exported="" />
|
|
||||||
<orderEntry type="module-library" scope="TEST">
|
<orderEntry type="module-library" scope="TEST">
|
||||||
<library name="JUnit4">
|
<library name="JUnit4">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
|
|
@ -44,18 +59,5 @@
|
||||||
<SOURCES />
|
<SOURCES />
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</orderEntry>
|
||||||
<orderEntry type="module-library">
|
|
||||||
<library name="ZWave lib">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="file://$MODULE_DIR$/plugins/zwave/lib" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/netty-all-4.0.46.Final-sources.jar!/" />
|
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/wzwave-0.0.3-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
<jarDirectory url="file://$MODULE_DIR$/plugins/zwave/lib" recursive="false" />
|
|
||||||
</library>
|
|
||||||
</orderEntry>
|
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
BIN
external/Z-Stick_Gen5_Drivers.zip
vendored
Normal file
BIN
external/Z-Stick_Gen5_Drivers.zip
vendored
Normal file
Binary file not shown.
BIN
plugins/zwave/lib/netty-all-4.0.21.Final.jar
Normal file
BIN
plugins/zwave/lib/netty-all-4.0.21.Final.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -50,11 +50,11 @@ abstract class AbstractNettyChannelInitializer<T extends Channel> extends Channe
|
||||||
|
|
||||||
// Setup general channel handlers and coders
|
// Setup general channel handlers and coders
|
||||||
channel.pipeline().addLast("decoder", new ZWaveFrameDecoder());
|
channel.pipeline().addLast("decoder", new ZWaveFrameDecoder());
|
||||||
channel.pipeline().addLast("ack", new AcknowledgementInboundHandler());
|
channel.pipeline().addLast("ack", new ACKInboundHandler());
|
||||||
channel.pipeline().addLast("transaction", new ZWaveDataFrameTransactionInboundHandler());
|
|
||||||
channel.pipeline().addLast("handler", inboundHandler);
|
|
||||||
channel.pipeline().addLast("encoder", new ZWaveFrameEncoder());
|
channel.pipeline().addLast("encoder", new ZWaveFrameEncoder());
|
||||||
channel.pipeline().addLast("writeQueue", new ZWaveQueuedOutboundHandler());
|
channel.pipeline().addLast("writeQueue", new FrameQueueHandler());
|
||||||
|
channel.pipeline().addLast("transaction", new TransactionInboundHandler());
|
||||||
|
channel.pipeline().addLast("handler", inboundHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,111 @@
|
||||||
/*******************************************************************************
|
/*
|
||||||
|
*******************************************************************************
|
||||||
* Copyright (c) 2013 Whizzo Software, LLC.
|
* Copyright (c) 2013 Whizzo Software, LLC.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*******************************************************************************/
|
*******************************************************************************
|
||||||
|
*/
|
||||||
package com.whizzosoftware.wzwave.controller.netty;
|
package com.whizzosoftware.wzwave.controller.netty;
|
||||||
|
|
||||||
import com.whizzosoftware.wzwave.channel.*;
|
import com.whizzosoftware.wzwave.channel.*;
|
||||||
import com.whizzosoftware.wzwave.codec.ZWaveFrameDecoder;
|
import com.whizzosoftware.wzwave.channel.event.*;
|
||||||
import com.whizzosoftware.wzwave.codec.ZWaveFrameEncoder;
|
import com.whizzosoftware.wzwave.commandclass.WakeUpCommandClass;
|
||||||
import com.whizzosoftware.wzwave.controller.ZWaveController;
|
import com.whizzosoftware.wzwave.controller.ZWaveController;
|
||||||
import com.whizzosoftware.wzwave.controller.ZWaveControllerContext;
|
import com.whizzosoftware.wzwave.controller.ZWaveControllerContext;
|
||||||
import com.whizzosoftware.wzwave.controller.ZWaveControllerListener;
|
import com.whizzosoftware.wzwave.controller.ZWaveControllerListener;
|
||||||
import com.whizzosoftware.wzwave.frame.*;
|
import com.whizzosoftware.wzwave.frame.*;
|
||||||
import com.whizzosoftware.wzwave.node.*;
|
import com.whizzosoftware.wzwave.node.*;
|
||||||
|
import com.whizzosoftware.wzwave.persist.PersistentStore;
|
||||||
|
import com.whizzosoftware.wzwave.persist.mapdb.MapDbPersistentStore;
|
||||||
|
import com.whizzosoftware.wzwave.util.ByteUtil;
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.oio.OioEventLoopGroup;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Netty implementation of a ZWaveController.
|
* A Netty implementation of a ZWaveController.
|
||||||
*
|
*
|
||||||
|
* The pipeline looks like this:
|
||||||
|
*
|
||||||
|
* I/O Request via Channel or
|
||||||
|
* ChannelHandlerContext
|
||||||
|
* |
|
||||||
|
* +----------------------------------------------------------------+-------------------+
|
||||||
|
* | ChannelPipeline | |
|
||||||
|
* | | |
|
||||||
|
* | +--------------------------------+ | |
|
||||||
|
* | | ZWaveChannelInboundHandler | | |
|
||||||
|
* | +---------------+----------------+ | |
|
||||||
|
* | /|\ | |
|
||||||
|
* | | | |
|
||||||
|
* | +---------------+----------------+ | |
|
||||||
|
* | | TransactionInboundHandler | | |
|
||||||
|
* | +---------------+----------------+ | |
|
||||||
|
* | /|\ | |
|
||||||
|
* | | \|/ |
|
||||||
|
* | +---------------+-------------------------------------------+--------------+ |
|
||||||
|
* | | FrameQueueHandler | |
|
||||||
|
* | +---------------+-------------------------------------------+--------------+ |
|
||||||
|
* | /|\ | |
|
||||||
|
* | | | |
|
||||||
|
* | +---------------+----------------+ | |
|
||||||
|
* | | ACKInboundHandler | | |
|
||||||
|
* | +---------------+----------------+ | |
|
||||||
|
* | /|\ | |
|
||||||
|
* | | | |
|
||||||
|
* | +---------------+----------------+ +-------------+--------------+ |
|
||||||
|
* | | ZWaveFrameDecoder | | ZWaveFrameEncoder | |
|
||||||
|
* | +---------------+----------------+ +-------------+--------------+ |
|
||||||
|
* | /|\ | |
|
||||||
|
* +--------------------+-------------------------------------------+-------------------+
|
||||||
|
* | | \|/ |
|
||||||
|
* +--------------------+-------------------------------------------+-------------------+
|
||||||
|
* | | | |
|
||||||
|
* | [ Socket.read() ] [ Socket.write() ] |
|
||||||
|
* +------------------------------------------------------------------------------------+
|
||||||
|
*
|
||||||
* @author Dan Noguerol
|
* @author Dan Noguerol
|
||||||
*/
|
*/
|
||||||
public class NettyZWaveController implements ZWaveController, ZWaveControllerContext, ZWaveControllerListener, ZWaveChannelListener, NodeListener {
|
public class NettyZWaveController implements ZWaveController, ZWaveControllerContext, ZWaveControllerListener, ZWaveChannelListener, NodeListener {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(NettyZWaveController.class);
|
private static final Logger logger = LoggerFactory.getLogger(NettyZWaveController.class);
|
||||||
|
|
||||||
|
private String serialPort;
|
||||||
|
private PersistentStore store;
|
||||||
private AbstractNettyChannelInitializer serial;
|
private AbstractNettyChannelInitializer serial;
|
||||||
private String libraryVersion;
|
private String libraryVersion;
|
||||||
private int homeId;
|
private Integer homeId;
|
||||||
private byte nodeId;
|
private Byte nodeId;
|
||||||
private ZWaveControllerListener listener;
|
private ZWaveControllerListener listener;
|
||||||
private final List<ZWaveNode> nodes = new ArrayList<ZWaveNode>();
|
private final List<ZWaveNode> nodes = new ArrayList<>();
|
||||||
private final Map<Byte,ZWaveNode> nodeMap = new HashMap<Byte,ZWaveNode>();
|
private final Map<Byte,ZWaveNode> nodeMap = new HashMap<>();
|
||||||
|
|
||||||
public NettyZWaveController(String serialPort) {
|
/**
|
||||||
// Choose a available library
|
* Constructor.
|
||||||
try{
|
*
|
||||||
Class.forName("gnu.io.SerialPort"); // check if RxTx is available
|
* @param serialPort the serial port the Z-Wave controller is accessible from
|
||||||
logger.info("RxTx is available, using it as Serial port Com port library");
|
* @param dataDirectory a directory in which to store persistent data
|
||||||
serial = new NettyRxtxChannelInitializer(serialPort, this);
|
*/
|
||||||
} catch (ClassNotFoundException e) {
|
public NettyZWaveController(String serialPort, File dataDirectory) {
|
||||||
try {
|
this(serialPort, new MapDbPersistentStore(dataDirectory));
|
||||||
Class.forName("com.fazecast.jSerialComm.SerialPort"); // check if jSerialComm is available
|
}
|
||||||
logger.info("jSerialComm is available, using it as Serial port library");
|
|
||||||
serial = new NettyJSCChannelInitializer(serialPort, this);
|
/**
|
||||||
} catch (ClassNotFoundException e1) {
|
* Constructor.
|
||||||
throw new RuntimeException("Unable to find Rxtx or jSerialComm lib in classpath", e);
|
*
|
||||||
}
|
* @param serialPort the serial port for Z-Wave controller is accessible from
|
||||||
}
|
* @param store the persistent store to use for storing/retrieving node information
|
||||||
|
*/
|
||||||
|
public NettyZWaveController(String serialPort, PersistentStore store) {
|
||||||
|
this.serialPort = serialPort;
|
||||||
|
this.store = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -65,18 +118,37 @@ public class NettyZWaveController implements ZWaveController, ZWaveControllerCon
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
serial.getBootstrap().connect(serial.getSocketAddress()).addListener(new ChannelFutureListener() {
|
if (serial == null) {
|
||||||
@Override
|
// Choose a available library
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
try{
|
||||||
if (future.isSuccess()) {
|
Class.forName("gnu.io.SerialPort"); // check if RxTx is available
|
||||||
serial.getChannel().write(new Version());
|
logger.info("RxTx is available, using it as Serial port library");
|
||||||
serial.getChannel().write(new MemoryGetId());
|
serial = new NettyRxtxChannelInitializer(serialPort, this);
|
||||||
serial.getChannel().write(new InitData());
|
} catch (ClassNotFoundException e) {
|
||||||
} else {
|
try {
|
||||||
listener.onZWaveConnectionFailure(future.cause());
|
Class.forName("com.fazecast.jSerialComm.SerialPort"); // check if jSerialComm is available
|
||||||
|
logger.info("jSerialComm is available, using it as Serial port library");
|
||||||
|
serial = new NettyJSCChannelInitializer(serialPort, this);
|
||||||
|
} catch (ClassNotFoundException e1) {
|
||||||
|
throw new RuntimeException("Unable to find Rxtx or jSerialComm lib in classpath", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// set up Netty bootstrap
|
||||||
|
Bootstrap bootstrap = serial.getBootstrap();
|
||||||
|
bootstrap.connect(serial.getSocketAddress()).addListener(new ChannelFutureListener() {
|
||||||
|
@Override
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
|
if (future.isSuccess()) {
|
||||||
|
sendDataFrame(new Version());
|
||||||
|
sendDataFrame(new MemoryGetId());
|
||||||
|
sendDataFrame(new InitData());
|
||||||
|
} else {
|
||||||
|
onZWaveConnectionFailure(future.cause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -105,8 +177,21 @@ public class NettyZWaveController implements ZWaveController, ZWaveControllerCon
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendDataFrame(DataFrame dataFrame) {
|
public ZWaveNode getNode(byte nodeId) {
|
||||||
serial.getChannel().write(dataFrame);
|
return nodeMap.get(nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendDataFrame(DataFrame frame) {
|
||||||
|
serial.getChannel().write(new OutboundDataFrame(frame, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendDataFrame(DataFrame frame, boolean isListeningNode) {
|
||||||
|
serial.getChannel().write(new OutboundDataFrame(frame, isListeningNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEvent(Object e) {
|
||||||
|
serial.getChannel().write(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -131,6 +216,65 @@ public class NettyZWaveController implements ZWaveController, ZWaveControllerCon
|
||||||
public void onZWaveConnectionFailure(Throwable t) {
|
public void onZWaveConnectionFailure(Throwable t) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onZWaveConnectionFailure(t);
|
listener.onZWaveConnectionFailure(t);
|
||||||
|
} else {
|
||||||
|
logger.error("Connection failure and no listener was set", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveControllerInfo(String libraryVersion, Integer homeId, Byte nodeId) {
|
||||||
|
if (listener != null && libraryVersion != null && homeId != null && nodeId != null) {
|
||||||
|
listener.onZWaveControllerInfo(libraryVersion, homeId, nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveInclusionStarted() {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveInclusionStarted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveInclusion(NodeInfo nodeInfo, boolean success) {
|
||||||
|
try {
|
||||||
|
logger.trace("Inclusion of new node {}", ByteUtil.createString(nodeInfo.getNodeId()));
|
||||||
|
ZWaveNode node = ZWaveNodeFactory.createNode(nodeInfo, !nodeInfo.hasCommandClass(WakeUpCommandClass.ID), this);
|
||||||
|
logger.trace("Created new node [{}]: {}", node.getNodeId(), node);
|
||||||
|
addNode(node);
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveInclusion(nodeInfo, success);
|
||||||
|
}
|
||||||
|
} catch (NodeCreationException e) {
|
||||||
|
logger.error("Unable to create node", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveInclusionStopped() {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveInclusionStopped();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveExclusionStarted() {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveExclusionStarted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveExclusion(NodeInfo nodeInfo, boolean success) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveExclusion(nodeInfo, success);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveExclusionStopped() {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveExclusionStopped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,48 +285,58 @@ public class NettyZWaveController implements ZWaveController, ZWaveControllerCon
|
||||||
@Override
|
@Override
|
||||||
public void onLibraryInfo(String libraryVersion) {
|
public void onLibraryInfo(String libraryVersion) {
|
||||||
this.libraryVersion = libraryVersion;
|
this.libraryVersion = libraryVersion;
|
||||||
|
onZWaveControllerInfo(libraryVersion, homeId, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onControllerInfo(int homeId, byte nodeId) {
|
public void onControllerInfo(int homeId, byte nodeId) {
|
||||||
this.homeId = homeId;
|
this.homeId = homeId;
|
||||||
this.nodeId = nodeId;
|
this.nodeId = nodeId;
|
||||||
|
onZWaveControllerInfo(libraryVersion, homeId, nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNodeProtocolInfo(byte nodeId, NodeProtocolInfo nodeProtocolInfo) {
|
public void onNodeProtocolInfo(byte nodeId, NodeProtocolInfo npi) {
|
||||||
try {
|
try {
|
||||||
logger.trace("Received protocol info for node " + nodeId);
|
logger.trace("Received protocol info for node {}", nodeId);
|
||||||
ZWaveNode node = ZWaveNodeFactory.createNode(this, nodeId, nodeProtocolInfo, this);
|
ZWaveNode node = store.getNode(nodeId, this);
|
||||||
logger.trace("Created node [" + node.getNodeId() + "]: " + node);
|
if (node == null || !node.matchesNodeProtocolInfo(npi)) {
|
||||||
nodes.add(node);
|
node = ZWaveNodeFactory.createNode(
|
||||||
nodeMap.put(node.getNodeId(), node);
|
new NodeInfo(nodeId, npi.getBasicDeviceClass(), npi.getGenericDeviceClass(), npi.getSpecificDeviceClass()),
|
||||||
|
npi.isListening(),
|
||||||
|
this
|
||||||
|
);
|
||||||
|
logger.trace("Created new node: {}: {}", nodeId, node);
|
||||||
|
} else {
|
||||||
|
logger.debug("Node[{}] matches persistent node information; no need to interview", nodeId);
|
||||||
|
}
|
||||||
|
addNode(node);
|
||||||
} catch (NodeCreationException e) {
|
} catch (NodeCreationException e) {
|
||||||
logger.error("Unable to create node", e);
|
logger.error("Unable to create node", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void addNode(ZWaveNode node) {
|
||||||
public void onSendData(SendData sendData) {
|
ZWaveNode n = nodeMap.get(node.getNodeId());
|
||||||
byte nodeId = sendData.getNodeId();
|
if (n != null) {
|
||||||
ZWaveNode node = nodeMap.get(nodeId);
|
nodes.remove(n);
|
||||||
if (node != null) {
|
nodeMap.remove(node.getNodeId());
|
||||||
node.onDataFrameReceived(this, sendData);
|
|
||||||
} else {
|
|
||||||
logger.error("Unable to find node " + nodeId);
|
|
||||||
}
|
}
|
||||||
|
nodes.add(node);
|
||||||
|
nodeMap.put(node.getNodeId(), node);
|
||||||
|
node.startInterview(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationCommand(ApplicationCommand applicationCommand) {
|
public void onApplicationCommand(ApplicationCommand applicationCommand) {
|
||||||
ZWaveNode node = nodeMap.get(applicationCommand.getNodeId());
|
ZWaveNode node = nodeMap.get(applicationCommand.getNodeId());
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.onDataFrameReceived(this, applicationCommand);
|
node.onApplicationCommand(this, applicationCommand);
|
||||||
if (listener != null && node.isStarted()) {
|
if (node.isStarted()) {
|
||||||
listener.onZWaveNodeUpdated(node);
|
onZWaveNodeUpdated(node);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Unable to find node " + applicationCommand.getNodeId());
|
logger.error("Unable to find node: {}", nodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,55 +351,117 @@ public class NettyZWaveController implements ZWaveController, ZWaveControllerCon
|
||||||
if (nodeId != null) {
|
if (nodeId != null) {
|
||||||
ZWaveNode node = nodeMap.get(nodeId);
|
ZWaveNode node = nodeMap.get(nodeId);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.onDataFrameReceived(this, applicationUpdate);
|
node.onApplicationUpdate(this, applicationUpdate);
|
||||||
if (listener != null && node.isStarted()) {
|
if (node.isStarted()) {
|
||||||
listener.onZWaveNodeUpdated(node);
|
onZWaveNodeUpdated(node);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Unable to find node " + applicationUpdate.getNodeId());
|
logger.error("Unable to find node: {}", nodeId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Unable to determine node to route ApplicationUpdate to");
|
logger.error("Unable to determine node to route ApplicationUpdate to");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransactionStarted(TransactionStartedEvent evt) {
|
||||||
|
logger.trace("Detected start of new transaction: {}", evt.getId());
|
||||||
|
serial.getChannel().write(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransactionComplete(TransactionCompletedEvent evt) {
|
||||||
|
logger.trace("Detected end of transaction: {}", evt.getId());
|
||||||
|
if (evt instanceof SendDataTransactionCompletedEvent) {
|
||||||
|
ZWaveNode node = nodeMap.get(evt.getNodeId());
|
||||||
|
if (node != null) {
|
||||||
|
node.onSendDataCallback(this, true);
|
||||||
|
} else {
|
||||||
|
logger.error("Unable to find node: {}", evt.getNodeId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serial.getChannel().write(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransactionFailed(TransactionFailedEvent evt) {
|
||||||
|
logger.trace("Detected transaction failure: {}", evt.getId());
|
||||||
|
if (evt instanceof SendDataTransactionFailedEvent) {
|
||||||
|
ZWaveNode node = nodeMap.get(evt.getNodeId());
|
||||||
|
if (node != null) {
|
||||||
|
node.onSendDataCallback(this, ((SendDataTransactionFailedEvent)evt).isTargetNodeACKReceived());
|
||||||
|
} else {
|
||||||
|
logger.error("Unable to find node: {}", evt.getNodeId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serial.getChannel().write(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAddNodeToNetwork(AddNodeToNetwork update) {
|
||||||
|
if (listener != null) {
|
||||||
|
switch (update.getStatus()) {
|
||||||
|
case AddNodeToNetwork.ADD_NODE_STATUS_LEARN_READY:
|
||||||
|
onZWaveInclusionStarted();
|
||||||
|
break;
|
||||||
|
case AddNodeToNetwork.ADD_NODE_STATUS_DONE:
|
||||||
|
onZWaveInclusionStopped();
|
||||||
|
break;
|
||||||
|
case AddNodeToNetwork.ADD_NODE_STATUS_ADDING_CONTROLLER:
|
||||||
|
case AddNodeToNetwork.ADD_NODE_STATUS_ADDING_SLAVE:
|
||||||
|
onZWaveInclusion(update.getNodeInfo(), true);
|
||||||
|
break;
|
||||||
|
case AddNodeToNetwork.ADD_NODE_STATUS_FAILED:
|
||||||
|
onZWaveInclusion(update.getNodeInfo(), false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.debug("Received unexpected status from AddNodeToNetwork frame: {}", update.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemoveNodeFromNetwork(RemoveNodeFromNetwork update) {
|
||||||
|
if (listener != null) {
|
||||||
|
switch (update.getStatus()) {
|
||||||
|
case RemoveNodeFromNetwork.REMOVE_NODE_STATUS_LEARN_READY:
|
||||||
|
onZWaveExclusionStarted();
|
||||||
|
break;
|
||||||
|
case RemoveNodeFromNetwork.REMOVE_NODE_STATUS_DONE:
|
||||||
|
onZWaveExclusionStopped();
|
||||||
|
break;
|
||||||
|
case RemoveNodeFromNetwork.REMOVE_NODE_STATUS_NODE_FOUND:
|
||||||
|
logger.debug("A node has been found that wants to be excluded: {}", ByteUtil.createString(update.getSource()));
|
||||||
|
break;
|
||||||
|
case RemoveNodeFromNetwork.REMOVE_NODE_STATUS_REMOVING_CONTROLLER:
|
||||||
|
case RemoveNodeFromNetwork.REMOVE_NODE_STATUS_REMOVING_SLAVE:
|
||||||
|
onZWaveExclusion(update.getNodeInfo(), true);
|
||||||
|
break;
|
||||||
|
case RemoveNodeFromNetwork.REMOVE_NODE_STATUS_FAILED:
|
||||||
|
onZWaveExclusion(update.getNodeInfo(), false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.debug("Received unexpected status from RemoveNodeFromNetwork frame: {}", update.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetDefault() {
|
||||||
|
logger.info("Z-Wave controller has been reset to factory default");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NodeListener methods
|
* NodeListener methods
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNodeStarted(ZWaveNode node) {
|
public void onNodeStarted(ZWaveNode node) {
|
||||||
|
// save the newly started node
|
||||||
|
logger.debug("Saving information for node {}", node.getNodeId());
|
||||||
|
store.saveNode(node);
|
||||||
|
|
||||||
// when a node moves to the "started" state, alert listeners that it's ready to be added
|
// when a node moves to the "started" state, alert listeners that it's ready to be added
|
||||||
if (listener != null) {
|
onZWaveNodeAdded(node);
|
||||||
listener.onZWaveNodeAdded(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test main
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
NettyZWaveController c = new NettyZWaveController("/dev/cu.SLAB_USBtoUART");
|
|
||||||
ZWaveControllerListener listener = new ZWaveControllerListener() {
|
|
||||||
@Override
|
|
||||||
public void onZWaveNodeAdded(ZWaveEndpoint node) {
|
|
||||||
System.out.println("onZWaveNodeAdded: " + node);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onZWaveNodeUpdated(ZWaveEndpoint node) {
|
|
||||||
System.out.println("onZWaveNodeUpdated: " + node);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onZWaveConnectionFailure(Throwable t) {
|
|
||||||
System.out.println("A connection error occurred: " + t.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
c.setListener(listener);
|
|
||||||
c.start();
|
|
||||||
|
|
||||||
Thread.sleep(10000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import io.netty.channel.RecvByteBufAllocator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static io.netty.channel.jsc.JSCChannelOption.*;
|
import static io.netty.channel.jsc.JSCChannelOption.*;
|
||||||
import static io.netty.channel.rxtx.RxtxChannelOption.WAIT_TIME;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default configuration class for jSerialComm device connections.
|
* Default configuration class for jSerialComm device connections.
|
||||||
|
|
@ -52,24 +51,18 @@ final class DefaultJSCChannelConfig extends DefaultChannelConfig implements JSCC
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <T> T getOption(ChannelOption<T> option) {
|
public <T> T getOption(ChannelOption<T> option) {
|
||||||
if (option == BAUD_RATE) {
|
if (option == BAUD_RATE)
|
||||||
return (T) Integer.valueOf(getBaudrate());
|
return (T) Integer.valueOf(getBaudrate());
|
||||||
}
|
else if (option == STOP_BITS)
|
||||||
if (option == STOP_BITS) {
|
|
||||||
return (T) getStopbits();
|
return (T) getStopbits();
|
||||||
}
|
else if (option == DATA_BITS)
|
||||||
if (option == DATA_BITS) {
|
|
||||||
return (T) Integer.valueOf(getDatabits());
|
return (T) Integer.valueOf(getDatabits());
|
||||||
}
|
else if (option == PARITY_BIT)
|
||||||
if (option == PARITY_BIT) {
|
|
||||||
return (T) getParitybit();
|
return (T) getParitybit();
|
||||||
}
|
else if (option == WAIT_TIME)
|
||||||
if (option == WAIT_TIME) {
|
|
||||||
return (T) Integer.valueOf(getWaitTimeMillis());
|
return (T) Integer.valueOf(getWaitTimeMillis());
|
||||||
}
|
else if (option == READ_TIMEOUT)
|
||||||
if (option == READ_TIMEOUT) {
|
|
||||||
return (T) Integer.valueOf(getReadTimeout());
|
return (T) Integer.valueOf(getReadTimeout());
|
||||||
}
|
|
||||||
return super.getOption(option);
|
return super.getOption(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public final class JSCChannelOption<T> extends ChannelOption<T> {
|
||||||
public static final ChannelOption<Stopbits> STOP_BITS = valueOf("STOP_BITS");
|
public static final ChannelOption<Stopbits> STOP_BITS = valueOf("STOP_BITS");
|
||||||
public static final ChannelOption<Integer> DATA_BITS = valueOf("DATA_BITS");
|
public static final ChannelOption<Integer> DATA_BITS = valueOf("DATA_BITS");
|
||||||
public static final ChannelOption<Paritybit> PARITY_BIT = valueOf("PARITY_BIT");
|
public static final ChannelOption<Paritybit> PARITY_BIT = valueOf("PARITY_BIT");
|
||||||
public static final ChannelOption<Integer> WAIT_TIME = valueOf("WITE_TIMEOUT");
|
public static final ChannelOption<Integer> WAIT_TIME = valueOf("WAIT_TIME");
|
||||||
public static final ChannelOption<Integer> READ_TIMEOUT = valueOf("READ_TIMEOUT");
|
public static final ChannelOption<Integer> READ_TIMEOUT = valueOf("READ_TIMEOUT");
|
||||||
|
|
||||||
@SuppressWarnings({ "unused", "deprecation" })
|
@SuppressWarnings({ "unused", "deprecation" })
|
||||||
|
|
|
||||||
|
|
@ -3,26 +3,87 @@ package se.hal.plugin.zwave;
|
||||||
import com.whizzosoftware.wzwave.controller.ZWaveController;
|
import com.whizzosoftware.wzwave.controller.ZWaveController;
|
||||||
import com.whizzosoftware.wzwave.controller.ZWaveControllerListener;
|
import com.whizzosoftware.wzwave.controller.ZWaveControllerListener;
|
||||||
import com.whizzosoftware.wzwave.controller.netty.NettyZWaveController;
|
import com.whizzosoftware.wzwave.controller.netty.NettyZWaveController;
|
||||||
|
import com.whizzosoftware.wzwave.node.NodeInfo;
|
||||||
import com.whizzosoftware.wzwave.node.ZWaveEndpoint;
|
import com.whizzosoftware.wzwave.node.ZWaveEndpoint;
|
||||||
|
import com.whizzosoftware.wzwave.persist.HashMapPersistentStore;
|
||||||
import se.hal.HalContext;
|
import se.hal.HalContext;
|
||||||
import se.hal.intf.*;
|
import se.hal.intf.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HalZWaveController implements HalSensorController, HalEventController, HalAutoScannableController, ZWaveControllerListener {
|
public class HalZWaveController implements HalSensorController, HalEventController, HalAutoScannableController {
|
||||||
|
|
||||||
private ZWaveController controller;
|
private ZWaveController controller;
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
NettyZWaveController zwave = new NettyZWaveController("COM5", new HashMapPersistentStore());
|
||||||
|
zwave.setListener(new ZWaveControllerListener(){
|
||||||
|
@Override
|
||||||
|
public void onZWaveNodeAdded(ZWaveEndpoint node) {
|
||||||
|
System.out.println("onZWaveNodeAdded: "+ node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveNodeUpdated(ZWaveEndpoint node) {
|
||||||
|
System.out.println("onZWaveNodeUpdated: "+ node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveConnectionFailure(Throwable t) {
|
||||||
|
System.out.println("onZWaveConnectionFailure: "+ t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveControllerInfo(String libraryVersion, Integer homeId, Byte nodeId) {
|
||||||
|
System.out.println("onZWaveControllerInfo: "+ libraryVersion+" "+homeId+" "+nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveInclusionStarted() {
|
||||||
|
System.out.println("onZWaveInclusionStarted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveInclusion(NodeInfo nodeInfo, boolean success) {
|
||||||
|
System.out.println("onZWaveInclusion: "+ nodeInfo + " "+success);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveInclusionStopped() {
|
||||||
|
System.out.println("onZWaveInclusionStopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveExclusionStarted() {
|
||||||
|
System.out.println("onZWaveExclusionStarted");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveExclusion(NodeInfo nodeInfo, boolean success) {
|
||||||
|
System.out.println("onZWaveExclusion: "+ nodeInfo + " "+success);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveExclusionStopped() {
|
||||||
|
System.out.println("onZWaveExclusionStopped");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
zwave.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
return HalContext.getStringProperty("zwave.com_port") != null;
|
return HalContext.getStringProperty("zwave.com_port") != null;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void initialize() throws Exception {
|
public void initialize() throws Exception {
|
||||||
controller = new NettyZWaveController(HalContext.getStringProperty("zwave.com_port"));
|
//controller = new NettyZWaveController(HalContext.getStringProperty("zwave.com_port"));
|
||||||
controller.setListener(this);
|
//controller.setListener(this);
|
||||||
controller.start();
|
controller.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,20 +95,6 @@ public class HalZWaveController implements HalSensorController, HalEventControll
|
||||||
|
|
||||||
////////////// Z-WAVE CODE ////////////////////////
|
////////////// Z-WAVE CODE ////////////////////////
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onZWaveNodeAdded(ZWaveEndpoint zWaveEndpoint) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onZWaveNodeUpdated(ZWaveEndpoint zWaveEndpoint) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onZWaveConnectionFailure(Throwable throwable) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////// HAL CODE ////////////////////////
|
////////////// HAL CODE ////////////////////////
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue