Post date: Nov 2, 2011 4:45:41 AM
Onkyo's protocol doc is attached to this post below in the attachments section. This doc is version 1.21 dated 2011, I just got it from my dealer (Crutchfield.ca), great support! It appears to be newer than any other floating around the net and specifically references the 3008 and 5008 models.
There are a few implementations that are floating around the internet - the one I found most useful was a python implementation at https://github.com/compbrain/Onkyo-TX-NR708-Control. It worked but was minimal, plus I wanted to wrap eISCP in a Java class that was robust and extendable.
I wrote a simple java class that I plan to continue to expand its functionality:
My Eiscp.java file is attached to this post below in the attachments section
Things I still want to update:
While I was implementing the eISCP message packet I found some things that were unclear in the Onkyo protocol document. Specifically the data size part of the message - is actually the size of the entire message, not just the data part. See my comments in the code for details.
Here is my code for the method that forms the data message. (full class is attached below)
getEiscpMessage Method
/**
* Wraps a command in a eiscp data message (data characters).
*
* @param command must be one of the Strings from the eiscp.Eiscp.Command class.
**/
public StringBuilder getEiscpMessage(String command)
{
StringBuilder sb = new StringBuilder();
int eiscpDataSize = command.length() + 2 ; // this is the eISCP data size
int eiscpMsgSize = eiscpDataSize + 1 + 16 ; // this is the size of the entire eISCP msg
/* This is where I construct the entire message
character by character. Each char is represented by a 2 disgit hex value */
sb.append("ISCP");
// the following are all in HEX representing one char
// 4 char Big Endian Header
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("10", 16));
// 4 char Big Endian data size
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("00", 16));
// the official ISCP docs say this is supposed to be just the data size (eiscpDataSize)
// ** BUT **
// It only works if you send the size of the entire Message size (eiscpMsgSize)
sb.append((char)Integer.parseInt(Integer.toHexString(eiscpMsgSize), 16));
// eiscp_version = "01";
sb.append((char)Integer.parseInt("01", 16));
// 3 chars reserved = "00"+"00"+"00";
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("00", 16));
sb.append((char)Integer.parseInt("00", 16));
// eISCP data
// Start Character
sb.append("!");
// eISCP data - unittype char '1' is receiver
sb.append("1");
// eISCP data - 3 char command and param ie PWR01
sb.append( command);
// msg end - this can be a few different cahrs depending on you receiver
// my NR5008 works when I use 'EOF'
sb.append((char)Integer.parseInt("0D", 16));
System.out.println("eISCP data size: "+eiscpDataSize +"(0x"+Integer.toHexString(eiscpDataSize) +") chars");
System.out.println("eISCP msg size: "+sb.length() +"(0x"+Integer.toHexString(sb.length()) +") chars");
return sb;
}
You can take and use the code as per the GNU license.
Have fun! and check back, I will continue to extend this until I have a full remote app.
Stay tuned, I also want to test this through the Networking module of the Universal Devices ISY-99i home controller.