New binding for DYI CANBUS based light switch solution

Hi all,

I am now working on new binding for my own DYI CANBUS based light switch solution. Firmware code: https://github.com/PoJD/can . PCB code: in my other can-pcb repo (I am limited by number of links in my first post).

All is probably clear from java/binding/discovery perspective, but I have a few questions to the community about the actual comm logic to the CANBUS.

I am now using USBTin device to connect from USB port to the CANBUS itself: https://www.fischl.de/usbtin/

I see several options how to make the binding work:

  1. use the provided LGPL licensed java library of the author: USBtinLib (github link again). Then only the traditional requirements for the openhab user of the openhab webapp apply (be member of dialout group or create udev rules to leverage dialout group permissions on all /dev/ttyACM* devices that this get mounted to).
  2. relay on socketCan. Currently I need to run slcand and attach commands as root, so this would be tricky to get into openhab web app unless I can make that a requirement to use this binding (are there other bindings with such requirements already?). Alternatively just use setGID for the socketcan processes (and probably ifconfig too in order to bring can network device up). This could then be just one time and part of the “installation procedure” to get can working on the host. Then use some library like libsocket-can-java in order to be able to leverage this in the webapp
  3. similar as above, but do not use any java library anymore, just rely on socketcan, commands like cansend, candump, etc and default to System.exec from java and parsing the outputs of the commands from within the binding code
  4. use built-in support in openhab (is this SerialPort now?) and reverse engineer and implement the comms logic to the device myself

Options 2 and 3 have the advantage that it won’t be much coding in the binding and in theory should also work for any other compatible device other than USBTin. But then not sure such pull request would get approved given that it has requirements on the host OS side to run prior running the webapp with this binding.

Option 1 is tricky due to the license itself. Already emailed license support team in ESH about the usage of that library, not sure I would get green light on that. Also this would mean if I got the tutorials correctly to actually upload the lib itself as opposed to traditional dependency management in maven (not to mention the above library is not actually present in any maven central anyway, but I could have gone the path of building it with maven and uploading myself. Actually already did some time ago my own fork and building it with maven). Less coding in binding though then, very simple and nice to use java API. No non-standard requirements at the host OS level.

Option 4 obviously would not have any of these limitations, but would require much more coding.

Is option 4 the preferred one by the community? If so, what libraries should I use for that? Should I try to make sense of perhaps openhab .org / addons / bindings / serial1/ and try to use that?

Thank you!
Lubos

1 Like

Few more updates:

re 2) I meant using https://github.com/linux-can/can-utils
re 4) I tried a simple POC using gnu.io package, serialPort, am able to connect to the port, but would need to now implement all the underlying logic that is now inside USBTin, so would only make it compatible with this USBTin device.

So I still prefer options 2 or 3… Or 1 if I get the license approved.

Nice work! Looks like you did a lot work to get that working. Regarding the license I don’t think that should be a problem as long as you include the library as a jar file (But I can’t make that decision). This is done for several other bindings also. Just search for LGPL in the openhab2-addons repository.
To make that work add the jar file in a lib folder in the root of your binding and reference to it in the MANIFEST.MF and build.properties files, and update the about.html to include the license (Look into other bindings for the best reference examples).
If you would include the source files from the library that would probably be a problem.

That having said the library itself has some problems as it outputs errors and messages to system out. And that won’t be logged correctly, so the user will have problems seeing those errors. Also the library isn’t that large, but unfortunately hasn’t separated serial communications from can bus properly. If that had been the case you could have used it with a different serial communications library. One solution could be to take the library and separate serial communications from the canbus logic in such a way the can logic can be used independent of the serial communications. You could try to work with the original developer to see if this can be build in the original library or just create your own fork.

If you want to learn more about serial communications within openHAB. The latest guidelines is to use the serial service. Take a look at the dsmr binding to how this could be implemented.

Two final remarks. Firstly. Correct me if I’m wrong but am I correct you developed your own standard of communicating over can to control switches and relays or is it a standard? If it’s something you developed yourself this might make it more difficult to get the binding accepted to be included in the distribution. In that case you can always add it to the Eclipse Marketplace. If it’s a standard just ignore this comment.
Secondly develop you binding on a branch on Github and not on your master. If you are going to submit it as a pull request you then can’t use the master as long as that pull request remains open. It’s general good practice to work on a branch.

Hi,

perfect, thanks a lot! I am clear on how to do it technically, just was checking on the direction itself, what would be best. I can work with the original author, but given he did not accept my own change of just using maven, not sure he would accept it in his tree. I can perhaps just continue my own fork then. I can then fix the problems you mention like output to stdout and separation of serial and canbus logic.

Yes, you are correct re the standard, it is my own. Do you know whom should I run it by to see if it will be accepted then? I found CanOpen too wide, got inspired later on by VSCP, but eventually figured that to save the CAN traffic, I did my own, even simpler protocol (I tried to minimize the CPU up time of the PIC chips to a bare miminum, since I am feeding 5V over the line and switches are “up” only during CAN send, otherwise in sleep mode not “eating” more than 3uA).

Re git - I know, I did not create new feature branch yet since as per guidelines I should try to match the issue ID, but I have not raised an issue yet since I am not super clear on these technicalities. For now I just keep amending 1 commit on my own fork’s master, but will obviously create a new branch before the actual PR. Just wanted to have the WIP code sitting somewhere outside of my PC :slight_smile:

Thanks a lot!

The approach you mention sound like a good plan. In case you need some help with the serial part in openHAB just tag me here. I’ve written that part in the DSMR binding.

The person who can give the definite answer on if your binding with your custom protocol is accepted to be merged in the openhab2-addons project is @Kai Kreuzer. I’ve tagged him know so hopefully he’ll find some time to provide you with an answer.

Regarding git. It’s not a must to create an issue first, you can submit a pr without one (At least that is what I did :slightly_smiling_face:).

Great, thanks a lot! By looking more into the actual logic I think I will write it myself using serial support in openHab already. I do not really need all the logic from the developer’s library anyway, the basics are fairly simple. It would just become tight to this USBTin device then most likely.

And while you offered help:) You may save me some time in digging into this. I am trying very similar approach as you in DSMR since it is from nutshell very similar usecase. One thing I can’t get working now is the autodiscovery of the bridge itself. I did add

<context>serial-port</context>

into my bridge configuration, yet when I debug it, there are no identifiers returned by serialPortManager.getIdentifiers() . What is the trick to get openHAB to show up a list of ports? A text/config file somewhere? I can obviously go the path of not discovering the bridge and forcing the user to select the port, but I like this approach of smooth discovery of bridges even too :slight_smile:

You probably need to pass the ports to the jvm instance that starts openHAB. See: https://www.openhab.org/docs/administration/serial.html

Thanks. That + actually adding the rxtx plugin at runtime did the trick.

OK, I think I have majority of the code done. Did a generic CAN device support in the binding in the end, then USBTin itself, then my own protocol, now also in my own branch :slight_smile: https://github.com/PoJD/openhab2-addons/commit/f48ff1ef16ae6c3b76c35d4da88ce9fbb9a8bd87

So I just need to finish linkage back from the device to openHAB framework (traffic on CANBUS to be translated to switches changes in openHAB). Then probably some scheduler to regularly check both openHAB and the actual relay devices on CANBUS are in sync. Then tests and documentation (I know I should have followed TDD, but I was so eager to make it work this weekend:) ).

So I basically have just one q - how do I somehow notify the framework that a handle command failed? E.g. when handling the command that eventually gets translated to sending a CANMessage and that failed. What to do then? Ideally I would like to tell the framework somehow that it failed - ideally perhaps even the user would see that somehow in UI. Sometimes I could find out about a failure a bit later (the CANBUS device can send errors later), then would probably need the same - perhaps find the last command handled and revert it…

I can always somehow make it work, but perhaps there is some “best” way. Not that I expect this to fail too much, but stability is surely in my mind since I plan to use this in my new house to control the lights! :slight_smile:

OK, nevermind, figured it out. Simply scheduled a reverting post command after some timeout.

Ok, just raised a PR here: https://github.com/openhab/openhab2-addons/pull/4297
Thanks for all your help!