Home Theater Macro: Global Cache iTach

(Neel) #1


I am writing a device handler that allows me to control all my home theater devices. For example, when I turn off the home theater, it should turn off the the projector, and the cable box using Global Cache iTach. For some reason, there is an 8 second delay from the time the SmartThings runIn scheduler fires and the time the iTach responds with a parse() callback. This lag time is causing all sorts of problems since the commands need to fire within a certain time period of each other.

I am using the sendhubcommand() using the LAN protocol. I posted the code, the heart of the code is the RunItachCommand() at the bottom:

def ShutdownSystem()

state.commandqueue = 	[
							[function: "RunMarantzCommand", commandText: "cmd0=PutZone_OnOff%2FOFF", host: "", port: "80"],
							[function: "RunItachCommand", commandText: "sendir,1:1,1,38000,1,1,8,34,8,66,8,29,8,109,8,50,8,50,8,45,8,103,8,497,8,34,8,29,8,29,8,29,8,29,8,109,8,29,8,29,8,3810", host: "", port: "4998"],    
							[function: "RunItachCommand", commandText: "sendir,1:3,1,38000,1,1,342,170,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,63,22,63,22,20,22,20,22,20,22,63,22,63,22,63,22,20,22,20,22,63,22,20,22,63,22,20,22,20,22,20,22,63,22,63,22,20,22,63,22,1738", host: "", port: "4998"],
							[function: "RunItachCommand", commandText: "sendir,1:3,1,38000,1,1,342,170,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,20,22,63,22,63,22,20,22,20,22,20,22,63,22,63,22,63,22,20,22,20,22,63,22,20,22,63,22,20,22,20,22,20,22,63,22,63,22,20,22,63,22,1738", host: "", port: "4998"]    
state.commandqueueindex = 0;
runIn(0, ExecuteCommandHandler, [overwrite: false])
runIn(0, ExecuteCommandHandler, [overwrite: false])
runIn(1, ExecuteCommandHandler, [overwrite: false])
runIn(2, ExecuteCommandHandler, [overwrite: false])


def ExecuteCommandHandler()
if(state.commandqueueindex < state.commandqueue.size())
def function = state.commandqueue[state.commandqueueindex].function;
def commandText = state.commandqueue[state.commandqueueindex].commandText;
def host = state.commandqueue[state.commandqueueindex].host;
def port = state.commandqueue[state.commandqueueindex].port;

	// log.debug(commandText);
	"$function"(commandText, host, port);

	state.commandqueueindex = state.commandqueueindex + 1;
	log.debug("ExecuteComandHandler duplicate run.")


private def RunItachCommand(commandText, networkIP, networkPort)
def hosthex = convertIPtoHex(networkIP);
def porthex = convertPortToHex(networkPort);
device.deviceNetworkId = “$hosthex:$porthex”;

def hubAction = new physicalgraph.device.HubAction("""$commandText\r\n""", physicalgraph.device.Protocol.LAN, "$device.deviceNetworkId");

return sendHubCommand(hubAction);



Tagging @scottinpollock since he has done a lot with Global Cache And might have something to add.

(Neel) #3

Thanks @JDRoberts. Also calling on @Mike_Maxwell. I’m wondering what your iTach lag times are from the time you send the hub command and get a parsed response.

(Convinced ST will never be unbroken…) #4

I got really nothing regarding this method. I simply send HAM Bridge an http GET using the SmartThings sendHubCommand. HAM Bridge then executes Python scripts to send command sequences to the iTachs.

Timing can be critical with IR commands and this just seems to be way too much a PITA from within a DTH.

(Neel) #5

Hello, I have not used HAM Bridge. From reading a blurb about it, what is the benefit of having SmartThings call HAM Bridge? At that point is it possible to just have Alexa call HAM Bridge and make HAM Bridge your hub?

(Neel) #6

On second thought, I see the value in the SmartThings hub. It’s for sending ZigBee and zwave signals. I’ll avoid using the hub for non-zwave and zigbee commands.

(Neel) #7

Hello, I figured out how to do everything with SmartThings and Global Cache.

1.) SmartThings has a function to send hub commands that allows you to set delay in milliseconds. It is much more reliable and useful than the runIn function. SendHubCommand(actions, 100) where actions is a list of HubActions and 100 would represent 100 millisecond delays between each HubAction in the actions list. It is more useful than runIn because runIn takes a parameter in seconds.

2.) The HubAction command has 3 ways of getting called. Two of the methods are for sending LAN commands. These two command has a bug in it: the LAN commands ignore whatever value I pass in for the device network id. Instead it will always use the device network id of the device itself. Fortunately, the third way of creating a HubAction allows you to set the network id and port. The network and port should not be converted to Hex. Below is the code, notice that this way of calling the function can send LAN requests since I deleted the other MapParams for method and path.

new physicalgraph.device.HubAction(
‘body’: “$commandText\r\n”,
‘headers’: [ HOST: “$networkIP:$networkPort” ]

3.) For powering off the projector, you will need to call the power on button twice with a predefined delay. This can be accomplished by concatenating the projector on code together twice. Just make sure to increase the numerical value at the end of the first projector on code to whatever milliseconds you need.

After making these changes, all the code works flawlessly with just the SmartThings hub and Global Cache Itach IP2IR! I can even power off my home theater lights using zwave send events and a custom SmartApp.