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])