Sky Q box switch

Hi there - I’m new to home automation and so far I’ve got the ps4 and TV working through my raspberry pi, which is ace!

I know lights are very much available right now, but adding Sky Q boxes would be great for those of us in the UK.

You can control these through the Sky Q app, so I wonder whether something similar to the ps4 switch is possible?

I put together a quick python script to control Sky Q boxes, including minis, from my pi. It’s not pretty but it works for me. It can issue commands like power on, backup etc, change to a specific channel number. There’s a small section in the code which I use with an Alexa skill to change channel by looking up the name for the channel number.

You need to put the address of your Sky Q box in the code.

The shell command section from configuration.yaml which calls the code:

shell_command:
  cmd_skyq_channel: /usr/local/bin/skyq/skyq.py channel {{chname}}
  cmd_skyq_chno: /usr/local/bin/skyq/skyq.py chno {{chno}}
  cmd_skyq_command: /usr/local/bin/skyq/skyq.py {{command}}

Examples of calling the shell commands:

      - service: shell_command.cmd_skyq_command
        data_template:
          command: 'power'
      - service: shell_command.cmd_skyq_command
        data_template:
          command: 'backup'
      - service: shell_command.cmd_skyq_chno
        data_template:
          chno: '501'

skyq.py file contents

#!/usr/bin/env python
import sys
import socket
import math
import array
from time import sleep
host_ip = "192.168.1.100" #Sky Q box address
port = 5900

def sendcommand(host,command):
   code = getcode(command)
   cmd1 = int(math.floor(224 + (code/16)))
   cmd2 = int(code % 16)
   command1 = array.array('B', [4, 1, 0, 0, 0, 0, cmd1, cmd2]).tostring()
   command2 = array.array('B', [4, 0, 0, 0, 0, 0, cmd1, cmd2]).tostring()

   s = socket.socket()
   s.connect((host,port))  #connect to SkyQ box
   reply = s.recv(12)      #receive handshake
   s.send(reply)           #send handshake
   reply = s.recv(2)       #receive 2 bytes
   s.send(reply[0])        #send 1 byte
   reply = s.recv(4)       #receive 4 bytes
   s.send(reply[0])        #send 1 byte
   reply = s.recv(24)      #receive 24 bytes

   s.send(command1)        #send command bytes part 1
   s.send(command2)        #send command bytes part 2

   s.close()               #close connection

def getcode(cmdname):
   commands = {
      "power": 0,
      "select": 1,
      "backup": 2,
      "dismiss": 2,
      "channelup": 6,
      "channeldown": 7,
      "interactive": 8,
      "sidebar": 8,
      "help": 9,
      "services": 10,
      "search": 10,
      "tvguide": 11,
      "home": 11,
      "i": 14,
      "text": 15,
      "up": 16,
      "down": 17,
      "left": 18,
      "right": 19,
      "red": 32,
      "green": 33,
      "yellow": 34,
      "blue": 35,
      "0": 48,
      "1": 49,
      "2": 50,
      "3": 51,
      "4": 52,
      "5": 53,
      "6": 54,
      "7": 55,
      "8": 56,
      "9": 57,
      "play": 64,
      "pause": 65,
      "stop": 66,
      "record": 67,
      "fastforward": 69,
      "rewind": 71,
      "boxoffice": 240,
      "sky": 241
   }
   return commands[cmdname]

def getchannelno( channel ):
  chno = {
    'sky_news': 501,
    'sky_sports_main_event': 401,
    'sky_sports_action': 407,
    'sky_sports_arena': 408,
    'sky_sports_cricket': 404,
    'sky_sports_golf': 405
  }
  return chno[channel]

if len(sys.argv) == 1:
  print "no parameters"
  sys.exit(2)

if sys.argv[1] == "channel":
  if len(sys.argv) < 3:
    print 'USAGE:',sys.argv[0],'[<command>|channel <channel name>]'
    sys.exit(2)

  chno = getchannelno(sys.argv[2])

  sendcommand(host_ip,str(chno/100))
  sleep(0.2)
  sendcommand(host_ip,str((chno%100)/10))
  sleep(0.2)
  sendcommand(host_ip,str(chno%10))
elif sys.argv[1] == "chno":
  chno = int(sys.argv[2])

  sendcommand(host_ip,str(chno/100))
  sleep(0.2)
  sendcommand(host_ip,str((chno%100)/10))
  sleep(0.2)
  sendcommand(host_ip,str(chno%10))
else:
  sendcommand(host_ip,sys.argv[1])

2 Likes

You can also fetch info from the box on port 9006

e.g.
http://<box ip>:9006/as/system/information

I having a troubles running that script via HA , works fine in console or when sudo to HA but when add to configuration just doesnt seems to do anything. Any ideas ? I tried double quotes etc.

Not really an expert on linux security but maybe switch the console to your hass user and test from there. I think the command is “sudo su [hassusername]” to switch the console to whatever your hass username is and then you can see whether that user has access to the folder in which the script lies, whether that user has permission to execute the script or help determine some other problem

sorted by using absolute path. Now working a charm !
If you dont mind me asking, did you hook that to alexa some nice way?
All I did just created input_boolean for on off using emulated hue but wonder if you can actually pass voice commands ?

Incorporate current status into an on/off switch for Sky Q Boxes.

binary_sensor:
  - platform: rest
    resource: http://192.168.1.15:9006/as/system/information
    name: sky_q_living_room_power_status
    device_class: power
    value_template: '{% if (value_json.activeStandby == False) %}on{% else %}off{% endif %}'

script:
  sky_q_living_room_power:
    alias: Toggle Sky Q Living Room power
    sequence:
      - service: shell_command.cmd_skyq_lr_command
        data_template:
          command: 'power'
      - service: shell_command.cmd_skyq_lr_command
        data_template:
          command: 'backup'

switch:
  - platform: template
    switches:
      sky_q_living_room:
        value_template: "{{ is_state('binary_sensor.sky_q_living_room_power_status', 'on') }}"
        turn_on:
          service: script.sky_q_living_room_power
        turn_off:
          service: script.sky_q_living_room_power
2 Likes

For anyone trying to get this to work, it looks like the port has moved to 49160. I’ve got the above code working, but had to replace 5900 with 49160 throughout.

2 Likes

Absolute legend, haven’t used this in a while due to changing configs started it up and it failed!
How did you find out about the port change?

Just did a port scan for open ports on the Sky Q box, then tried them one by one.

Hi @Angarmgmt I was using your code in a RPi3 and it worked fine but now i am using a NUC Ubuntu with docker and its not working.

I get this error.

2018-03-29 15:05:25 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: `/config/python_scripts/skyq.py {{command}}`, return code: 1
NoneType: None

Any help please this was a great piece of code.

Hi @cameron,
Do you have a copy of your config for the sky q remote and channels? Looks great would love to utilise some of what you have done.

Thanks

Hi @Baneeshc
I am sorry i am away at the moment but i will but together some thing the weekend.
I have got it working with Node Red so its using MQTT from the HA to Node Red and the Sky Remote Node.

Hi all!

Wondering if someone could help me out with this?

I have the sky.py file setup however I’m unsure where to place this file within home assistant?

Could anyone pass on any advice on this?

Thanks!

I just uploaded to SkyQ and was quite frustrated my sony IR blaster stopped working with the new box. Just wanted to say that this thread gave me exactly what I needed. Thank you - works a treat!

Hi TDM,

Did you get the sky.py working or did you create the binary sensor?

Did you get this working, @wonkydog?

I have got it all working perfectly, and would be happy to help if you want.

:raised_hands::raised_hands:

Thanks for helping!

No joy yet! Will this work on Haas.io? I’m starting to think no?

Also where did you save the sky.py file?

Any help really appreciated! Thanks again!

WD

I don’t use hass.io, so not sure on that point!

It doesn’t matter where your sky.py file is, as long as HA can reach it and you point to it in your configuration file I have done the below:

shell_command:
  cmd_skyq_channel: /home/homeassistant/.homeassistant/custom_components/sky/skyq.py channel {{chname}}
  cmd_skyq_chno: /home/homeassistant/.homeassistant/custom_components/sky/skyq.py chno {{chno}}
  cmd_skyq_command: /home/homeassistant/.homeassistant/custom_components/sky/skyq.py {{command}}

Then you just need to amend the sky.py file so it has the correct IP address of your sky box.

You can set up a sensor as below:

sensor:

  - platform: rest
    resource: http://192.168.1.13:9006/as/system/information
    name: Sky Q Living Room
    value_template: '{% if (value_json.activeStandby == False) %}on{% else %}off{% endif %}'

And I also set a switch up like this:

  switches:
    sky_q_living_room:
      value_template: "{{ is_state('sensor.sky_q_living_room', 'on') }}"
      turn_on:
        service: script.sky_q_living_room_power
      turn_off:
        service: script.sky_q_living_room_power

It can take a few seconds for the Sky box to realise it’s on, and the switch will turn itself off in the meantime. It will change to on if you leave it.

Hopefully this helps!

Thanks for looking into this. Seems like I can actually call the service now however still no response from the sky box when I call the service. Ive just checked the IP address and that is correct but I’ve thought of the following that may be beneficial to my case…

Could you confirm the port number (for commands) you’re using and getting results from?

Could you perhaps tell me the service data that you are sending in your configs/automations? I’m currently trying:

{
  "command": "power"
}

and also;

{
  "data_template": {
    "command": "power"
  }
}

With no apparent luck with either, any thoughts or suggestions from here again really appreciated! Least I seem to be able to call the sky.py file now which is a big step forward so thank you!

WD