Onkyo Receiver Custom Driver

The only other thing I have to offer is the link I posted mentioned:

Replace variables beginning with data with device.data

So perhaps replace def data = msg.data with def data = msg.device.data
Other than that, I see that @mike.maxwell has responded so perhaps he will find it if it's not this or the tiles section.

I hope my reference to you in the comments section is enough. If not feel free to provide any suggestions on how to appropriately reference your work. Thanks!

1 Like

I started dinking with my original code in Hubitat over a year ago, and haven't had time to mess with it since.
The good news is that we have a telnet interface, which allows the onkyo to send status updates to the driver without being polled.
The bad news is that the telnet interface isn't well documented yet and I've done nothing more with the driver since getting telnet running on it.
I'll install the driver tomorrow, if it works I'll probably have some info for you.

1 Like

It is, and appreciated!

Other than the clutter the tiles section induces, it will do no harm as we just ignore it. From a sharing and clarity standpoint in hubitats forums its a nice section to remove as drivers are confusing enough for new folks, even without that section...

1 Like

Thanks for the clarification @mike.maxwell
I was going on this post in the App and driver porting to Hubitat topic:

1 Like

Thanks for the recommendations to clean up the Hubitat version of the code. I've updated the code in my original insert above with extraneous sections (e.g. tiles) removed.

Unsolicited onkyo data comming in via our telnet implementation into a telnet enabled driver.
I'll post up some info when I'm able to poke some commands to it. The driver telnet session is connected to the onkyo eiscp port.

3 Likes

Curious if you've had any luck submitting commands via the hub. Thanks!

Curious if anyone has gotten the Onkyo receivers working yet with Hubitat and what specifically you can do with this connection besides turn on or off the receiver? Thanks.

I'd be curious too. I use an Onkyo 555.

I'm wondering if it might allow for a universal "play/pause" command, which could then be used to dim lights. I've fooled around with connecting my Sony TV in the past using some Kodi integration. It worked when I was playing videos from Kodi, but obviously couldn't work if I was using Netflix. I wonder if going directly through the Onkyo receiver would work.

I also have a Remotec remote attached to the wall next to the couch. This can control various lights in the room, and in the past I've had four buttons control Play/pause/forward/backward when using Kodi. This is just for convenience, but it's an example of something else you might do with a connected theater system.

1 Like

If you use onkyo's EISCP protocol which works with our telnet capability, you can do anything the device supports, on,off, mute, read and set volume, change inputs, the lot.
Also when you use telnet, any changes made to the receiver via IR or physical interaction are sent over the telnet connection...

1 Like

Should they also be cautious about multiple telnet connections? Is this confirmed an issue until the fix coming soon (tomorrow?)

Multiple telnet connections (1 from each device) isn't an issue, I have three of them running 24/7
2 for two separate Lutron Pro bridges, and then one for the Onkyo...
Attempting to run multiple telnet connections from the same driver, due to an incorrect implementation?, sure, I can't imagine that would go over well...

1 Like

I noticed the new Onkyo's are advertised on the Onkyo website to have Sonos integration. Looks like if they detect input from a sonos play, they turn themselves on, set the input, and volume to a configured volume so that you can use the Sonos app to control volume! Im thinking about picking up a TX-RZ830

Mike could you please provide an example? I would love to integrate HE with my Denon receiver that also supports a telnet interface. I got it to work in the past via HTTP but I had to poll the receiver for updates.

Does the Dennon support telnet?

I finally got a driver for my Onkyo receiver working! I have a couple of receivers in my house, so one thing I need to figure out is how to set the IP address of each device dynamically. I added an IP preference, but it only shows up in one of the devices I create.

In the second one it's not showing up.

Is there another way, without creating two DTH's, to reuse the same DTH for multiple devices while setting the IP separately for each device?

/**
 *  Onkyo IP Control Device Type for Hubitat
 *  Carson Dallum (@cdallum)
 *  Originally based on: Mike Maxwell's and Allan Klein's code
 *
 *  Usage:
 *  1. Be sure you have enabled control of the receiver via the network under the settings on your receiver.
 *  2. Add this code as a device handler in the Hubitat Drivers Code section
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 * Some future commands that might be useful to incorporate reading:
 * Power Status: PWRQSTN
 * Input Selected: SLIQSTN
 * Volume Level: MVLQSTN (value in hex)
 * Artist Name: NATQSTN
 * Track Name: NTIQSTN
 * Zone 2 Mute: ZMTQSTN
 * Zone 2 Volume: ZVLQSTN
 * Zone 2 Input Selected: SLZQSTN
 * ISCP commands were found at https://github.com/miracle2k/onkyo-eiscp/blob/master/eiscp-commands.yaml
 */

metadata {
	definition (name: "Onkyo Receiver (Family Room)", namespace: "cdallum", author: "Carson Dallum") {
	capability "Initialize"
    capability "Telnet"
    capability "Switch"
	command "cable"
	command "stb"
	command "pc"
	}
    main "switch"
    details(["switch","cable","stb","pc"])
}

def on() {
	log.debug "Powering on receiver"
	sendEvent(name: "switch", value: "on")
	def msg = getEiscpMessage("PWR01")
    return new hubitat.device.HubAction(msg,hubitat.device.Protocol.TELNET)
}

def off() {
	log.debug "Powering off receiver"
	sendEvent(name: "switch", value: "off")
	def msg = getEiscpMessage("PWR00")
    return new hubitat.device.HubAction(msg,hubitat.device.Protocol.TELNET)
}

def cable() {
	log.debug "Setting input to Cable"
	def msg = getEiscpMessage("SLI01")
	return new hubitat.device.HubAction(msg,hubitat.device.Protocol.TELNET)
}

def stb() {
	log.debug "Setting input to STB"
	def msg = getEiscpMessage("SLI02")
	return new hubitat.device.HubAction(msg,hubitat.device.Protocol.TELNET)
}

def pc() {
	log.debug "Setting input to PC"
	def msg = getEiscpMessage("SLI05")
	return new hubitat.device.HubAction(msg,hubitat.device.Protocol.TELNET)
}

/* This is where I construct the entire message character by character. Each char is represented by a 2 disgit hex value */
def getEiscpMessage(command){
	def sb = StringBuilder.newInstance()
	def eiscpDataSize = command.length() + 3  // this is the eISCP data size
	def eiscpMsgSize = eiscpDataSize + 1 + 16  // this is the size of the entire eISCP msg
    
	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)
	// Changing eiscpMsgSize to eiscpDataSize for testing
	sb.append((char)Integer.parseInt(Integer.toHexString(eiscpDataSize), 16))
	//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 your receiver
	// my NR5008 works when I use  'EOF'
	//OD is CR
	//0A is LF
	/*
	[CR]			Carriage Return					ASCII Code 0x0D			
	[LF]			Line Feed						ASCII Code 0x0A			
	[EOF]			End of File						ASCII Code 0x1A			
	*/
	//works with cr or crlf
	sb.append((char)Integer.parseInt("0D", 16)) //cr

	return sb.toString()
}

// General App Events
def initialize(){
	telnetConnect("192.168.1.xxx", 60128, null, null)
	log.debug "Opening telnet connection"
}

def installed(){
	initialize()
}

def updated(){
	initialize()
}

Couple of items on this.
telnet should include capability "Initialize"
Then move all the telnetConnect code into def initialize(){telnetconnect here...}, I'm surprised it even runs where you currently have it, pauseExecution isn't required.
Initialize is called when the hub starts up, if you then include initialize within updated, then any ip changes will restart telnet.
telnetClose should be removed as it's not needed, you want the connection open all the time.

The parse method code isn't doing anything, you can remove all of it as these aren't lan messages, first place to start with that is to dump the output and see whats coming back.

You will need a separate driver for each device you have.

Yes I can open a Telnet connection to my Denon receiver. Could you please provide a telnet example in the public repo?