Harmony / Eventghost

One of my goals is to have my harmony remote control smartthings. Since Harmony won’t release the API, I’ve been thinking of other ways to accomplish this. I have an idea that might work, but I wanted to see if anyone else has tried this before.

I was thinking of setting up a laptop with eventghost (and a flirc IR receiver) and creating a Smartthings activity on the harmony. Then when eventghost receives a command from the remote, have it connect via http to a REST url.

In my head, this will work, but I have never used eventghost and am basing my ideas off of what I have read about eventghost online. Has anyone else tried this?

I can verify that this does work. I have the same setup currently (with a MCE IR receiver instead of a flirc) with my Harmony One remote.

If you would want to go one step further, this IR receiver can also be used as a repeater via EventGhost and some IR emitters, so you can control your home theater with Smartthings.

Then you just have to setup a custom device type to tie it all together with Eventghost.

Sweet - I’m going to order those and set this up! Would you mind sharing your app code with me?

Also note - there are some efforts internally to get Logitech integrated. Still would love to see what you come up with!

1 Like

@kylefitzgerald - yeah, I’ll write up some instructions hopefully later on tonight.

@ben_edwards - that’s awesome news! My current Logitech integration is a bit hacked together but it does work. Excited to see how ST can polish it up.

@nelemansc if you would post them on here, I’m thinking about doing the same thing.

These instructions are to get the Logitech remote to talk to SmartThings.

EventGhost MCE IR Receiver Setup

make sure the MCE receiver is plugged in before proceeding with the MCE IR setup

  1. Install EventGhost
  2. Install Microsoft MCE Remote - Vista/Win 7 plugin
  3. Click on “Install Service” from within the plugin configuration page

Harmony Remote Setup

  1. Setup your Logitech Harmony remote with a new device in the Logitech Harmony Remote Software (Device Type > Computer > Media Center PC. Manufacturer > Microsoft. Model > MicrosoftMCE Keyboard)
  2. Find a button you would like to map for your SmartThings command and press it while aiming it at the MCE IR Receiver, you should see it displayed in the log on the left side of EventGhost. This should have a lightning bolt icon next to it and it will be your EventGhost “Event” that will trigger an EventGhost “Action”.
  3. Right click on the right side of EventGhost and select the option for “Add Macro”.
  4. Expand the tree for EventGhost and select Python Script.
    python_script
  5. For the python script, the syntax for the Rest url string is
import urllib; urllib.urlopen('https://graph.api.smartthings.com/api/smartapps/installations/xxxxxx/switches/xxxxxxxxxxxx/on?access_token=xxxxxxxxx')

The REST URL will come from setting up a Rest Endpoint Smartapp. So for example, say you have a switch setup in the endpoint example that you would want to turn on from your Harmony remote, right click the “on” button and select Copy Link Address. This URL is what you would put into the Python script.

Click Save/Apply for the Python script.
6. Drag the EventGhost Event of the button press from the log on the left over to the appropriate Macro folder on the right. Now whenever you press the specific button on the Harmony remote, the Python script will be executed causing your light to turn on.

Sorry for this being a bit wordy, hard to explain tying it in with EventGhost. Check out the EventGhost tutorial to get a better understanding on how everything works, it’s pretty powerful when you start to play around with it.

2 Likes

Thanks for the post, @nelemansc.

I saw your instructions for how to set up SmartThings to receive commands from an IR receiver. Would you be able to post instructions on how you set SmartThings to send IR commands? It would be greatly appreciated.

Thanks!

@Johnny_Davy I will try and get some instructions put together later this week. FYI - there are a few parts to make it all work.

Requirements:

@nelemansc

Hey there… I am using HAMBridge to send IR from SmartThings, but I would like to see your home theatre device type. Is that online somewhere?

@scottinpollock Yup, here it is. I have my WAN IP, username/password, and port all hard-coded

metadata {

	definition (name: "Home Theater Control", author: "nelemansc@gmail.com") {
		capability "Polling"
		capability "Button"
		capability "Switch"
		capability "Refresh"

		command "volUp"
		command "volDown"
		command "Input4"
		command "Input5"
		command "Input6"
		command "mute"
		command "unmute"
	}

    tiles {
        standardTile("power", "device.switch", width: 2, height: 2) {
            state "off", label: 'Off', action: "switch.on", icon: "st.Electronics.electronics18", backgroundColor: "#ffffff", nextState: "on"
            state "on", label: 'On', action: "switch.off", icon: "st.Electronics.electronics18", backgroundColor: "#79b821", nextState: "off"
        }
		standardTile("muteSwitch", "device.switch", canChangeIcon: true) {
			state "mute", label: 'Mute', action: "mute", icon: "st.alarm.beep.beep", backgroundColor: "#ffffff", nextState: "unmute"
			state "unmute", label: '', action: "unmute", icon: "st.secondary.off", backgroundColor: "#79b821", nextState: "mute"
		}
        standardTile("lUp", "device.button", inactiveLabel: false,decoration: "flat", canChangeIcon: false) {
            state "up", label:'Volume Up', action:"volUp",icon:"st.thermostat.thermostat-up"
        }
		standardTile("lDown", "device.button", inactiveLabel: false,decoration: "flat", canChangeIcon: false) {
            state "down", label:'Volume Down', action:"volDown",icon:"st.thermostat.thermostat-down"
        }
        standardTile("Input4", "device.button", inactiveLabel: false,decoration: "flat", canChangeIcon: false) {
            state "Input4", label:'Xbox One', action:"Input4",icon:"st.Electronics.electronics5"
        }
		standardTile("Input5", "device.button", inactiveLabel: false,decoration: "flat", canChangeIcon: false) {
            state "Input5", label:'XBMC', action:"Input5",icon:"st.Entertainment.entertainment1"
        }
		standardTile("Input6", "device.button", inactiveLabel: false,decoration: "flat", canChangeIcon: false) {
            state "Input6", label:'TV', action:"Input6",icon:"st.Electronics.electronics15"
        }
		main(["power"])
        details(["power", "lUp", "lDown", "Input6", "Input5", "Input4", "muteSwitch"])
    }
}

// parse events into attributes


// handle commands
def on() {
	log.debug "Executing 'on'"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?pwrOn"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}

def off() {
	log.debug "Executing 'off'"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?pwrOff"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}
def mute() {
	log.debug "Muting the audio"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?muteOn"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}

def unmute() {
	log.debug "Unmuting the audio"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?muteOff"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}
def volUp() {
	log.debug "Turning up volume"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?volup"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}
def volDown() {
	log.debug "Turning down volume"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?voldown"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}
def Input4() {
	log.debug "Changing input to 'Input 4'"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?Input4"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}
def Input5() {
	log.debug "Changing input to 'Input 5'"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?Input5"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}
def Input6() {
	log.debug "Changing input to 'Input 6'"
    def url = "http://username:password@Enter.WAN.IP.Here:Port/index.html?Input6"
    httpGet(url) { 
        response -> 
        if (response.status != 200 ) {
            log.debug "Eventghost webserver failed, status = ${response.status}"
        }
    }
}

What are you using to emit the IR signal from your Mac?

Thanks! Do you really use this outside of your LAN? Pretty sure you could do this all locally with hubAction (if you wanted to).

Global Cache iTach IP2IR

I have rarely used it outside of my LAN, other than the occasional troubleshooting of the HTPC setup for the gf when I’m not at home. I haven’t looked into using hubAction at all, but it could be nice to close off the port.

Does the Global Cache iTach IP2IR offer anything as far as IR signal confirmation? One issue I have encountered for instance is sending the “TV Power Off” signal when the Good Night mode is triggered, but the TV never successfully powers off even though the device type shows it as off.

This is a problem with IR (no feedback). The iTach can only tell you if “it” received the command successfully. But their API gives you amazing control over the codes. For discrete commands like “off” and “on” I usually send 3 repeats. In one case (the TV/Sat input on a pioneer pre/pro) I had to bump the repeat up to 5. You can also set the spacing on the repeats, and they have a number of apps that can be used with it to learn and test codes, as well as translating them to/from Global Cache native format to HEX or Pronto formats. You can find their API here.

I really like these devices, and the IP2IR and WF2IR (as well as their serial and contact counterparts) support multiple simultaneous connections so I can use them with the Mac and multiple handsets running iRule, MBH Remote, or other software capable of sending a TCP stream.

@nelemansc

Ok… I can clean up your device-type to be local. Give me a few hours; gonna go grab some lunch and check out HomeDepot for GE Link (just for grins).

@scottinpollock

Awesome, thanks! I’m debating snagging a few GE Link bulbs as well and possibly the Wink Hub if the “Buy 2 Wink products, get the Wink Hub for $0.01” deal works for the GE Link.

@nelemansc

Here is a mini version of your device with the local code and cleaned up command structure. You’ll need to add your “user:passwd@” to what’s returned from the getHostAddress() function. Its working here with HAM Bridge.

metadata {

	definition (name: "Home Theater Control", author: "nelemansc@gmail.com") {
		capability "Polling"
		capability "Button"
		capability "Switch"
		capability "Refresh"

		command "on"
		command "off"
	}

    tiles {
        standardTile("power", "device.switch", width: 2, height: 2) {
            state "off", label: 'Off', action: "switch.on", icon: "st.Electronics.electronics18", backgroundColor: "#ffffff", nextState: "on"
            state "on", label: 'On', action: "switch.off", icon: "st.Electronics.electronics18", backgroundColor: "#79b821", nextState: "off"
        }
	
		main(["power"])
        details(["power"])
    }
}

// parse events into attributes
def parse(String description) {
    def map = [:]
    def retResult = []
    def descMap = parseDescriptionAsMap(description)
    def body = new String(descMap["body"].decodeBase64())
	log.debug body
}

// define commands
def on() {
	log.debug "Executing 'on'"
    getapi("/index.html?pwrOn")
}

def off() {
	log.debug "Executing 'off'"
    getapi("/index.html?pwrOff")
}

private getapi(thePARAMS) {
  log.debug("Executing get api to " + getHostAddress())
  def uri = thePARAMS
  def hubAction = new physicalgraph.device.HubAction(
    method: "GET",
    path: uri,
    headers: [HOST:getHostAddress()]
  )
  hubAction
}

private Integer convertHexToInt(hex) {
	Integer.parseInt(hex,16)
}
private String convertHexToIP(hex) {
	[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
}

private getHostAddress() {
	def parts = device.deviceNetworkId.split(":")
	def ip = convertHexToIP(parts[0])
	def port = convertHexToInt(parts[1])
	//return user + ":" + pswd + "@"+ ip + ":" + port
    return ip + ":" + port

}

def parseDescriptionAsMap(description) {
	description.split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
		map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
	}
}

@nelemansc, I know this is an older thread but I just setup my older Harmony 700 remote to toggle some lights. It works great. Now those colored buttons serve a purpose. Thank you for the detailed instructions on how to set this up. My wife loves being able to control the lights from the remote. I loved not having to spend lots of $ setting it up.

1 Like

So, I’ve just gotten Eventghost up and running (so I can put my son’s PC to sleep at his bedtime, lol)

I was wondering…I would love to have a piston that tells my Harmony Hub to skip forward 6 times (3 minutes ovreall) to skip over commercial breaks. Is there a way to send this command to the Hub through Eventghost? I figured I’d set up a switch in Alexa called SKIP COMMERCIAL that would activate a Piston in Webcore to send the IR command. Anyone know how to do this?

@tgauchat, do you know if this is possible?

Check out KuKu Harmony and WebCoRE.