How I control my Harmony Hub with an $8 remote

I’m using a GE universal remote with a Flirc IR receiver to control my Harmony Hub activities and devices with a Python_Script integration. It works GREAT!!

coniguration.yaml (snippet):

##########################
# flirc remote keyboard
##########################
keyboard_remote:
#- device_descriptor: '/dev/input/event3'
  device_name: 'flirc.tv flirc Keyboard'
  type: 'key_up'

coniguration.yaml (snippet):

##########################
# harmony hub
##########################
remote:
  - platform: harmony
    name: HUB@3911 Master Bedroom
    host: 192.168.0.180

coniguration.yaml (snippet):

##########################
# default integrations
##########################
python_script:

automations.yaml (snippet):

- alias: Remote Key Pressed
  id: '1571938694985'
  description: ''
  trigger:
  - event_data: {}
    event_type: keyboard_remote_command_received
    platform: event
  condition: []
  action:
    - service: python_script.control_hub
      data_template:
        entity_id: 'remote.hub_3911_master_bedroom'
        key_code: '{{ trigger.event.data.key_code }}'
        current_activity: "{{ state_attr('remote.hub_3911_master_bedroom', 'current_activity') }}"
        log_level: 'warn'

service: python_script.control_hub:

'''
Get Harmony Hub Command
'''

########################
# Parameters
########################
entity = data.get('entity_id', "remote.hub_3911_master_bedroom")
activity = data.get('current_activity')
key = data.get('key_code')
loglevel = data.get('log_level', 'warn')

indent="     "
logs = {'warn': logger.warn}
logger = logs[loglevel]

########################
# keyMap for Flirc 'keyboard_remote_command_received' event key_codes
########################
keyMap = {
   "1" : "1",
   "2" : "2",
   "3" : "3",
   "4" : "4",
   "5" : "5",
   "6" : "6",
   "7" : "7",
   "8" : "8",
   "9" : "9",
   "10": "0",
   "11": ".",
   "12": "enter",
   "13": "input",
   "20": "<<",
   "21": "<>",
   "22": "><",
   "23": ">>",
   "24": "rec",
   "25": "stop",
   "26": "eject",
   "30": "up",
   "31": "down",
   "32": "left",
   "33": "right",
   "34": "ok",
   "35": "list",
   "36": "menu",
   "37": "guide",
   "38": "back",
   "50": "media1",
   "51": "media2",
   "52": "media3",
   "53": "media4",
   "60": "vol+",
   "61": "vol-",
   "62": "chan+",
   "63": "chan-",
   "64": "chan<",
   "65": "mute"
}

########################
# hubCommands
########################
hubCommands = {
  'Watch DirecTV': {
    "vol+" : {"device": "Sonos PLAYBAR", "command": "VolumeUp"},
    "vol-" : {"device": "Sonos PLAYBAR", "command": "VolumeDown"},
    "mute" : {"device": "Sonos PLAYBAR", "command": "Mute"},
    "<<"   : {"device": "DirecTV Genie", "command": "Rewind"},
    "<>"   : {"device": "DirecTV Genie", "command": "Play"},
    "><"   : {"device": "DirecTV Genie", "command": "Pause"},
    ">>"   : {"device": "DirecTV Genie", "command": "FastForward"},
    "chan+": {"device": "DirecTV Genie", "command": "ChannelUp"},
    "chan+": {"device": "DirecTV Genie", "command": "ChannelUp"},
    "chan-": {"device": "DirecTV Genie", "command": "ChannelDown"},
    "chan<": {"device": "DirecTV Genie", "command": "ChannelPrev"},
    "up"   : {"device": "DirecTV Genie", "command": "DirectionUp"},
    "down" : {"device": "DirecTV Genie", "command": "DirectionDown"},
    "left" : {"device": "DirecTV Genie", "command": "DirectionLeft"},
    "right": {"device": "DirecTV Genie", "command": "DirectionRight"},
    "ok"   : {"device": "DirecTV Genie", "command": "Select"},
    "list" : {"device": "DirecTV Genie", "command": "List"},
    "menu" : {"device": "DirecTV Genie", "command": "Menu"},
    "guide": {"device": "DirecTV Genie", "command": "Guide"},
    "back" : {"device": "DirecTV Genie", "command": "Exit"},
    "num"  : {"device": "DirecTV Genie", "command": "0"},
    "."    : {"device": "DirecTV Genie", "command": "-"},
    "enter": {"device": "DirecTV Genie", "command": "enter"}
  },
  'Watch Fire TV': {
    "vol+" : {"device": "Sonos PLAYBAR", "command": "VolumeUp"},
    "vol-" : {"device": "Sonos PLAYBAR", "command": "VolumeDown"},
    "mute" : {"device": "Sonos PLAYBAR", "command": "Mute"},
    "<<"   : {"device": "Amazon Fire TV Stick", "command": "Rewind"},
    "<>"   : {"device": "Amazon Fire TV Stick", "command": "Play"},
    "><"   : {"device": "Amazon Fire TV Stick", "command": "Pause"},
    ">>"   : {"device": "Amazon Fire TV Stick", "command": "FastForward"},
    "rec"  : {"device": "Amazon Fire TV Stick", "command": "Record"},
    "stop" : {"device": "Amazon Fire TV Stick", "command": "Stop"},
    "eject": {"device": "Amazon Fire TV Stick", "command": "Red"},
    "up"   : {"device": "Amazon Fire TV Stick", "command": "DirectionUp"},
    "down" : {"device": "Amazon Fire TV Stick", "command": "DirectionDown"},
    "left" : {"device": "Amazon Fire TV Stick", "command": "DirectionLeft"},
    "right": {"device": "Amazon Fire TV Stick", "command": "DirectionRight"},
    "ok"   : {"device": "Amazon Fire TV Stick", "command": "OK"},
    "list" : {"device": "Amazon Fire TV Stick", "command": "Home"},
    "menu" : {"device": "Amazon Fire TV Stick", "command": "Menu"},
    "back" : {"device": "Amazon Fire TV Stick", "command": "Back"}
  },
  'Watch Antenna TV': {
    "vol+" : {"device": "Sonos PLAYBAR", "command": "VolumeUp"},
    "vol-" : {"device": "Sonos PLAYBAR", "command": "VolumeDown"},
    "mute" : {"device": "Sonos PLAYBAR", "command": "Mute"},
    "num"  : {"device": "Vizio TV", "command": "0"},
     "."   : {"device": "Vizio TV", "command": "-"}
 }
}

########################
# sendCommand
########################
def sendCommand(hass, logger):
  global entity, activity, key, keyMap, hubCommands, indent

  indent = '         '
  logger(indent)
  logger("######## Send Command:")

# Validate Data
  if entity is None:
    return logger(indent+"Abort: enityId is missing")
  elif activity is None:
    return logger(indent+"Abort: activityName is missing")
  elif key is None:
    return logger(indent+"Abort: keyCode is missing")
  elif keyMap.get(key) is None:
    return logger(indent+"Abort: keyMap is missing for remote key: {}".format(key))
    
# Determine service action and service data values
  service_action = 'send_command'
  service_data = {'entity_id' : entity}

  if keyMap[key] is "media1":
    service_action = 'turn_off'
  elif keyMap[key] is 'media2':
    service_action = 'turn_on'
    service_data.update({'activity': 'Watch DirecTV'})
  elif keyMap[key] is 'media3':
    service_action = 'turn_on'
    service_data.update({'activity': 'Watch Fire TV'})
  elif keyMap[key] is "media4":
    service_action = 'turn_on'
    service_data.update({'activity': 'Watch Antenna TV'})
  elif keyMap[key] is "input":
    # toggle activities
    service_action = 'turn_on'
    if activity == 'Watch DirecTV':
      service_data.update({'activity': 'Watch Fire TV'})
    elif activity == 'Watch Fire TV':            
      service_data.update({'activity': 'Watch Antenna TV'})
    else:
      service_data.update({'activity': 'Watch DirecTV'})
  elif int(key) >= 1 and int(key) <= 10 and hubCommands.get(activity,{}).get('num') is not None:
    # Numeric Key Pressed on supported device
    service_action = 'send_command'
    service_data.update(hubCommands[activity]['num'])
    service_data['command'] = key
  elif hubCommands.get(activity,{}).get(keyMap[key]) is not None:
    # Get device command
    service_action = 'send_command'
    service_data.update(hubCommands[activity][keyMap[key]])
  else:
    return logger(indent+"Abort: hubCommand is invalid for activity: '{}' or keyMap: '{}'".format(activity, keyMap[key]))

  logger(indent+"Call Service to: '{}'".format(service_data['entity_id']))
  logger(indent+"service_action: '{}'".format(service_action))
  logger(indent+"service_data: {}".format(service_data))
  hass.services.call('remote', service_action, service_data, False)
  return logger(indent+"Service Called")

########################
####### MAIN ###########
########################
logger("\n")
logger('#### Running Python_Script: "control_hub"')
logger(indent+"using input data:")
logger(indent+"entity: '{}'".format(entity))
logger(indent+"activity: '{}'".format(activity))
logger(indent+"key: '{}'".format(key))
logger(indent+"loglevel: '{}'".format(loglevel))

hass.bus.fire('control_hub_event', { "entity_id": entity, "state": "send_command", "key_code": key, "current_activity": activity })
sendCommand(hass, logger)
hass.bus.fire('control_hub_event', { "entity_id": entity, "state": "command_sent", "key_code": key, "current_activity": activity })
2 Likes