Java Libraries to Use for Serial and USB Devices

Here are some ideas when using openHAB 2.5.0-SNAPSHOT:

Properly configure the serial port

Make sure you have sufficient permissions to access the serial port. On Linux you need to be in the right group (usually dialout).

See also: Serial Port Configuration.

If you’re using udev rules to create (non-standard) aliases for serial ports you need to add these to the -Dgnu.io.rxtx.SerialPorts= list. That’s because the serial library (nrjavaserial) cannot assume each and every file in /dev/ is a serial port. :wink:

It’s depending on the OS/distribution which files are considered for serial ports. You can find this logic in RXTXCommDriver.java.

Make sure the serial transport is installed

If you’re adding your binding JAR to an existing openHAB instance, make sure the serial transport is installed.

You can check if it is installed on the Karaf Console as follows:

openhab> bundle:list -s | grep serial
209 │ Active │  80 │ 3.15.0.OH2            │ com.neuronrobotics.nrjavaserial
211 │ Active │  80 │ 2.5.0.201906040317    │ org.openhab.core.io.transport.serial
212 │ Active │  80 │ 2.5.0.201906040321    │ org.openhab.core.io.transport.serial.rxtx

If these are not there, install them using:

feature:install openhab-core-io-transport-serial

You can also install them by installing an existing binding with these dependencies.

E.g. on 2.5.0-SNAPSHOT:

DSMR, EnOcean, PowerMax, RFXCom, Serial Button, Smartmeter, Plugwise, ZWave

Make sure the serial transports are part of the “Run Requirements” when debugging with Eclipse

Besides adding your binding bundle, the org.openhab.core.io.transport.serial and org.openhab.core.io.transport.serial.rxtx bundles need to be added to the “Run Requirements” of app.bndrun:

Then click “Resolve”, save the file and “Debug OSGi”.

If you’re using a non-standard serial port name (udev rules) you’ll probably need to setup the environment variable for these in the app.bndrun "Run Configuration ", e.g. right click app.bndrun and select “Debug As” -> “Debug Configurations…”:

4 Likes

If you use more than one, all serial ports that you want to use need to be added. If not, when you make a selection, the list will collapse to the port you’ve selected and you won’t be able to use the other port.

2 Likes

Hello Raphael,

this are parts of my current implementation, I hope, it helps:

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

//=======================================================
// class LCNSerialHandler
//
//=======================================================
public class LCNSerialHandler extends BaseThingHandler
{

private final Logger logger = LoggerFactory.getLogger(LCNSerialHandler.class); 
private static SerialPort serialPort = null;
private static LCNPort    myLCNPort  = null;
//==================================
// Constructor
//
//=================================== 	
public LCNSerialHandler(Thing thing) 
{
    super(thing);
}


//==================================
// void initialize()
//
//=================================== 
@Override
public void initialize() 
{
    instCount ++;	// Increment InstanceCounter
    
    String port  = (String) getConfig().get(LCNSerialBindingConstants.CONFIG_PORT); 
    
    String lcn_IdStr = (String) getConfig().get(LCNSerialBindingConstants.CONFIG_LCN_ID);
    lcnAdress = Integer.parseInt(lcn_IdStr);
        
    if (port == null | lcn_IdStr == null) 
    {
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, "Parameter must be set!");
        return;
    }
           
    try 
    {
		initPort( port, this);
	} 
    catch (Exception e1) 
    {
    	e1.printStackTrace();
	}

	try 
	{
		myLCNPort.Read_Modul_All(lcnAdress);
	} 
	catch (InterruptedException | IOException e) 
	{
    	e.printStackTrace();
	}

	logger.info("Update ThingStatus LCNSerial: ok");
	
    updateStatus(ThingStatus.ONLINE);
    
               
}

//============================================================
// void initPort( String port,  LCNSerialHandler handler)
//
//============================================================
private void initPort( String port, LCNSerialHandler handler) throws Exception
{
	if (serialPort != null)
	{
		myLCNPort.SetLCNSerialHandler(lcnAdress, handler);
		return;
	}
	  	
	CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(port);
	if (portIdentifier.isCurrentlyOwned()) 
	{
		throw new Exception("Port is currently in use");
	}

	CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); // timeout 2 s.
	if (!(commPort instanceof SerialPort)) 
	{
		throw new Exception("Only serial port is supported");
	}
	
	serialPort = (SerialPort) commPort;
	
	// 9600 bit/s, 8 bits, stop bit length 1, no parity bit   
    serialPort.setSerialPortParams(9600, 8,1,0);
    
    serialPort.disableReceiveTimeout();
        
    serialPort.setRTS(false);
    serialPort.setDTR(true);
    
    
}

}

Beside that, it’s correct, what wborn mentioned: These features must be activated:

209 │ Active │ 80 │ 3.15.0.OH2 │ com.neuronrobotics.nrjavaserial
211 │ Active │ 80 │ 2.5.0.201906040317 │ org.openhab.core.io.transport.serial
212 │ Active │ 80 │ 2.5.0.201906040321 │ org.openhab.core.io.transport.serial.rxtx

In the “runbundles” of app.bndrun, “com.neuronrobotics.nrjavaserial;version=’[3.15.0,3.15.1)’,”
is added.

Please don’t provide this code as a (good) example. Besides the openHAB styling/naming is incorrect, throws not allowed generic Exception, printStrackTrace which is bad. Has non final static fields. Doesn’t use getConfigAs (So you have to parse the config values yourself). You should not use the gnu serial library directly but use the openHAB added layer via org.eclipse.smarthome.io.transport.serial.SerialPortManager
I don’t want to discourage you, but this code makes me, as a reviewer, very sad :frowning_face:. If you want to see how to implement serial take a look at the DSMR binding.

2 Likes

Hello Hilbrand,

Pls keep in mind and think about my comments

  1. The OpenHAB-Topic is the first time, I ever in my live had contact to a development community
  2. I only wanted to help with my answer
  3. Until now, I never used Eclipse, Java, maven and all these things - so I‘m a complete beginner
  4. Nevertheless I have the goal to create a LCN-Binding, which will help other users of OpenHAB. On my machine, this binding works meanwhile
  5. I can understand, that it‘s a challenge to keep Code-quality in an open-source community high.
  6. But pls. give a beginner like me the chance, to become better.
  7. Beginners like me need the feedback from the experts like you. But to say, that you‘re sad about what you see can only lead to frustration, not motivation. But Motivation is the base for the community…

Hi Thomas,

Don’t get frustrated by comments like this. Remember, even those hard core coders sometimes show actual signs of human emotion. :laughing::wink::laughing:
Keep in mind that the Dutch - being one myself - are known for being candit and to the point, right @hilbrand
Actually, you should feel honored. Normally they only respond in JSON-format or some abstract class or interface! :rofl::rofl::rofl:

I also started my first steps in the world of binding development and it has a steep learning curve for newcomers like me, I can say. Especially on the library usage and framework ‘interaction’ part.

So, keep up the good work. There are never enough bindings in the world of OH!

:+1::+1::+1:

qft

Thanks for all the feedback, and sorry for not responding for a long time. I don’t remember what exactly made it work finally, but I definitely @wborn’s comment about adding Run requirements was involved. Now I have
Run Requirements: org.openhab.core.io.transport.serial.rxtx
Run Bundles:

org.openhab.core.io.transport.serial;version=‘[2.5.0,2.5.1)’,
com.neuronrobotics.nrjavaserial;version=‘[3.15.0,3.15.1)’,
org.openhab.core.io.transport.serial.rxtx;version=‘[2.5.0,2.5.1)’

and
-runvm: -Dgnu.io.rxtx.SerialPorts=/dev/ttyUSB0

for development in eclipse and I’ll see what I need on the target RaspberryPi.

edit: fix formatting

As you most likely spotted on, there are ongoing changes in how IDE is set up. Moreover, there are few technologies (Maven, OSGi, Karaf, Bnd/Bndtools, JSON processing) beside plain Java, which cause quite steep learning curve. You can follow the documentation about these to be ready for eventual traps and troubles.

Do you intend to swap existing LCN1 binding and provide version valid for oopenHAB2? If so then we can have a separate chat. :slight_smile:

Cheers,
Łukasz

Hello Lukasz,

My LCN Binding is for OpenHAB-2, it‘s completely different - LCN-PCHK is not needed.I’m doing the LCN-Bus communication directly.

Cheers
Thomas

1 Like

Please forgive what may be an ignorant question. Did you get your binding to work? I am interested in installing OpenHAB on a Raspberry Pi to control the lights and shutters in my house using the LCN-PKU that is already installed in the panel. But I would rather not have to buy LCN-PCHK since I don’t know how well this will all work. On this page, it says the LCN binding requires LCN-PCHK or LCN-PKE

Thank you
Matt

I am afraid there is no enough interest (both money and community wise) in getting LCN integration at that level. I have LCN myself and imposed connection limit is pain in the a…
There are other commercial products which are able to attach directly to LCN bus (ie domiq), but you wont get any protocol description from them. For sure OH is indirect competitor for them, as well as for LCN integration server (one which map modbus, bacnet etc.).
From what was told to me LCN bus uses modified rs485 to run on high voltage, yet I had no ways to confirm that myself. The difficult part in getting it over is really correlating serial level telegrams with PCHK output, probably for each and every active bus participant LCN offers.

So this thing is really just for professional system integrators to use with a laptop running some LCN-specific configuration software? It’s not intended to be used as an interface to a home automation system? Or it’s just not common enough for anyone to develop a use case for it in OpenHAB?
image

It is intended to be used as integration plug together with PCHK software which translate bus level telegrams to text protocol handled by OH-LCN integration.

@Fischert implemented raw binding which was able to switch inputs/outputs over USB and without PCHK. Not sure where his work ended.

Hello Łukasz,

My LCN-binding is directly using the bus-protocol, but I never tested it with USB, only with serial port-communication.

I’m using it with Openhab 2.0 since a long time, open issue furthermore is the shutter-implementation. I tried to realize a time based position-automation, but the current implementation of that functionality is not good enough.

Best regards
Thomas

Thomas,

I haven’t yet started implementing OpenHAB. I have been waiting to make sure there is a reasonable chance of success before buying the Raspberry Pi and going down the rabbit hole.

Is your LCN-binding available to download once I decide to jump in?

Thanks,
Matt

Hi Matt,

I can send you the binding, that‘s no problem.

But as I mentioned:

  • I‘ m using the serial connector (LCN-PK), I never tested it with the USB Connector (LCN- PKU)
  • I developed the binding some time again - for Openhab-2.0. I don‘t know if something has to be adapted for 2.5.

Regards
Thomas

The manufacturer of LCN strongly discourages accessing the LCN bus directly via serial connection.

Using LCN-PCHK or LCN-PKE is the recommended way. These softwares contain important timings like appropriate inter-frame gaps and also rate-limits in case a third-party software like OH runs crazy to guarentee a still functioning bus. Accessing the bus directly has impact to collision detection and can therefore cause lost frames.

Just for clarification, there is an LCN binding for openHAB 2 & 3, which is part of the official distribution.

Disclaimer: I’m a former employee/developer of the manufacturer company and I’m the author of above binding.

2 Likes

Technically speaking this is what ebus binding does thanks to https://github.com/csowada/ebus. @csowada implemented bus collision detection, handling of escape symbols and all other low level stuff. All possible with serial port.
There are other solutions such domiq mentioned above, which is attached directly to bus. Without the need for a connection license. Things you mention have impact on the complexity of integration thus also the costs of its development to achieve stable work over time.