
org.ogema.driver.zwave.ZWaveDriver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zwave Show documentation
Show all versions of zwave Show documentation
Low-level zwave device driver
The newest version!
/**
* Copyright 2011-2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Wissenschaften e.V.
*
* This file is part of OGEMA.
*
* OGEMA is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* as published by the Free Software Foundation.
*
* OGEMA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OGEMA. If not, see .
*/
package org.ogema.driver.zwave;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.ogema.core.channelmanager.driverspi.ChannelDriver;
import org.ogema.core.channelmanager.driverspi.ChannelLocator;
import org.ogema.core.channelmanager.driverspi.ChannelScanListener;
import org.ogema.core.channelmanager.driverspi.ChannelUpdateListener;
import org.ogema.core.channelmanager.driverspi.DeviceListener;
import org.ogema.core.channelmanager.driverspi.DeviceLocator;
import org.ogema.core.channelmanager.driverspi.DeviceScanListener;
import org.ogema.core.channelmanager.driverspi.NoSuchChannelException;
import org.ogema.core.channelmanager.driverspi.NoSuchDeviceException;
import org.ogema.core.channelmanager.driverspi.NoSuchInterfaceException;
import org.ogema.core.channelmanager.driverspi.SampledValueContainer;
import org.ogema.core.channelmanager.driverspi.ValueContainer;
import org.ogema.core.channelmanager.measurements.Value;
import org.ogema.core.hardwaremanager.HardwareDescriptor;
import org.ogema.core.hardwaremanager.HardwareListener;
import org.ogema.core.hardwaremanager.HardwareManager;
import org.ogema.core.hardwaremanager.UsbHardwareDescriptor;
import org.ogema.driver.zwave.manager.LocalDevice;
import org.ogema.driver.zwave.manager.Node;
import org.slf4j.Logger;
/**
*
* @author baerthbn
*
*/
public class ZWaveDriver implements ChannelDriver, HardwareListener {
private final Logger logger = org.slf4j.LoggerFactory.getLogger("zwave-driver");
private final Map connectionsMap; //
private final Map> listenerMap;
private final String driverId = "zwave-driver";
private final String description = "OGEMA ZWave Driver";
ArrayList devListeners;
private LocalDevice mainLocal;
private final Object connectionLock = new Object();
private HardwareManager hwMngr;
public ZWaveDriver(HardwareManager hwMngr) {
this.connectionsMap = new HashMap<>();
this.listenerMap = new HashMap<>();
this.devListeners = new ArrayList<>();
this.hwMngr = hwMngr;
hwMngr.addListener(this);
}
protected void addConnection(Connection con) {
mainLocal = con.getLocalDevice();
connectionsMap.put(con.getInterfaceId(), con);
con.getLocalDevice().addDeviceListeners(devListeners);
}
protected void removeConnection(String interfaceId) {
Connection con = connectionsMap.remove(interfaceId);
con.getLocalDevice().removeDeviceListeners(devListeners);
}
protected Map getConnections() {
return connectionsMap;
}
protected Connection findConnection(String interfaceId) {
return connectionsMap.get(interfaceId);
}
@Override
public String getDriverId() {
return driverId;
}
@Override
public String getDescription() {
return description;
}
@Override
public void startDeviceScan(String interfaceId, String filter, DeviceScanListener listener)
throws UnsupportedOperationException, NoSuchInterfaceException, IOException {
boolean success = false;
if (interfaceId != null) {
Connection connection = connectionsMap.get(interfaceId);
if (connection.getLocalDevice().isReady()) {
for (Entry deviceEntry : connection.getLocalDevice().getNodes().entrySet()) {
Node node = deviceEntry.getValue();
if (node.isReady() && node.getNodeId() != connection.getLocalDevice().getNodeId()) {
String parameters = node.getProductString() + ":" + node.getProductName();
DeviceLocator deviceLocator = new DeviceLocator(driverId, interfaceId, node
.getNodeName(), parameters);
logger.debug("\nDevice found:\nAddress = " + deviceLocator.getDeviceAddress()
+ "\nDeviceParameters = " + deviceLocator.getParameters());
listener.deviceFound(deviceLocator);
success = true;
}
}
}
}
else {
Set> connections = connectionsMap.entrySet();
if (connections.size() <= 0)
logger.debug("Currently there are no connections alive to ZWave coordinator hardware.");
else
for (Entry con : connections) {
if (con.getValue().getLocalDevice().isReady()) {
for (Entry deviceEntry : con.getValue().getLocalDevice().getNodes().entrySet()) {
Node node = deviceEntry.getValue();
if (node.isReady() && node.getNodeId() != con.getValue().getLocalDevice().getNodeId()) {
String parameters = node.getProductString() + ":" + node.getProductName();
DeviceLocator deviceLocator = new DeviceLocator(driverId, con.getValue()
.getInterfaceId(), node.getNodeName(), parameters);
logger.debug("\nDevice found:\nAddress = " + deviceLocator.getDeviceAddress()
+ "\nDeviceParameters = " + deviceLocator.getParameters());
listener.deviceFound(deviceLocator);
success = true;
}
}
}
}
}
listener.finished(success, null);
}
@Override
public void abortDeviceScan(String interfaceId, String filter) {
throw new UnsupportedOperationException(); // TODO how?
}
@Override
public void startChannelScan(DeviceLocator device, ChannelScanListener listener) {
String params = device.getParameters();
String id = params.substring(params.lastIndexOf(':') + 1, params.length());
mainLocal.printNodes();
Node node = mainLocal.nodes.get(Short.valueOf(id));
logger.debug(String.format("ChannelScanListener registered for node %d", Short.valueOf(id)));
node.addChannelListener(listener);
}
@Override
public List getChannelList(DeviceLocator device) throws UnsupportedOperationException {
return connectionsMap.get(device.getInterfaceName()).findDevice(device).getChannelLocators();
}
@Override
public void readChannels(List channels) throws UnsupportedOperationException, IOException {
for (SampledValueContainer container : channels) {
ChannelLocator channelLocator = container.getChannelLocator();
try {
Connection con = findConnection(channelLocator.getDeviceLocator().getInterfaceName());
Device dev = con.findDevice(channelLocator.getDeviceLocator());
Channel channel = dev.findChannel(channelLocator);
// read data
container.setSampledValue(channel.readValue(con));
} catch (NullPointerException e) {
throw new IOException("Unknown channel: " + channelLocator, e);
}
}
}
@Override
public void listenChannels(List channels, ChannelUpdateListener listener)
throws UnsupportedOperationException, NoSuchDeviceException, NoSuchChannelException, IOException {
logger.debug("listenChannels");
List channelList = listenerMap.get(listener);
if (channelList == null) {
channelList = new ArrayList();
}
for (SampledValueContainer container : channels) {
ChannelLocator channelLocator = container.getChannelLocator();
try {
DeviceLocator dev = channelLocator.getDeviceLocator();
Channel channel = findConnection(dev.getInterfaceName()).findDevice(dev).findChannel(channelLocator);
channel.setEventListener(container, listener);
channelList.add(channel);
} catch (NullPointerException e) {
throw new IOException("Unknown channel: " + channelLocator, e);
}
}
listenerMap.put(listener, channelList);
}
@Override
public void writeChannels(List channels) throws UnsupportedOperationException, IOException,
NoSuchDeviceException, NoSuchChannelException {
for (ValueContainer container : channels) {
ChannelLocator channelLocator = container.getChannelLocator();
try {
Connection con = findConnection(channelLocator.getDeviceLocator().getInterfaceName());
Device dev = con.findDevice(channelLocator.getDeviceLocator());
Channel channel = dev.findChannel(channelLocator);
channel.writeValue(con, container.getValue());
} catch (NullPointerException e) {
throw new IOException("Unknown channel: " + channelLocator, e);
}
}
}
@Override
public void channelAdded(ChannelLocator channel) {
DeviceLocator device = channel.getDeviceLocator();
String iface = device.getInterfaceName();
Connection con;
Device dev;
Channel chan;
// Connection handling
con = findConnection(iface);
if (con == null) {
return;
}
// Device handling
dev = con.findDevice(device);
if (dev == null) {
dev = new Device(device, con);
con.addDevice(dev);
}
// Channel handling
chan = dev.findChannel(channel);
if (chan == null) {
chan = new Channel(channel, dev);
dev.addChannel(chan);
}
}
@Override
public void channelRemoved(ChannelLocator channel) {
DeviceLocator device = channel.getDeviceLocator();
Connection con = findConnection(device.getInterfaceName());
Device dev = con.findDevice(device);
Channel chan = null;
chan = dev.findChannel(channel);
if (chan != null)
dev.removeChannel(chan);
}
@Override
public void hardwareAdded(HardwareDescriptor descriptor) {
/* This function is responsible for what to do when new hardware (e.g. usb stick) is added */
logger.debug("hardware added: " + descriptor.getIdentifier().toString());
establishConnection();
}
@Override
public void hardwareRemoved(HardwareDescriptor descriptor) {
logger.debug("hardware removed: " + descriptor.getIdentifier().toString());
String portName = ((UsbHardwareDescriptor) descriptor).getPortName();
if (portName != null) {
Connection con = connectionsMap.get(portName);
if (con != null)
con.close();
}
}
@Override
public void shutdown() {
}
@Override
public void addDeviceListener(DeviceListener listener) {
if (listener == null)
throw new NullPointerException("Listener object mustn't be null!");
devListeners.add(listener);
Set> connections = connectionsMap.entrySet();
for (Entry con : connections) {
LocalDevice dev = con.getValue().getLocalDevice();
dev.addDeviceListener(listener);
}
}
@Override
public void removeDeviceListener(DeviceListener listener) {
if (listener == null)
throw new NullPointerException("Listener object mustn't be null!");
devListeners.remove(listener);
Set> connections = connectionsMap.entrySet();
for (Entry con : connections) {
LocalDevice dev = con.getValue().getLocalDevice();
dev.removeDeviceListener(listener);
}
}
public DeviceLocator createDeviceLocator(String ifaceName, Node node) {
String prodString = node.getProductString();
String prodName = node.getProductName();
String nodeName = node.readNodeName();
// It can take a while until product string and product name are valid for a newly added node
int tries = 5;
while (tries-- > 0) {
prodName = node.getProductName();
prodString = node.getProductString();
if (!prodName.equals("") && !prodString.equals(".."))
break;
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
logger.debug(String.format("CreateDeviceLocator: ProductString = %s, ProductName = %s, NodeName = %s",
prodString, prodName, nodeName));
if (prodName.equals("") || prodName == null)
return null;
String parameters = prodString + ":" + prodName + ":" + node.getNodeId();
DeviceLocator deviceLocator = new DeviceLocator(driverId, ifaceName, nodeName, parameters);
return deviceLocator;
}
public void establishConnection() {
final String portName = getPortName(hwMngr);
Connection con = connectionsMap.get(portName);
if (con == null && portName != null) {
final ZWaveDriver driver = this;
Thread connectThread = new Thread() {
@Override
public void run() {
Connection con = new Connection(portName, connectionLock, hwMngr, driver);
synchronized (connectionLock) {
while (!con.hasConnection() && Activator.bundleIsRunning) {
try {
connectionLock.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
addConnection(con);
}
};
connectThread.setName("zwave-connect");
connectThread.start();
}
else if (con != null) {
con.getLocalDevice().restart();
}
else {
logger.info("No portname could be determined!");
}
}
String getPortName(HardwareManager hwMngr) {
String portName = System.getProperty(Constants.STATIC_IF_NAME);
if (portName == null) {
String hardwareDesriptors = System.getProperty(Constants.HARDWARE_DESCRIPTOR,
Constants.SIGMA_ACC_UZB_EU);
logger.info(String.format(
"No device file specified on the command line. The Hardware descriptor %s is used instead.",
hardwareDesriptors));
// Collection descriptors = hwMngr.getHardwareDescriptors(".+:0658:0200:");
Collection descriptors = hwMngr.getHardwareDescriptors(hardwareDesriptors);
// logger.info(
// String.format("Portname via hardware descriptor: %s.%s", hardwareDesriptors, descriptors.size()));
for (HardwareDescriptor descr : descriptors) {
portName = ((UsbHardwareDescriptor) descr).getPortName();
if (portName != null)
break;
}
}
logger.info(String.format("Port name detected %s", portName));
return portName;
}
@Override
public void writeChannel(ChannelLocator channelLocator, Value value) throws UnsupportedOperationException,
IOException, NoSuchDeviceException, NoSuchChannelException {
try {
Connection con = findConnection(channelLocator.getDeviceLocator().getInterfaceName());
Device dev = con.findDevice(channelLocator.getDeviceLocator());
Channel channel = dev.findChannel(channelLocator);
channel.writeValue(con, value);
} catch (NullPointerException e) {
throw new IOException("Unknown channel: " + channelLocator, e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy