Initial implementation of ZWave plugin
This commit is contained in:
parent
017b690437
commit
fa3b6f35f5
16 changed files with 1276 additions and 0 deletions
17
Hal.iml
17
Hal.iml
|
|
@ -6,6 +6,7 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/resource" type="java-resource" relativeOutputPath="resource" />
|
<sourceFolder url="file://$MODULE_DIR$/resource" type="java-resource" relativeOutputPath="resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/plugins/zwave/src" isTestSource="false" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
@ -21,6 +22,9 @@
|
||||||
</NATIVE>
|
</NATIVE>
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="jar://$USER_HOME$/.ideaLibSources/jSerialComm-1.3.10-sources.jar!/" />
|
<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/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>
|
||||||
|
|
@ -36,5 +40,18 @@
|
||||||
<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>
|
||||||
|
|
@ -15,3 +15,5 @@ sync_port=6666
|
||||||
# Network scanning should probably be disabled in some networks (default on)
|
# Network scanning should probably be disabled in some networks (default on)
|
||||||
#netscan.ipscan=false
|
#netscan.ipscan=false
|
||||||
|
|
||||||
|
## ZWave plugin
|
||||||
|
#zwave.com_port=COM4
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013 Whizzo Software, LLC.
|
||||||
|
* 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 com.whizzosoftware.wzwave.controller.netty;
|
||||||
|
|
||||||
|
import com.whizzosoftware.wzwave.channel.*;
|
||||||
|
import com.whizzosoftware.wzwave.codec.ZWaveFrameDecoder;
|
||||||
|
import com.whizzosoftware.wzwave.codec.ZWaveFrameEncoder;
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.jsc.JSerialCommChannel;
|
||||||
|
import io.netty.channel.oio.OioEventLoopGroup;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A abstract initializer
|
||||||
|
*
|
||||||
|
* @author Ziver Koc
|
||||||
|
*/
|
||||||
|
abstract class AbstractNettyChannelInitializer<T extends Channel> extends ChannelInitializer<T> {
|
||||||
|
|
||||||
|
protected String serialPort;
|
||||||
|
private ZWaveChannelInboundHandler inboundHandler;
|
||||||
|
|
||||||
|
protected Bootstrap bootstrap;
|
||||||
|
protected Channel channel;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractNettyChannelInitializer(String serialPort, ZWaveChannelListener listener) {
|
||||||
|
this.serialPort = serialPort;
|
||||||
|
this.inboundHandler = new ZWaveChannelInboundHandler(listener);
|
||||||
|
|
||||||
|
bootstrap = new Bootstrap();
|
||||||
|
bootstrap.group(new OioEventLoopGroup());
|
||||||
|
bootstrap.handler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initChannel(T channel) throws Exception {
|
||||||
|
this.channel = channel;
|
||||||
|
doInitChannel(channel);
|
||||||
|
|
||||||
|
// Setup general channel handlers and coders
|
||||||
|
channel.pipeline().addLast("decoder", new ZWaveFrameDecoder());
|
||||||
|
channel.pipeline().addLast("ack", new AcknowledgementInboundHandler());
|
||||||
|
channel.pipeline().addLast("transaction", new ZWaveDataFrameTransactionInboundHandler());
|
||||||
|
channel.pipeline().addLast("handler", inboundHandler);
|
||||||
|
channel.pipeline().addLast("encoder", new ZWaveFrameEncoder());
|
||||||
|
channel.pipeline().addLast("writeQueue", new ZWaveQueuedOutboundHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Bootstrap getBootstrap() {
|
||||||
|
return bootstrap;
|
||||||
|
}
|
||||||
|
public Channel getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract SocketAddress getSocketAddress();
|
||||||
|
|
||||||
|
protected abstract void doInitChannel(T channel) throws Exception;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013 Whizzo Software, LLC.
|
||||||
|
* 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 com.whizzosoftware.wzwave.controller.netty;
|
||||||
|
|
||||||
|
import com.whizzosoftware.wzwave.channel.ZWaveChannelListener;
|
||||||
|
import io.netty.channel.jsc.JSCChannelConfig;
|
||||||
|
import io.netty.channel.jsc.JSCDeviceAddress;
|
||||||
|
import io.netty.channel.jsc.JSerialCommChannel;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A jSerialComm serial port initializer
|
||||||
|
*
|
||||||
|
* @author Ziver Koc
|
||||||
|
*/
|
||||||
|
public class NettyJSCChannelInitializer extends AbstractNettyChannelInitializer<JSerialCommChannel> {
|
||||||
|
|
||||||
|
|
||||||
|
public NettyJSCChannelInitializer(String serialPort, ZWaveChannelListener listener) {
|
||||||
|
super(serialPort, listener);
|
||||||
|
|
||||||
|
bootstrap.channel(JSerialCommChannel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInitChannel(JSerialCommChannel channel) throws Exception {
|
||||||
|
this.channel = channel;
|
||||||
|
channel.config().setBaudrate(115200);
|
||||||
|
channel.config().setDatabits(8);
|
||||||
|
channel.config().setParitybit(JSCChannelConfig.Paritybit.NONE);
|
||||||
|
channel.config().setStopbits(JSCChannelConfig.Stopbits.STOPBITS_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCDeviceAddress getSocketAddress() {
|
||||||
|
return new JSCDeviceAddress(serialPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013 Whizzo Software, LLC.
|
||||||
|
* 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 com.whizzosoftware.wzwave.controller.netty;
|
||||||
|
|
||||||
|
import com.whizzosoftware.wzwave.channel.ZWaveChannelListener;
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.oio.OioEventLoopGroup;
|
||||||
|
import io.netty.channel.rxtx.RxtxChannel;
|
||||||
|
import io.netty.channel.rxtx.RxtxChannelConfig;
|
||||||
|
import io.netty.channel.rxtx.RxtxDeviceAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A RxTx serial port initializer
|
||||||
|
*
|
||||||
|
* @author Ziver Koc
|
||||||
|
*/
|
||||||
|
public class NettyRxtxChannelInitializer extends AbstractNettyChannelInitializer<RxtxChannel> {
|
||||||
|
|
||||||
|
|
||||||
|
public NettyRxtxChannelInitializer(String serialPort, ZWaveChannelListener listener) {
|
||||||
|
super(serialPort, listener);
|
||||||
|
|
||||||
|
bootstrap.channel(RxtxChannel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInitChannel(RxtxChannel channel) throws Exception {
|
||||||
|
channel.config().setBaudrate(115200);
|
||||||
|
channel.config().setDatabits(RxtxChannelConfig.Databits.DATABITS_8);
|
||||||
|
channel.config().setParitybit(RxtxChannelConfig.Paritybit.NONE);
|
||||||
|
channel.config().setStopbits(RxtxChannelConfig.Stopbits.STOPBITS_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RxtxDeviceAddress getSocketAddress() {
|
||||||
|
return new RxtxDeviceAddress(serialPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,251 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013 Whizzo Software, LLC.
|
||||||
|
* 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 com.whizzosoftware.wzwave.controller.netty;
|
||||||
|
|
||||||
|
import com.whizzosoftware.wzwave.channel.*;
|
||||||
|
import com.whizzosoftware.wzwave.codec.ZWaveFrameDecoder;
|
||||||
|
import com.whizzosoftware.wzwave.codec.ZWaveFrameEncoder;
|
||||||
|
import com.whizzosoftware.wzwave.controller.ZWaveController;
|
||||||
|
import com.whizzosoftware.wzwave.controller.ZWaveControllerContext;
|
||||||
|
import com.whizzosoftware.wzwave.controller.ZWaveControllerListener;
|
||||||
|
import com.whizzosoftware.wzwave.frame.*;
|
||||||
|
import com.whizzosoftware.wzwave.node.*;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Netty implementation of a ZWaveController.
|
||||||
|
*
|
||||||
|
* @author Dan Noguerol
|
||||||
|
*/
|
||||||
|
public class NettyZWaveController implements ZWaveController, ZWaveControllerContext, ZWaveControllerListener, ZWaveChannelListener, NodeListener {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(NettyZWaveController.class);
|
||||||
|
|
||||||
|
private AbstractNettyChannelInitializer serial;
|
||||||
|
private String libraryVersion;
|
||||||
|
private int homeId;
|
||||||
|
private byte nodeId;
|
||||||
|
private ZWaveControllerListener listener;
|
||||||
|
private final List<ZWaveNode> nodes = new ArrayList<ZWaveNode>();
|
||||||
|
private final Map<Byte,ZWaveNode> nodeMap = new HashMap<Byte,ZWaveNode>();
|
||||||
|
|
||||||
|
public NettyZWaveController(String serialPort) {
|
||||||
|
// Choose a available library
|
||||||
|
try{
|
||||||
|
Class.forName("gnu.io.SerialPort"); // check if RxTx is available
|
||||||
|
logger.info("RxTx is available, using it as Serial port Com port library");
|
||||||
|
serial = new NettyRxtxChannelInitializer(serialPort, this);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ZWaveController methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setListener(ZWaveControllerListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
serial.getBootstrap().connect(serial.getSocketAddress()).addListener(new ChannelFutureListener() {
|
||||||
|
@Override
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
|
if (future.isSuccess()) {
|
||||||
|
serial.getChannel().write(new Version());
|
||||||
|
serial.getChannel().write(new MemoryGetId());
|
||||||
|
serial.getChannel().write(new InitData());
|
||||||
|
} else {
|
||||||
|
listener.onZWaveConnectionFailure(future.cause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHomeId() {
|
||||||
|
return homeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLibraryVersion() {
|
||||||
|
return libraryVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ZWaveNode> getNodes() {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendDataFrame(DataFrame dataFrame) {
|
||||||
|
serial.getChannel().write(dataFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ZWaveControllerListener methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveNodeAdded(ZWaveEndpoint node) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveNodeAdded(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveNodeUpdated(ZWaveEndpoint node) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveNodeUpdated(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveConnectionFailure(Throwable t) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onZWaveConnectionFailure(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ZWaveChannelListener methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLibraryInfo(String libraryVersion) {
|
||||||
|
this.libraryVersion = libraryVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onControllerInfo(int homeId, byte nodeId) {
|
||||||
|
this.homeId = homeId;
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNodeProtocolInfo(byte nodeId, NodeProtocolInfo nodeProtocolInfo) {
|
||||||
|
try {
|
||||||
|
logger.trace("Received protocol info for node " + nodeId);
|
||||||
|
ZWaveNode node = ZWaveNodeFactory.createNode(this, nodeId, nodeProtocolInfo, this);
|
||||||
|
logger.trace("Created node [" + node.getNodeId() + "]: " + node);
|
||||||
|
nodes.add(node);
|
||||||
|
nodeMap.put(node.getNodeId(), node);
|
||||||
|
} catch (NodeCreationException e) {
|
||||||
|
logger.error("Unable to create node", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSendData(SendData sendData) {
|
||||||
|
byte nodeId = sendData.getNodeId();
|
||||||
|
ZWaveNode node = nodeMap.get(nodeId);
|
||||||
|
if (node != null) {
|
||||||
|
node.onDataFrameReceived(this, sendData);
|
||||||
|
} else {
|
||||||
|
logger.error("Unable to find node " + nodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationCommand(ApplicationCommand applicationCommand) {
|
||||||
|
ZWaveNode node = nodeMap.get(applicationCommand.getNodeId());
|
||||||
|
if (node != null) {
|
||||||
|
node.onDataFrameReceived(this, applicationCommand);
|
||||||
|
if (listener != null && node.isStarted()) {
|
||||||
|
listener.onZWaveNodeUpdated(node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error("Unable to find node " + applicationCommand.getNodeId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationUpdate(ApplicationUpdate applicationUpdate) {
|
||||||
|
Byte nodeId = applicationUpdate.getNodeId();
|
||||||
|
|
||||||
|
if (applicationUpdate.didInfoRequestFail()) {
|
||||||
|
logger.trace("UPDATE_STATE_NODE_INFO_REQ_FAILED received");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeId != null) {
|
||||||
|
ZWaveNode node = nodeMap.get(nodeId);
|
||||||
|
if (node != null) {
|
||||||
|
node.onDataFrameReceived(this, applicationUpdate);
|
||||||
|
if (listener != null && node.isStarted()) {
|
||||||
|
listener.onZWaveNodeUpdated(node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error("Unable to find node " + applicationUpdate.getNodeId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.error("Unable to determine node to route ApplicationUpdate to");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NodeListener methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNodeStarted(ZWaveNode node) {
|
||||||
|
// when a node moves to the "started" state, alert listeners that it's ready to be added
|
||||||
|
if (listener != null) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
231
plugins/zwave/src/io/netty/channel/jsc/DefaultJSCChannelConfig.java
Executable file
231
plugins/zwave/src/io/netty/channel/jsc/DefaultJSCChannelConfig.java
Executable file
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.channel.jsc;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.DefaultChannelConfig;
|
||||||
|
import io.netty.channel.MessageSizeEstimator;
|
||||||
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static io.netty.channel.jsc.JSCChannelOption.*;
|
||||||
|
import static io.netty.channel.rxtx.RxtxChannelOption.WAIT_TIME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default configuration class for jSerialComm device connections.
|
||||||
|
*/
|
||||||
|
final class DefaultJSCChannelConfig extends DefaultChannelConfig implements JSCChannelConfig {
|
||||||
|
|
||||||
|
private volatile int baudrate = 115200;
|
||||||
|
private volatile boolean dtr;
|
||||||
|
private volatile boolean rts;
|
||||||
|
private volatile Stopbits stopbits = Stopbits.STOPBITS_1;
|
||||||
|
private volatile int databits = 8;
|
||||||
|
private volatile Paritybit paritybit = Paritybit.NONE;
|
||||||
|
private volatile int waitTime;
|
||||||
|
private volatile int readTimeout = 1000;
|
||||||
|
|
||||||
|
DefaultJSCChannelConfig(JSerialCommChannel channel) {
|
||||||
|
super(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<ChannelOption<?>, Object> getOptions() {
|
||||||
|
return getOptions(super.getOptions(), BAUD_RATE, DTR, RTS, STOP_BITS, DATA_BITS, PARITY_BIT, WAIT_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T> T getOption(ChannelOption<T> option) {
|
||||||
|
if (option == BAUD_RATE) {
|
||||||
|
return (T) Integer.valueOf(getBaudrate());
|
||||||
|
}
|
||||||
|
if (option == STOP_BITS) {
|
||||||
|
return (T) getStopbits();
|
||||||
|
}
|
||||||
|
if (option == DATA_BITS) {
|
||||||
|
return (T) Integer.valueOf(getDatabits());
|
||||||
|
}
|
||||||
|
if (option == PARITY_BIT) {
|
||||||
|
return (T) getParitybit();
|
||||||
|
}
|
||||||
|
if (option == WAIT_TIME) {
|
||||||
|
return (T) Integer.valueOf(getWaitTimeMillis());
|
||||||
|
}
|
||||||
|
if (option == READ_TIMEOUT) {
|
||||||
|
return (T) Integer.valueOf(getReadTimeout());
|
||||||
|
}
|
||||||
|
return super.getOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> boolean setOption(ChannelOption<T> option, T value) {
|
||||||
|
validate(option, value);
|
||||||
|
|
||||||
|
if (option == BAUD_RATE) {
|
||||||
|
setBaudrate((Integer) value);
|
||||||
|
} else if (option == STOP_BITS) {
|
||||||
|
setStopbits((Stopbits) value);
|
||||||
|
} else if (option == DATA_BITS) {
|
||||||
|
setDatabits((Integer)value);
|
||||||
|
} else if (option == PARITY_BIT) {
|
||||||
|
setParitybit((Paritybit) value);
|
||||||
|
} else if (option == WAIT_TIME) {
|
||||||
|
setWaitTimeMillis((Integer) value);
|
||||||
|
} else if (option == READ_TIMEOUT) {
|
||||||
|
setReadTimeout((Integer) value);
|
||||||
|
} else {
|
||||||
|
return super.setOption(option, value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setBaudrate(final int baudrate) {
|
||||||
|
this.baudrate = baudrate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setStopbits(final Stopbits stopbits) {
|
||||||
|
this.stopbits = stopbits;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setDatabits(final int databits) {
|
||||||
|
this.databits = databits;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setParitybit(final Paritybit paritybit) {
|
||||||
|
this.paritybit = paritybit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBaudrate() {
|
||||||
|
return baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stopbits getStopbits() {
|
||||||
|
return stopbits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDatabits() {
|
||||||
|
return databits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Paritybit getParitybit() {
|
||||||
|
return paritybit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWaitTimeMillis() {
|
||||||
|
return waitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setWaitTimeMillis(final int waitTimeMillis) {
|
||||||
|
if (waitTimeMillis < 0) {
|
||||||
|
throw new IllegalArgumentException("Wait time must be >= 0");
|
||||||
|
}
|
||||||
|
waitTime = waitTimeMillis;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setReadTimeout(int readTimeout) {
|
||||||
|
if (readTimeout < 0) {
|
||||||
|
throw new IllegalArgumentException("readTime must be >= 0");
|
||||||
|
}
|
||||||
|
this.readTimeout = readTimeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getReadTimeout() {
|
||||||
|
return readTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
|
||||||
|
super.setConnectTimeoutMillis(connectTimeoutMillis);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public JSCChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
|
||||||
|
super.setMaxMessagesPerRead(maxMessagesPerRead);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setWriteSpinCount(int writeSpinCount) {
|
||||||
|
super.setWriteSpinCount(writeSpinCount);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setAllocator(ByteBufAllocator allocator) {
|
||||||
|
super.setAllocator(allocator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
|
||||||
|
super.setRecvByteBufAllocator(allocator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setAutoRead(boolean autoRead) {
|
||||||
|
super.setAutoRead(autoRead);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setAutoClose(boolean autoClose) {
|
||||||
|
super.setAutoClose(autoClose);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
|
||||||
|
super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
|
||||||
|
super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
|
||||||
|
super.setMessageSizeEstimator(estimator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
236
plugins/zwave/src/io/netty/channel/jsc/JSCChannelConfig.java
Executable file
236
plugins/zwave/src/io/netty/channel/jsc/JSCChannelConfig.java
Executable file
|
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.channel.jsc;
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.channel.ChannelConfig;
|
||||||
|
import io.netty.channel.MessageSizeEstimator;
|
||||||
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A configuration class for JSerialComm device connections.
|
||||||
|
*
|
||||||
|
* <h3>Available options</h3>
|
||||||
|
*
|
||||||
|
* In addition to the options provided by {@link ChannelConfig},
|
||||||
|
* {@link DefaultJSCChannelConfig} allows the following options in the option map:
|
||||||
|
*
|
||||||
|
* <table border="1" cellspacing="0" cellpadding="6">
|
||||||
|
* <tr>
|
||||||
|
* <th>Name</th><th>Associated setter method</th>
|
||||||
|
* </tr><tr>
|
||||||
|
* <td>{@link JSCChannelOption#BAUD_RATE}</td><td>{@link #setBaudrate(int)}</td>
|
||||||
|
* </tr><tr>
|
||||||
|
* <td>{@link JSCChannelOption#STOP_BITS}</td><td>{@link #setStopbits(Stopbits)}</td>
|
||||||
|
* </tr><tr>
|
||||||
|
* <td>{@link JSCChannelOption#DATA_BITS}</td><td>{@link #setDatabits(int)}</td>
|
||||||
|
* </tr><tr>
|
||||||
|
* <td>{@link JSCChannelOption#PARITY_BIT}</td><td>{@link #setParitybit(Paritybit)}</td>
|
||||||
|
* </tr><tr>
|
||||||
|
* <td>{@link JSCChannelOption#WAIT_TIME}</td><td>{@link #setWaitTimeMillis(int)}</td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
*/
|
||||||
|
public interface JSCChannelConfig extends ChannelConfig {
|
||||||
|
enum Stopbits {
|
||||||
|
/**
|
||||||
|
* 1 stop bit will be sent at the end of every character
|
||||||
|
*/
|
||||||
|
STOPBITS_1(SerialPort.ONE_STOP_BIT),
|
||||||
|
/**
|
||||||
|
* 2 stop bits will be sent at the end of every character
|
||||||
|
*/
|
||||||
|
STOPBITS_2(SerialPort.TWO_STOP_BITS),
|
||||||
|
/**
|
||||||
|
* 1.5 stop bits will be sent at the end of every character
|
||||||
|
*/
|
||||||
|
STOPBITS_1_5(SerialPort.ONE_POINT_FIVE_STOP_BITS);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Stopbits(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stopbits valueOf(int value) {
|
||||||
|
for (Stopbits stopbit : Stopbits.values()) {
|
||||||
|
if (stopbit.value == value) {
|
||||||
|
return stopbit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("unknown " + Stopbits.class.getSimpleName() + " value: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Paritybit {
|
||||||
|
/**
|
||||||
|
* No parity bit will be sent with each data character at all
|
||||||
|
*/
|
||||||
|
NONE(SerialPort.NO_PARITY),
|
||||||
|
/**
|
||||||
|
* An odd parity bit will be sent with each data character, ie. will be set
|
||||||
|
* to 1 if the data character contains an even number of bits set to 1.
|
||||||
|
*/
|
||||||
|
ODD(SerialPort.ODD_PARITY),
|
||||||
|
/**
|
||||||
|
* An even parity bit will be sent with each data character, ie. will be set
|
||||||
|
* to 1 if the data character contains an odd number of bits set to 1.
|
||||||
|
*/
|
||||||
|
EVEN(SerialPort.EVEN_PARITY),
|
||||||
|
/**
|
||||||
|
* A mark parity bit (ie. always 1) will be sent with each data character
|
||||||
|
*/
|
||||||
|
MARK(SerialPort.MARK_PARITY),
|
||||||
|
/**
|
||||||
|
* A space parity bit (ie. always 0) will be sent with each data character
|
||||||
|
*/
|
||||||
|
SPACE(SerialPort.SPACE_PARITY);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
Paritybit(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Paritybit valueOf(int value) {
|
||||||
|
for (Paritybit paritybit : Paritybit.values()) {
|
||||||
|
if (paritybit.value == value) {
|
||||||
|
return paritybit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("unknown " + Paritybit.class.getSimpleName() + " value: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the baud rate (ie. bits per second) for communication with the serial device.
|
||||||
|
* The baud rate will include bits for framing (in the form of stop bits and parity),
|
||||||
|
* such that the effective data rate will be lower than this value.
|
||||||
|
*
|
||||||
|
* @param baudrate The baud rate (in bits per second)
|
||||||
|
*/
|
||||||
|
JSCChannelConfig setBaudrate(int baudrate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of stop bits to include at the end of every character to aid the
|
||||||
|
* serial device in synchronising with the data.
|
||||||
|
*
|
||||||
|
* @param stopbits The number of stop bits to use
|
||||||
|
*/
|
||||||
|
JSCChannelConfig setStopbits(Stopbits stopbits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of data bits to use to make up each character sent to the serial
|
||||||
|
* device.
|
||||||
|
*
|
||||||
|
* @param databits The number of data bits to use
|
||||||
|
*/
|
||||||
|
JSCChannelConfig setDatabits(int databits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of parity bit to be used when communicating with the serial device.
|
||||||
|
*
|
||||||
|
* @param paritybit The type of parity bit to be used
|
||||||
|
*/
|
||||||
|
JSCChannelConfig setParitybit(Paritybit paritybit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The configured baud rate, defaulting to 115200 if unset
|
||||||
|
*/
|
||||||
|
int getBaudrate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The configured stop bits, defaulting to {@link Stopbits#STOPBITS_1} if unset
|
||||||
|
*/
|
||||||
|
Stopbits getStopbits();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The configured data bits, defaulting to 8 if unset
|
||||||
|
*/
|
||||||
|
int getDatabits();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The configured parity bit, defaulting to {@link Paritybit#NONE} if unset
|
||||||
|
*/
|
||||||
|
Paritybit getParitybit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of milliseconds to wait between opening the serial port and
|
||||||
|
* initialising.
|
||||||
|
*/
|
||||||
|
int getWaitTimeMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the time to wait after opening the serial port and before sending it any
|
||||||
|
* configuration information or data. A value of 0 indicates that no waiting should
|
||||||
|
* occur.
|
||||||
|
*
|
||||||
|
* @param waitTimeMillis The number of milliseconds to wait, defaulting to 0 (no
|
||||||
|
* wait) if unset
|
||||||
|
* @throws IllegalArgumentException if the supplied value is < 0
|
||||||
|
*/
|
||||||
|
JSCChannelConfig setWaitTimeMillis(int waitTimeMillis);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximal time (in ms) to block while try to read from the serial port. Default is 1000ms
|
||||||
|
*/
|
||||||
|
JSCChannelConfig setReadTimeout(int readTimeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the maximal time (in ms) to block and wait for something to be ready to read.
|
||||||
|
*/
|
||||||
|
int getReadTimeout();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
JSCChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setWriteSpinCount(int writeSpinCount);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setAllocator(ByteBufAllocator allocator);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setAutoRead(boolean autoRead);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setAutoClose(boolean autoClose);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JSCChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator);
|
||||||
|
}
|
||||||
40
plugins/zwave/src/io/netty/channel/jsc/JSCChannelOption.java
Executable file
40
plugins/zwave/src/io/netty/channel/jsc/JSCChannelOption.java
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.channel.jsc;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.jsc.JSCChannelConfig.Paritybit;
|
||||||
|
import io.netty.channel.jsc.JSCChannelConfig.Stopbits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option for configuring a serial port connection
|
||||||
|
*/
|
||||||
|
public final class JSCChannelOption<T> extends ChannelOption<T> {
|
||||||
|
|
||||||
|
public static final ChannelOption<Integer> BAUD_RATE = valueOf("BAUD_RATE");
|
||||||
|
public static final ChannelOption<Boolean> DTR = valueOf("DTR");
|
||||||
|
public static final ChannelOption<Boolean> RTS = valueOf("RTS");
|
||||||
|
public static final ChannelOption<Stopbits> STOP_BITS = valueOf("STOP_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<Integer> WAIT_TIME = valueOf("WITE_TIMEOUT");
|
||||||
|
public static final ChannelOption<Integer> READ_TIMEOUT = valueOf("READ_TIMEOUT");
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unused", "deprecation" })
|
||||||
|
private JSCChannelOption() {
|
||||||
|
super(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
plugins/zwave/src/io/netty/channel/jsc/JSCDeviceAddress.java
Executable file
45
plugins/zwave/src/io/netty/channel/jsc/JSCDeviceAddress.java
Executable file
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.channel.jsc;
|
||||||
|
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link SocketAddress} subclass to wrap the serial port address of a jSerialComm
|
||||||
|
* device (e.g. COM1, /dev/ttyUSB0).
|
||||||
|
*/
|
||||||
|
public class JSCDeviceAddress extends SocketAddress {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -2907820090993709523L;
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSCDeviceAddress representing the address of the serial port.
|
||||||
|
*
|
||||||
|
* @param value the address of the device (e.g. COM1, /dev/ttyUSB0, ...)
|
||||||
|
*/
|
||||||
|
public JSCDeviceAddress(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The serial port address of the device (e.g. COM1, /dev/ttyUSB0, ...)
|
||||||
|
*/
|
||||||
|
public String value() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
181
plugins/zwave/src/io/netty/channel/jsc/JSerialCommChannel.java
Executable file
181
plugins/zwave/src/io/netty/channel/jsc/JSerialCommChannel.java
Executable file
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.channel.jsc;
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import io.netty.channel.oio.OioByteStreamChannel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static io.netty.channel.jsc.JSCChannelOption.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A channel to a serial device using the jSerialComm library.
|
||||||
|
*/
|
||||||
|
public class JSerialCommChannel extends OioByteStreamChannel {
|
||||||
|
|
||||||
|
private static final JSCDeviceAddress LOCAL_ADDRESS = new JSCDeviceAddress("localhost");
|
||||||
|
|
||||||
|
private final JSCChannelConfig config;
|
||||||
|
|
||||||
|
private boolean open = true;
|
||||||
|
private JSCDeviceAddress deviceAddress;
|
||||||
|
private SerialPort serialPort;
|
||||||
|
|
||||||
|
public JSerialCommChannel() {
|
||||||
|
super(null);
|
||||||
|
|
||||||
|
config = new DefaultJSCChannelConfig(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCChannelConfig config() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpen() {
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractUnsafe newUnsafe() {
|
||||||
|
return new JSCUnsafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
|
||||||
|
JSCDeviceAddress remote = (JSCDeviceAddress) remoteAddress;
|
||||||
|
SerialPort commPort = SerialPort.getCommPort(remote.value());
|
||||||
|
if(!commPort.openPort())
|
||||||
|
throw new IOException("Could not open port: "+remote.value());
|
||||||
|
|
||||||
|
commPort.setComPortTimeouts(
|
||||||
|
SerialPort.TIMEOUT_READ_BLOCKING, config().getOption(READ_TIMEOUT), 0);
|
||||||
|
|
||||||
|
deviceAddress = remote;
|
||||||
|
serialPort = commPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doInit() throws Exception {
|
||||||
|
serialPort.setComPortParameters(
|
||||||
|
config().getOption(BAUD_RATE),
|
||||||
|
config().getOption(DATA_BITS),
|
||||||
|
config().getOption(STOP_BITS).value(),
|
||||||
|
config().getOption(PARITY_BIT).value()
|
||||||
|
);
|
||||||
|
//serialPort.setFlowControl(config().getOption(FLOW_CTRL));
|
||||||
|
|
||||||
|
activate(serialPort.getInputStream(), serialPort.getOutputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCDeviceAddress localAddress() {
|
||||||
|
return (JSCDeviceAddress) super.localAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSCDeviceAddress remoteAddress() {
|
||||||
|
return (JSCDeviceAddress) super.remoteAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSCDeviceAddress localAddress0() {
|
||||||
|
return LOCAL_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSCDeviceAddress remoteAddress0() {
|
||||||
|
return deviceAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doBind(SocketAddress localAddress) throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doDisconnect() throws Exception {
|
||||||
|
doClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doClose() throws Exception {
|
||||||
|
open = false;
|
||||||
|
try {
|
||||||
|
super.doClose();
|
||||||
|
} finally {
|
||||||
|
if (serialPort != null) {
|
||||||
|
serialPort.closePort();
|
||||||
|
serialPort = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isInputShutdown() {
|
||||||
|
return !open;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final class JSCUnsafe extends AbstractUnsafe {
|
||||||
|
@Override
|
||||||
|
public void connect(
|
||||||
|
final SocketAddress remoteAddress,
|
||||||
|
final SocketAddress localAddress, final ChannelPromise promise) {
|
||||||
|
if (!promise.setUncancellable() || !isOpen()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean wasActive = isActive();
|
||||||
|
doConnect(remoteAddress, localAddress);
|
||||||
|
|
||||||
|
int waitTime = config().getOption(WAIT_TIME);
|
||||||
|
if (waitTime > 0) {
|
||||||
|
eventLoop().schedule(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
doInit();
|
||||||
|
safeSetSuccess(promise);
|
||||||
|
if (!wasActive && isActive()) {
|
||||||
|
pipeline().fireChannelActive();
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
safeSetFailure(promise, t);
|
||||||
|
closeIfClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, waitTime, TimeUnit.MILLISECONDS);
|
||||||
|
} else {
|
||||||
|
doInit();
|
||||||
|
safeSetSuccess(promise);
|
||||||
|
if (!wasActive && isActive()) {
|
||||||
|
pipeline().fireChannelActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
safeSetFailure(promise, t);
|
||||||
|
closeIfClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
plugins/zwave/src/io/netty/channel/jsc/package-info.java
Executable file
20
plugins/zwave/src/io/netty/channel/jsc/package-info.java
Executable file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A serial and parallel port communication transport based on <a href="http://rxtx.qbang.org/">RXTX</a>.
|
||||||
|
*/
|
||||||
|
package io.netty.channel.jsc;
|
||||||
92
plugins/zwave/src/se/hal/plugin/zwave/HalZWaveController.java
Executable file
92
plugins/zwave/src/se/hal/plugin/zwave/HalZWaveController.java
Executable file
|
|
@ -0,0 +1,92 @@
|
||||||
|
package se.hal.plugin.zwave;
|
||||||
|
|
||||||
|
import com.whizzosoftware.wzwave.controller.ZWaveController;
|
||||||
|
import com.whizzosoftware.wzwave.controller.ZWaveControllerListener;
|
||||||
|
import com.whizzosoftware.wzwave.controller.netty.NettyZWaveController;
|
||||||
|
import com.whizzosoftware.wzwave.node.ZWaveEndpoint;
|
||||||
|
import se.hal.HalContext;
|
||||||
|
import se.hal.intf.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HalZWaveController implements HalSensorController, HalEventController, HalAutoScannableController, ZWaveControllerListener {
|
||||||
|
|
||||||
|
private ZWaveController controller;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return HalContext.getStringProperty("zwave.com_port") != null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void initialize() throws Exception {
|
||||||
|
controller = new NettyZWaveController(HalContext.getStringProperty("zwave.com_port"));
|
||||||
|
controller.setListener(this);
|
||||||
|
controller.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
controller.stop();
|
||||||
|
controller = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////// Z-WAVE CODE ////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveNodeAdded(ZWaveEndpoint zWaveEndpoint) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveNodeUpdated(ZWaveEndpoint zWaveEndpoint) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onZWaveConnectionFailure(Throwable throwable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////// HAL CODE ////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(HalSensorConfig sensor) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void register(HalEventConfig event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deregister(HalSensorConfig sensor) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void deregister(HalEventConfig event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setListener(HalEventReportListener listener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setListener(HalSensorReportListener listener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(HalEventConfig eventConfig, HalEventData eventData) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue