-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathDirectPy.py
More file actions
154 lines (119 loc) · 5.34 KB
/
DirectPy.py
File metadata and controls
154 lines (119 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python
import requests
class DIRECTV:
"""DirectPy.py by Eric Walters (github.com/sentry07)
Control a DirecTV receiver over the network using
DirecTV's SHEF protocol. For more information on
enabling the SHEF interface, please see this PDF:
https://www.satinstalltraining.com/homeautomation/DTV-MD-0359-DIRECTV_SHEF_Command_Set-V1.3.C.pdf
The clientAddr parameter of the class is used for
Genie systems that have a server receiver and client
receivers. To control a client receiver, you must
know the MAC address and reference it without colons.
EX: DIRECTV('192.168.1.10',clientAddr='000A959D6816')
"""
def __init__(self, ip, port=8080, clientAddr='0', determine_state=True):
self.ip = ip
self.port = port
self.clientAddr = clientAddr
self.standby = False
self.channel = '0'
self.valid_keys = ['power', 'poweron', 'poweroff', 'format', 'pause',
'rew', 'replay', 'stop', 'advance', 'ffwd',
'record', 'play', 'guide', 'active', 'list', 'exit',
'back', 'menu', 'info', 'up', 'down', 'left',
'right', 'select', 'red', 'green', 'yellow', 'blue',
'chanup', 'chandown', 'prev', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', 'dash', 'enter']
self.base_url = 'http://%s:%s' % (ip, port)
if determine_state:
self.get_standby()
if not self.standby:
self.get_tuned()
@staticmethod
def _parse_channel(channel):
"""Return major and minor channel numbers for given channel"""
try:
major, minor = channel.split('-')
except ValueError:
major = channel
minor = 65535
return major, minor
@staticmethod
def _combine_channel(major, minor):
"""Return the combined channel number. If minor == 65535, there is no
minor channel number."""
if minor == 65535:
return str(major)
else:
return '%d-%d' % (major, minor)
def get_standby(self):
"""Return standby status of the receiver."""
jResp = requests.get('%s/info/mode?clientAddr=%s' %
(self.base_url, self.clientAddr)).json()
"""Handle clientAddrs that are offline/not reporting for some reason"""
if jResp['status']['code'] == 403:
self.standby = 1
else:
self.standby = (jResp['mode'] == 1)
return self.standby
def get_channel(self, channel: "'###' or '###-#'"):
"""Return program information for a channel."""
if not type(channel) is str:
raise TypeError('Channel should be a string')
major, minor = self._parse_channel(channel)
jResp = requests.get(
'%s/tv/getProgInfo?major=%s&minor=%s&clientAddr=%s' %
(self.base_url, major, minor, self.clientAddr)).json()
return jResp
def get_tuned(self):
"""Returns the channel and program information of the current
channel."""
jResp = requests.get(
'%s/tv/getTuned?clientAddr=%s' %
(self.base_url, self.clientAddr)).json()
if jResp['status']['code'] == 200:
self.channel = self._combine_channel(jResp['major'],
jResp['minor'])
return jResp
def tune_channel(self, channel: "'###' or '###-#'"):
"""Change the channel on the receiver."""
if not type(channel) is str:
raise TypeError('Channel should be a string')
major, minor = self._parse_channel(channel)
jResp = requests.get(
'%s/tv/tune?major=%s&minor=%s&clientAddr=%s' %
(self.base_url, major, minor, self.clientAddr)).json()
if jResp['status']['code'] == 200:
self.channel = channel
return jResp
def key_press(self, key: str):
"""Emulate pressing a key on the remote. See help() for supported keys.
Supported keys: power, poweron, poweroff, format,
pause, rew, replay, stop, advance, ffwd, record,
play, guide, active, list, exit, back, menu, info,
up, down, left, right, select, red, green, yellow,
blue, chanup, chandown, prev, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, dash, enter
"""
if not type(key) is str:
raise TypeError('Key should be a string')
if not key.lower() in self.valid_keys:
raise ValueError('Invalid key: ' + key)
jResp = requests.get(
'%s/remote/processKey?key=%s&hold=keyPress&clientAddr=%s' %
(self.base_url, key, self.clientAddr)).json()
return jResp
def get_locations(self):
"""Returns the clientAddr for all devices."""
jResp = requests.get('%s/info/getLocations' % (self.base_url)).json()
return jResp
def get_version(self):
"""Returns the access card ID, received ID, STB software version,
system time ,and version of current implementation."""
jResp = requests.get('%s/info/getVersion' % (self.base_url)).json()
return jResp
def get_serial_num(self):
"""Returns the serial number."""
jResp = requests.get('%s/info/getSerialNum' % (self.base_url)).json()
return jResp