LedNet Proxy
by tgutwin
Posted on Sunday Dec 18, 2016 at 06:40PM in Programming
I want to control a LED light Strip with the 5 channel (rgbw) LEDNet controller that I bought. I want to use my own software. Thankfully others have figured out the IP messaging packet, so I wrote my own little app that lets me program/control a Strip of RGBw LEDs.
The ultimate intent is to be able to control it using My UDI ISY-994 home controller. I can actually do this already using the Network Resources plugin, BUT it is a bit slow to respond. So i want to directly control it with a Java app and have the ISY call pre-made routines in it so it functions quicker. This Java app must also be a IP listener, to respond to requests from the ISY.
Its all do-able.
Message Format
SetColour
Based on the post at the UDI Forum;
here is the messaging format for a SetColour Message; 13 Base10 chars:
- 49
- R (0-255)
- G (0-255)
- B (0-255)
- WW (0-255)
- CW (0-255) (only needed for the 5 channel model, omit for the 4 channel model)
- 0
- 15
- checkSum = sum (lowest byte ONLY) of the 1st 8 chars (or 7 chars for the 4 channel model)
- 129
- 138
- 139
- 150
NOTE: there is a 4 channel model available, that has one less char/byte in the message (and one less byte/char included in the checksum)
The associated UDI ISY-994 Network Resource string:
Red: 49;255;0;0;0;0;0;15;63;129;138;139;150
Green: 49;0;255;0;0;0;0;15;63;129;138;139;150
Blue: 49;0;0;255;0;0;0;15;63;129;138;139;150
White: 49;0;0;0;0;255;0;15;63;129;138;139;150
Cyan: 49;0;255;255;0;0;0;15;62;129;138;139;150
NOTE: that the CYAN checksum wraps to 2 bytes so only the low byte (62) is sent.
Here is the messaging format for the On/Off Message; 8 Base10 chars:
- 113
- 35 (or 36 for Off)
- 15
- checkSum = sum of the 1st 3 chars (163 for on, 164 for off)
- 129
- 138
- 139
- 150
The associated UDI ISY-994 Network Resource string:
ON: 113;35;15;163;129;138;139;150
OFF: 113;36;15;164;129;138;139;150
The detailed messages available have been documented in the ledNet_MessageSyntax.txt file.
On/Off
Here is the Java code I use to construct the message string that gets directly sent to the LedNET:
public StringBuilder getLedNetColourMessage(int r, int g, int b, int w) { String cmdStr = ""; int chkSum = r+g+b+w+49+15; if(chkSum>(4*256)) chkSum-=(4*256); else if(chkSum>(3*256)) chkSum-=(3*256); else if(chkSum>(2*256)) chkSum-=(2*256); else if(chkSum>(256)) chkSum-=(256); StringBuilder sb = new StringBuilder(); /* This is where I construct the entire message character by character. */ sb.append((char)Integer.parseInt("49", 10)); // 3 char for R G B sb.append((char)Integer.parseInt(""+r, 10)); sb.append((char)Integer.parseInt(""+g, 10)); sb.append((char)Integer.parseInt(""+b, 10)); // 1 char for Warm White (mine is not connected) sb.append((char)Integer.parseInt(""+0, 10)); // 1 char for Cold White sb.append((char)Integer.parseInt(""+w, 10)); // a zero sb.append((char)Integer.parseInt(""+0, 10)); // a 15 to end content sb.append((char)Integer.parseInt(""+15, 10)); // low byte/ char for checkSum sb.append((char)Integer.parseInt(""+chkSum, 10)); // msg end sb.append((char)Integer.parseInt(""+129, 10)); sb.append((char)Integer.parseInt(""+138, 10)); sb.append((char)Integer.parseInt(""+139, 10)); sb.append((char)Integer.parseInt(""+150, 10)); return sb; } //getLedNetColourMessage
Note: I use parseInt in case I want to use HEX values, in that case I would switch the 10 to a 16
Sending the Message
Empirically, I found the message took about 505ms to send and allow me to send another.
Here is the Java code to send the message to a a previously created ObjectOutputStream connected to the LedNet IP Socket:
public void sendColourCommand(int r, int g, int b, int w, boolean closeSocket) { StringBuilder sb = getLedNetColourMessage(r,g,b,w); boolean verbose = false; if(connectSocket()) // sets up out_ -an ObjectOutputStream already connected to the LedNet IP Socket { try { if(verbose)System.out.println(" sending "+sb.length() +" chars: "); /* out_ has already been created and connected to the LedNet IP Socket */ out_.writeBytes(sb.toString()); // <--- This is the one that works out_.flush(); if(verbose)System.out.println("sent!" ); /* now listen for the response. */ Vector <String> rv = null; rv = readQueryResponses(); } catch(IOException ioException) { ioException.printStackTrace(); } } if (closeSocket) closeSocket(); }
Thats it... now play around.
Full Java Code:
LedNet Device
Tags: isy java opensource