Telnet not getting data to parse

I've been trying to get the tcp/telnet function to create a connection to a kodi box so that I can monitor notifications. This should be really simple stuff, all it should be is open port 9090 (default) on the correct IP .. and that's it. Listen and let parse() display output.

I've used Envisalink code from @doug as a base (as it's performance is rock solid for my envisalink connection) and cut it down to it's most basic parts to start with. The connection get established, and I can successfully even sendMsg to the kodi box from my driver, but I never see any responses.

I can use PuTTY from multiple PC's at the same time, and open a basic telnet connection .. and they all receive the notifications from the kodi box, including notifications from the messages I send in my driver, but the hubitat driver never gets anything to parse.

I'm completely at a loss as to what I'm doing wrong. Here's the driver code:

public static String version() { return "v0.0.1" }
public static boolean isDebug() { return true }

import groovy.transform.Field

metadata {
definition (name: "KodiTCP", namespace: "hamsando", author: "Putch") {
capability "Initialize"
capability "Telnet"
capability "Actuator"
command "sendMsg", ["String"]
command "scan"

preferences {
input("ip", "text", title: "IP Address", description: "ip", required: true)

//general handlers
def installed() {
log.warn "installed..."

def updated() {
ifDebug("Configuring IP: ${ip}")

def initialize() {
try {
//open telnet connection
telnetConnect(ip, 9090, null, null)
//give it a chance to start
ifDebug("Telnet connection to Kodi established")
} catch(e) {
log.warn "initialize error: ${e.message}"

def uninstalled() {

private parse(String message) {
ifDebug("Parsing Incoming message: " + message)

def scan() {

def sendMsg(String s) {
ifDebug("sendMsg $s")
return new hubitat.device.HubAction(s, hubitat.device.Protocol.TELNET)
//sendHubCommand(new hubitat.device.HubAction(s, hubitat.device.Protocol.TELNET))

def getReTry(Boolean inc){
def reTry = (state.reTryCount ?: 0).toInteger()
if (inc) reTry++
state.reTryCount = reTry
return reTry

def telnetStatus(String status){
log.warn "telnetStatus- error: ${status}"
if (status != "receive error: Stream is closed"){
log.error "Telnet connection dropped..."
} else {
log.warn "Telnet is restarting..."

private ifDebug(msg)
log.debug('KODI Driver: ' + msg)

@Field static final String VIDEOSCAN = "{"jsonrpc":"2.0","method":"VideoLibrary.Scan","id":"justme"}"

Try adding the termination character. carriage return and lf to your telnetconnect.

Thanks for the quick response!
OK .. that sort of works - sort of. Unfortunately the response back from Kodi has no specific termination character.

The closest I can do is:
telnetConnect([termChars:[125]],ip, 9090, null, null)

which is "}" as the termination character. Unfortunately the response from kodi is JSON encoded, so there could be multiple "}" in data. I'll have to think about this one some more.

EDIT: FYI, I also captured the response from Kodi using wireshark, there is definitely no termination characters.

Ok not sure what you are trying to accomplish but I don't think Kodi has a telnet server running. What OS are you running Kodi on? If Kodi has a command line interface the the telnet connect might work ONLY if the OS Kodi is running on have a telnet server running.

If you are trying to talk to Kodi using their API then telnet won't work. Sound like that's what's going on because you are getting JSON data. I would check to see if someone did something for Kodi on the ST forum and use that as your starting point.

It appears Kodi support an variety of connectivity transports, however Telnet is not advertised as one of them.

I would look at using HTTP or WebSockets with Hubitat, if the ST Integration that @cuboy29 posted above does not work out.

I've seen some of the Kodi ST projects - and did consider porting however they either rely on polling to get status (not a fan) or installing other addons in Kodi to provide the status updates.

The HTTP interface provided by Kodi does not provide any method for notifications back to HE without installation of other Kodi addons.

The Websockets interface is an option. I'll need to read up on how to implement in HE.

Kodi also has a raw TCP interface. A simple client connecting to it, gets notifications as raw JSON and can also send commands (in JSON) over the same pipe (hence my comment about using PuTTY as a simple method of testing it out, I also have a windows TCP client I wrote previously which works on that TCP connections too).

The HE Telnet implementation is, from all appearances, just a basic TCP client, and it does largely work that way (and was easy to implement based on existing code examples). I can successfully pipe commands through it to the Kodi box using simple JSON and the kodi box does what the instructions say, I also get the responses and notifications from the Kodi box (once I added a termination character). The only problem is that in my case, there is no actual termination character, so in making '}' the termination character I do run the risk of losing some if the incoming data.

Ideally, the TCP/Telnet connection on HE would have a timeout on the incoming buffer so that in the absence of a termination character, after say 1/2 second of no incoming data, it passes data to parse().

Anyway, I appreciate the responses and help and will look into either (a) hacking something with the TCP/Telnet and termination character or (b) figuring out the HE websocket implementation

You can take a look at my Logitech Harmony Hub Driver which uses webSockets. It is really pretty easy once you see a working example, I can't promise you that it is the prettiest code...but it has been working for many users for months now without any issues. You should be able to reuse your JSON packing and unpacking routines, In many ways, it is very similar to the Hubitat Telnet model.

Good luck and have fun!