dtvcontroller 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/README.md +117 -0
- data/Rakefile +11 -0
- data/dtvcontroller.gemspec +26 -0
- data/lib/dtvcontroller.rb +10 -93
- data/lib/dtvcontroller/constants.rb +16 -0
- data/lib/dtvcontroller/set_top_box.rb +88 -0
- data/lib/dtvcontroller/version.rb +3 -0
- data/spec/dtvcontroller/set_top_box_spec.rb +286 -0
- data/spec/spec_helper.rb +46 -0
- metadata +89 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb15783ee58c6796a38197bb400cc19fa2bfd477
|
4
|
+
data.tar.gz: ee618252604a45d0e5c7b45b2b3234a27a624b29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9cfc63fb896bbba90ea382e3867e95cf0ea2fd5affbe97e9576d18f62b3e563b69e440137ec58758f8446cd0193957318f39e9efb6f4d1da528e9e661fe055ea
|
7
|
+
data.tar.gz: 04edba46dcc45213f998e78078ba7319d0823489526d5a9df52b36685171a68319b21edec95988c1fc8f05aa48c596b550b5e55e57dc9bbac7958077dac960ec
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
Description
|
2
|
+
===========
|
3
|
+
This gem allows one to control a DirecTV Set Top Box (STB or receiver). This works with the current implication of the "External Device" control system. DirecTV could change or even disable this method at any time without notice.
|
4
|
+
|
5
|
+
# Requirements
|
6
|
+
|
7
|
+
+ net/http
|
8
|
+
+ json
|
9
|
+
+ External Device set to Allow on DTV Box (Menu -> Settings -> Whole-Home -> External Device - All set to 'Allow')
|
10
|
+
|
11
|
+
# Install
|
12
|
+
|
13
|
+
Use rubygems to install the dtvcontroller gem:
|
14
|
+
|
15
|
+
```
|
16
|
+
$ gem install dtvcontroller
|
17
|
+
```
|
18
|
+
|
19
|
+
# Example Usage
|
20
|
+
|
21
|
+
### Initialize:
|
22
|
+
|
23
|
+
```
|
24
|
+
irb(main):001:0> require "dtvcontroller"
|
25
|
+
=> true
|
26
|
+
irb(main):002:0> set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
27
|
+
=> #<Dtvcontroller::SetTopBox:0x000000028ab450 @ip="192.168.1.100", @base_url="http://192.168.1.100:8080">
|
28
|
+
```
|
29
|
+
|
30
|
+
### Get details on what's on with `#currently_playing`:
|
31
|
+
|
32
|
+
```
|
33
|
+
irb(main):003:0> set_top_box.currently_playing
|
34
|
+
=> "529: SEDGHD - The Lost World: Jurassic Park"
|
35
|
+
```
|
36
|
+
|
37
|
+
The output follows the format:
|
38
|
+
|
39
|
+
```
|
40
|
+
<Channel>:<Network> - <Program>: <Program Title if Available>
|
41
|
+
```
|
42
|
+
|
43
|
+
A TV show looks like this (note the episode title):
|
44
|
+
|
45
|
+
```
|
46
|
+
irb(main):004:0> set_top_box.currently_playing
|
47
|
+
=> "298: CNHD - Family Guy: Peters Tale"
|
48
|
+
```
|
49
|
+
|
50
|
+
### Change the channel with `#tune_to_channel`:
|
51
|
+
|
52
|
+
```
|
53
|
+
irb(main):005:0> set_top_box.tune_to_channel(7)
|
54
|
+
=> "OK."
|
55
|
+
```
|
56
|
+
|
57
|
+
### Channel Options:
|
58
|
+
|
59
|
+
Must be between 1-9999.
|
60
|
+
|
61
|
+
### Simulate the remote with `#send_key`:
|
62
|
+
|
63
|
+
```
|
64
|
+
irb(main):006:0> set_top_box.send_key(:chanup)
|
65
|
+
=> "OK."
|
66
|
+
```
|
67
|
+
|
68
|
+
### Remote Key Options:
|
69
|
+
|
70
|
+
+ `:power`
|
71
|
+
+ `:poweron`
|
72
|
+
+ `:poweroff`
|
73
|
+
+ `:format`
|
74
|
+
+ `:pause`
|
75
|
+
+ `:rew`
|
76
|
+
+ `:replay`
|
77
|
+
+ `:stop`
|
78
|
+
+ `:advance`
|
79
|
+
+ `:ffwd`
|
80
|
+
+ `:record`
|
81
|
+
+ `:play`
|
82
|
+
+ `:guide`
|
83
|
+
+ `:active`
|
84
|
+
+ `:list`
|
85
|
+
+ `:exit`
|
86
|
+
+ `:back`
|
87
|
+
+ `:menu`
|
88
|
+
+ `:info`
|
89
|
+
+ `:up`
|
90
|
+
+ `:down`
|
91
|
+
+ `:left`
|
92
|
+
+ `:right`
|
93
|
+
+ `:select`
|
94
|
+
+ `:red`
|
95
|
+
+ `:green`
|
96
|
+
+ `:yellow`
|
97
|
+
+ `:blue`
|
98
|
+
+ `:chanup`
|
99
|
+
+ `:chandown`
|
100
|
+
+ `:prev`
|
101
|
+
+ `:0-9`
|
102
|
+
+ `:dash`
|
103
|
+
+ `:enter`
|
104
|
+
|
105
|
+
### Get details about the unit with `#system_info`:
|
106
|
+
|
107
|
+
```
|
108
|
+
irb(main):007:0> set_top_box.system_info(:access_card_id)
|
109
|
+
=> "0123-4567-8901"
|
110
|
+
```
|
111
|
+
|
112
|
+
### System Info Options:
|
113
|
+
|
114
|
+
+ `:access_card_id`
|
115
|
+
+ `:receiver_id`
|
116
|
+
+ `:stb_software_version`
|
117
|
+
+ `:version`
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "dtvcontroller/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dtvcontroller"
|
8
|
+
spec.version = Dtvcontroller::VERSION
|
9
|
+
spec.authors = ["Nicholas M. Petty"]
|
10
|
+
spec.email = ["nick@ihackeverything.com"]
|
11
|
+
spec.description = "Allows control of DirecTV Set Top Boxes whoms Whole-Home -> External Device settings are set to Allow"
|
12
|
+
spec.summary = "DirecTV STB Controller"
|
13
|
+
spec.homepage = "http://github.com/nickpetty/dtvcontroller-gem"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "webmock"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
end
|
data/lib/dtvcontroller.rb
CHANGED
@@ -1,96 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
# Getting current channel:
|
6
|
-
# puts control.get_channel => "529: SEDGHD - The Lost World: Jurassic Park"
|
7
|
-
#
|
8
|
-
# Tuning to a certain channel:
|
9
|
-
# a = "206"
|
10
|
-
# control.tune(a) => "" *if 'msg' is not 'OK.' 'msg' will be RETURNED
|
11
|
-
#
|
12
|
-
# Sending a remote key:
|
13
|
-
# a = "ch_up"
|
14
|
-
# control.send_key(a) => ""
|
15
|
-
#
|
16
|
-
# Getting information from systeminfo
|
17
|
-
# a = "accessCardId"
|
18
|
-
# b = control.get_sysinfo(a)
|
19
|
-
# puts b => "0918 9292 1846"
|
20
|
-
#
|
21
|
-
# If connection fails because of timeout
|
22
|
-
# for any method, "Can't Connect." will be RETURNED.
|
23
|
-
#######################################
|
1
|
+
require "dtvcontroller/version"
|
2
|
+
require "dtvcontroller/set_top_box"
|
3
|
+
require "dtvcontroller/constants"
|
24
4
|
|
25
|
-
|
26
|
-
require
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def initialize(n)
|
31
|
-
@ip = n
|
32
|
-
end
|
33
|
-
|
34
|
-
def ver
|
35
|
-
puts "1"
|
36
|
-
end
|
37
|
-
|
38
|
-
def get_channel
|
39
|
-
uri = URI('http://' + @ip + ':8080/tv/getTuned')
|
40
|
-
|
41
|
-
begin
|
42
|
-
result = Net::HTTP.get(uri)
|
43
|
-
response = JSON.parse(result)
|
44
|
-
|
45
|
-
if response["episodeTitle"] == nil # Not allow programs have an 'episodetitle'. However, from my experience, all have a 'title' at the least.
|
46
|
-
return response["major"].to_s + ': ' + response["callsign"] + ' - ' + response["title"] # Callsign is the channel 'name'
|
47
|
-
else
|
48
|
-
return response["major"].to_s + ': ' + response["callsign"] + ' - ' + response["title"] + ': ' + response["episodeTitle"]
|
49
|
-
end
|
50
|
-
|
51
|
-
rescue Errno::ETIMEDOUT => e
|
52
|
-
return "Can't Connect"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def tune(chan)
|
57
|
-
if chan == ''
|
58
|
-
return 'no input'
|
59
|
-
else
|
60
|
-
uri = URI('http://' + @ip + ':8080/tv/tune?major=' + chan)
|
5
|
+
begin
|
6
|
+
require "pry"
|
7
|
+
rescue LoadError
|
8
|
+
end
|
61
9
|
|
62
|
-
|
63
|
-
|
64
|
-
response = JSON.parse(result)
|
65
|
-
parse = response["status"]
|
66
|
-
message = parse["msg"]
|
67
|
-
if message != "OK."
|
68
|
-
return message
|
69
|
-
end
|
70
|
-
|
71
|
-
rescue Errno::ETIMEDOUT => e
|
72
|
-
return "Can't Connect"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
#key-list: 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, ch_up, ch_dn, prev, 0-9, dash(or '-'), enter
|
78
|
-
def send_key(key)
|
79
|
-
uri = URI("http://" + @ip + ":8080/remote/processKey?key=" + key)
|
80
|
-
begin
|
81
|
-
Net::HTTP.get(uri)
|
82
|
-
rescue Errno::ETIMEDOUT => e
|
83
|
-
return "Can't Connect"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
#possible requests: accessCardId, receiverId, stbSoftwareVersion, version
|
88
|
-
def get_sysinfo(request)
|
89
|
-
uri = URI("http://" + @ip + ":8080/info/getVersion")
|
90
|
-
a = Net::HTTP.get(uri)
|
91
|
-
result = JSON.parse(a)
|
92
|
-
parse = result[request]
|
93
|
-
return parse
|
94
|
-
end
|
95
|
-
|
10
|
+
module Dtvcontroller
|
11
|
+
# binding.pry
|
96
12
|
end
|
13
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dtvcontroller
|
2
|
+
module Constants
|
3
|
+
SEND_KEY_OPTIONS = [:power, :poweron, :poweroff, :format, :pause, :rew,
|
4
|
+
:replay, :stop, :advance, :ffwd, :record, :play,
|
5
|
+
:guide, :active, :list, :exit, :back, :menu, :info,
|
6
|
+
:up, :down, :left, :right, :select, :red, :green,
|
7
|
+
:yellow, :blue, :chanup, :chandown, :prev, :"0",
|
8
|
+
:"1", :"2", :"3", :"4", :"5", :"6", :"7", :"8", :"9",
|
9
|
+
:dash, :enter]
|
10
|
+
|
11
|
+
SYSTEM_INFO_HASH = {:access_card_id => "accessCardId",
|
12
|
+
:receiver_id => "receiverId",
|
13
|
+
:stb_software_version => "stbSoftwareVersion",
|
14
|
+
:version => "version"}
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "json"
|
3
|
+
require_relative "constants"
|
4
|
+
|
5
|
+
module Dtvcontroller
|
6
|
+
class SetTopBox
|
7
|
+
include Constants
|
8
|
+
attr_reader :ip, :base_url
|
9
|
+
|
10
|
+
def initialize(ip_address)
|
11
|
+
@ip = ip_address.to_s
|
12
|
+
@base_url = "http://#{ip}:8080/"
|
13
|
+
end
|
14
|
+
|
15
|
+
def ver
|
16
|
+
"SetTopBox#ver is deprecated, use '$ gem which dtvcontroller'\n2.0.0"
|
17
|
+
end
|
18
|
+
|
19
|
+
def currently_playing
|
20
|
+
url = "#{base_url}tv/getTuned"
|
21
|
+
response_hash = get_json_parsed_response_body(url)
|
22
|
+
channel = response_hash["major"].to_s
|
23
|
+
network = response_hash["callsign"].to_s
|
24
|
+
program = response_hash["title"].to_s
|
25
|
+
result = "#{channel}: #{network} - #{program}"
|
26
|
+
if response_hash.has_key?("episodeTitle")
|
27
|
+
result = "#{result}: #{response_hash["episodeTitle"]}"
|
28
|
+
end
|
29
|
+
result
|
30
|
+
end
|
31
|
+
alias_method :get_channel, :currently_playing
|
32
|
+
|
33
|
+
def tune_to_channel(number)
|
34
|
+
return "no input" if number == ""
|
35
|
+
url = "#{base_url}tv/tune?major=#{number}"
|
36
|
+
response_hash = get_json_parsed_response_body(url)
|
37
|
+
response_hash["status"]["msg"]
|
38
|
+
end
|
39
|
+
alias_method :tune, :tune_to_channel
|
40
|
+
|
41
|
+
def send_key_options
|
42
|
+
SEND_KEY_OPTIONS
|
43
|
+
end
|
44
|
+
|
45
|
+
def send_key(key)
|
46
|
+
raise "Unknown remote key: #{key}" unless SEND_KEY_OPTIONS.include?(key.to_sym)
|
47
|
+
url = "#{base_url}remote/processKey?key=#{key}"
|
48
|
+
response_hash = get_json_parsed_response_body(url)
|
49
|
+
response_hash["status"]["msg"]
|
50
|
+
end
|
51
|
+
|
52
|
+
def system_info_options
|
53
|
+
SYSTEM_INFO_HASH.keys
|
54
|
+
end
|
55
|
+
|
56
|
+
def system_info(item)
|
57
|
+
value = validated_hash_lookup(item, SYSTEM_INFO_HASH)
|
58
|
+
url = "#{base_url}info/getVersion"
|
59
|
+
response_hash = get_json_parsed_response_body(url)
|
60
|
+
response_hash[value]
|
61
|
+
end
|
62
|
+
alias_method :get_sysinfo, :system_info
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def validated_hash_lookup(key, hash_to_search)
|
67
|
+
begin
|
68
|
+
hash_to_search.fetch(key.to_sym)
|
69
|
+
rescue KeyError
|
70
|
+
raise "Unrecognized system option: #{key}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# TODO add a retry with counter and decrement per Ruby Tapas #257
|
75
|
+
def get_json_parsed_response_body(url)
|
76
|
+
begin
|
77
|
+
response = Net::HTTP.get(URI(url))
|
78
|
+
JSON.parse(response)
|
79
|
+
rescue Errno::ETIMEDOUT
|
80
|
+
raise "Cannot connect to set top box"
|
81
|
+
rescue Errno::EHOSTUNREACH
|
82
|
+
raise "Unreachable host likely caused by no internet connect"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,286 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Dtvcontroller
|
4
|
+
describe SetTopBox do
|
5
|
+
describe "#initialize" do
|
6
|
+
it "has an ip address string representation" do
|
7
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
8
|
+
|
9
|
+
expect(set_top_box.ip).to eq("192.168.1.100")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has a base url" do
|
13
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
14
|
+
|
15
|
+
expect(set_top_box.base_url).to eq("http://192.168.1.100:8080/")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#ver" do
|
20
|
+
it "returns a deprecation warning and '2.0.0'" do
|
21
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
22
|
+
|
23
|
+
expect(set_top_box.ver).to eq("SetTopBox#ver is deprecated, use '$ gem which dtvcontroller'\n2.0.0")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#send_key_options" do
|
28
|
+
it "returns an array of symobols with choices" do
|
29
|
+
options = [:power,
|
30
|
+
:poweron,
|
31
|
+
:poweroff,
|
32
|
+
:format,
|
33
|
+
:pause,
|
34
|
+
:rew,
|
35
|
+
:replay,
|
36
|
+
:stop,
|
37
|
+
:advance,
|
38
|
+
:ffwd,
|
39
|
+
:record,
|
40
|
+
:play,
|
41
|
+
:guide,
|
42
|
+
:active,
|
43
|
+
:list,
|
44
|
+
:exit,
|
45
|
+
:back,
|
46
|
+
:menu,
|
47
|
+
:info,
|
48
|
+
:up,
|
49
|
+
:down,
|
50
|
+
:left,
|
51
|
+
:right,
|
52
|
+
:select,
|
53
|
+
:red,
|
54
|
+
:green,
|
55
|
+
:yellow,
|
56
|
+
:blue,
|
57
|
+
:chanup,
|
58
|
+
:chandown,
|
59
|
+
:prev,
|
60
|
+
:"0",
|
61
|
+
:"1",
|
62
|
+
:"2",
|
63
|
+
:"3",
|
64
|
+
:"4",
|
65
|
+
:"5",
|
66
|
+
:"6",
|
67
|
+
:"7",
|
68
|
+
:"8",
|
69
|
+
:"9",
|
70
|
+
:dash,
|
71
|
+
:enter]
|
72
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
73
|
+
|
74
|
+
expect(set_top_box.send_key_options).to eq(options)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#system_info_options" do
|
79
|
+
it "lists the system info options" do
|
80
|
+
options = [:access_card_id,
|
81
|
+
:receiver_id,
|
82
|
+
:stb_software_version,
|
83
|
+
:version]
|
84
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
85
|
+
|
86
|
+
expect(set_top_box.system_info_options).to eq(options)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#system_info" do
|
91
|
+
it "returns the access card id" do
|
92
|
+
access_card_id = "0123-4567-8901"
|
93
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
94
|
+
|
95
|
+
expect(set_top_box.system_info(:access_card_id)).to eq(access_card_id)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns the receiver id" do
|
99
|
+
receiver_id = "0123 4567 8901"
|
100
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
101
|
+
|
102
|
+
expect(set_top_box.system_info(:receiver_id)).to eq(receiver_id)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns the set top box software version" do
|
106
|
+
stb_software_version = "0x912"
|
107
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
108
|
+
|
109
|
+
expect(set_top_box.system_info(:stb_software_version)).to eq(stb_software_version)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns the version" do
|
113
|
+
version = "1.6"
|
114
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
115
|
+
|
116
|
+
expect(set_top_box.system_info(:version)).to eq(version)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "returns the access card id when given a string (not a symbol)" do
|
120
|
+
access_card_id = "0123-4567-8901"
|
121
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
122
|
+
|
123
|
+
expect(set_top_box.system_info("access_card_id")).to eq(access_card_id)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "raises a RuntimeError on a bad input parameter" do
|
127
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
128
|
+
|
129
|
+
expect { set_top_box.system_info(:not_a_key) }.to raise_error(RuntimeError)
|
130
|
+
end
|
131
|
+
|
132
|
+
# special IP address 1.2.3.4 triggers the Webmock timeout
|
133
|
+
it "raises a RuntimeError on a timeout" do
|
134
|
+
set_top_box = Dtvcontroller::SetTopBox.new("1.2.3.4")
|
135
|
+
|
136
|
+
expect { set_top_box.system_info(:version) }.to raise_error(RuntimeError)
|
137
|
+
end
|
138
|
+
|
139
|
+
# special IP address 4.3.2.1 triggers the Webmock runtime error
|
140
|
+
it "raises a RuntimeError on a failed connection" do
|
141
|
+
set_top_box = Dtvcontroller::SetTopBox.new("4.3.2.1")
|
142
|
+
|
143
|
+
expect { set_top_box.system_info(:version) }.to raise_error(RuntimeError)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "#get_sysinfo" do
|
148
|
+
it "aliases to #system_info" do
|
149
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
150
|
+
system_info_method = set_top_box.method(:system_info)
|
151
|
+
get_sysinfo_method = set_top_box.method(:get_sysinfo)
|
152
|
+
|
153
|
+
expect(system_info_method).to eq(get_sysinfo_method)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#tune_to_channel" do
|
158
|
+
it "changes the channel given a number from 1-65536" do
|
159
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
160
|
+
|
161
|
+
expect(set_top_box.tune_to_channel(7)).to eq("OK.")
|
162
|
+
end
|
163
|
+
|
164
|
+
it "returns the 'Forbidden' message given channel 0" do
|
165
|
+
failure_string = "Forbidden.Invalid URL parameter(s) found."
|
166
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
167
|
+
|
168
|
+
expect(set_top_box.tune_to_channel(0)).to eq(failure_string)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "returns the 'Forbidden' message given channel 10000" do
|
172
|
+
failure_string = "Forbidden.Invalid URL parameter(s) found."
|
173
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
174
|
+
|
175
|
+
expect(set_top_box.tune_to_channel(10000)).to eq(failure_string)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "returns the 'no input' message given a blank channel" do
|
179
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
180
|
+
|
181
|
+
expect(set_top_box.tune_to_channel("")).to eq("no input")
|
182
|
+
end
|
183
|
+
|
184
|
+
# special IP address 1.2.3.4 triggers the Webmock timeout
|
185
|
+
it "raises a RuntimeError on a timeout" do
|
186
|
+
set_top_box = Dtvcontroller::SetTopBox.new("1.2.3.4")
|
187
|
+
|
188
|
+
expect { set_top_box.tune_to_channel(7) }.to raise_error(RuntimeError)
|
189
|
+
end
|
190
|
+
|
191
|
+
# special IP address 4.3.2.1 triggers the Webmock runtime error
|
192
|
+
it "raises a RuntimeError on a failed connection" do
|
193
|
+
set_top_box = Dtvcontroller::SetTopBox.new("4.3.2.1")
|
194
|
+
|
195
|
+
expect { set_top_box.tune_to_channel(7) }.to raise_error(RuntimeError)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "#tune" do
|
200
|
+
it "aliases to #tune_to_channel" do
|
201
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
202
|
+
tune_method = set_top_box.method(:tune)
|
203
|
+
tune_to_channel_method = set_top_box.method(:tune_to_channel)
|
204
|
+
|
205
|
+
expect(tune_method).to eq(tune_to_channel_method)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "#get_currently_playing" do
|
210
|
+
# Use 192.168.1.101 for a TV episode
|
211
|
+
it "returns major and callsign and title and episode title for a tv show" do
|
212
|
+
tv_response = "299: NIKeHD - How I Met Your Mother: Sunrise"
|
213
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.101")
|
214
|
+
|
215
|
+
expect(set_top_box.currently_playing).to eq(tv_response)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Use 192.168.1.102 for a movie
|
219
|
+
it "returns major and callsign and title for a movie" do
|
220
|
+
movie_response = "501: HBOeHD - Good Burger"
|
221
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.102")
|
222
|
+
|
223
|
+
expect(set_top_box.currently_playing).to eq(movie_response)
|
224
|
+
end
|
225
|
+
|
226
|
+
# special IP address 1.2.3.4 triggers the Webmock timeout
|
227
|
+
it "raises a RuntimeError on a timeout" do
|
228
|
+
set_top_box = Dtvcontroller::SetTopBox.new("1.2.3.4")
|
229
|
+
|
230
|
+
expect { set_top_box.currently_playing }.to raise_error(RuntimeError)
|
231
|
+
end
|
232
|
+
|
233
|
+
# special IP address 4.3.2.1 triggers the Webmock runtime error
|
234
|
+
it "raises a RuntimeError on a failed connection" do
|
235
|
+
set_top_box = Dtvcontroller::SetTopBox.new("4.3.2.1")
|
236
|
+
|
237
|
+
expect { set_top_box.currently_playing }.to raise_error(RuntimeError)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe "#get_channel" do
|
242
|
+
it "aliases to #currently_playing" do
|
243
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
244
|
+
system_info_method = set_top_box.method(:get_channel)
|
245
|
+
get_sysinfo_method = set_top_box.method(:currently_playing)
|
246
|
+
|
247
|
+
expect(system_info_method).to eq(get_sysinfo_method)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "#send_key" do
|
252
|
+
it "sends the dash key" do
|
253
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
254
|
+
|
255
|
+
expect(set_top_box.send_key(:dash)).to eq("OK.")
|
256
|
+
end
|
257
|
+
|
258
|
+
it "sends the dash key given a string (not a symbol)" do
|
259
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
260
|
+
|
261
|
+
expect(set_top_box.send_key("dash")).to eq("OK.")
|
262
|
+
end
|
263
|
+
|
264
|
+
it "raises a RuntimeError on a bad input parameter" do
|
265
|
+
set_top_box = Dtvcontroller::SetTopBox.new("192.168.1.100")
|
266
|
+
|
267
|
+
expect { set_top_box.send_key(:not_a_key) }.to raise_error(RuntimeError)
|
268
|
+
end
|
269
|
+
|
270
|
+
# special IP address 1.2.3.4 triggers the Webmock timeout
|
271
|
+
it "raises a RuntimeError on a timeout" do
|
272
|
+
set_top_box = Dtvcontroller::SetTopBox.new("1.2.3.4")
|
273
|
+
|
274
|
+
expect { set_top_box.send_key(:dash) }.to raise_error(RuntimeError)
|
275
|
+
end
|
276
|
+
|
277
|
+
# special IP address 4.3.2.1 triggers the Webmock runtime error
|
278
|
+
it "raises a RuntimeError on a failed connection" do
|
279
|
+
set_top_box = Dtvcontroller::SetTopBox.new("4.3.2.1")
|
280
|
+
|
281
|
+
expect { set_top_box.send_key(:dash) }.to raise_error(RuntimeError)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "dtvcontroller"
|
2
|
+
require "webmock/rspec"
|
3
|
+
|
4
|
+
system_info_json_as_string = "{\n \"accessCardId\": \"0123-4567-8901\",\n \"receiverId\": \"0123 4567 8901\",\n \"status\": {\n \"code\": 200,\n \"commandResult\": 0,\n \"msg\": \"OK.\",\n \"query\": \"/info/getVersion\"\n },\n \"stbSoftwareVersion\": \"0x912\",\n \"systemTime\": 1424316674,\n \"version\": \"1.6\"\n}"
|
5
|
+
|
6
|
+
change_channel_success_json_as_string = "{\"status\": {\n \"code\": 200,\n \"commandResult\": 0,\n \"msg\": \"OK.\",\n \"query\": \"/tv/tune?major=7\"\n}}"
|
7
|
+
|
8
|
+
change_channel_fail_json_as_string = "{\"status\": {\n \"code\": 403,\n \"commandResult\": 1,\n \"msg\": \"Forbidden.Invalid URL parameter(s) found.\",\n \"query\": \"/tv/tune?major=0\"\n}}"
|
9
|
+
|
10
|
+
currently_playing_tv_json_as_string = "{\n \"broadcastStartTime\": 1424327040,\n \"callsign\": \"NIKeHD\",\n \"contentStartTime\": 27579,\n \"date\": \"20140203\",\n \"duration\": 2160,\n \"episodeTitle\": \"Sunrise\",\n \"expiration\": \"0\",\n \"expiryTime\": 0,\n \"isOffAir\": false,\n \"isPartial\": false,\n \"isPclocked\": 3,\n \"isPpv\": false,\n \"isRecording\": false,\n \"isViewed\": true,\n \"isVod\": false,\n \"keepUntilFull\": true,\n \"major\": 299,\n \"minor\": 65535,\n \"offset\": 1055,\n \"priority\": \"20 of 31\",\n \"programId\": \"13083758\",\n \"rating\": \"TV-14-D-L\",\n \"recType\": 3,\n \"startTime\": 1424327040,\n \"stationId\": 3900972,\n \"status\": {\n \"code\": 200,\n \"commandResult\": 0,\n \"msg\": \"OK.\",\n \"query\": \"/tv/getTuned\"\n },\n \"title\": \"How I Met Your Mother\",\n \"uniqueId\": \"6388\"\n}"
|
11
|
+
|
12
|
+
currently_playing_movie_json_as_string = "{\n \"callsign\": \"HBOeHD\",\n \"date\": \"1997\",\n \"duration\": 6300,\n \"isOffAir\": false,\n \"isPclocked\": 3,\n \"isPpv\": false,\n \"isRecording\": false,\n \"isVod\": false,\n \"major\": 501,\n \"minor\": 65535,\n \"offset\": 5294,\n \"programId\": \"8833886\",\n \"rating\": \"PG\",\n \"startTime\": 1424466900,\n \"stationId\": 2220258,\n \"status\": {\n \"code\": 200,\n \"commandResult\": 0,\n \"msg\": \"OK.\",\n \"query\": \"/tv/getTuned\"\n },\n \"title\": \"Good Burger\"\n}"
|
13
|
+
|
14
|
+
send_dash_key_success_json_as_string = "{\n \"hold\": \"keyPress\",\n \"key\": \"dash\",\n \"status\": {\n \"code\": 200,\n \"commandResult\": 0,\n \"msg\": \"OK.\",\n \"query\": \"/remote/processKey?key=dash\"\n }\n}"
|
15
|
+
|
16
|
+
WebMock.disable_net_connect!(:allow_localhost => true)
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.expect_with :rspec do |expectations|
|
20
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
21
|
+
end
|
22
|
+
|
23
|
+
config.mock_with :rspec do |mocks|
|
24
|
+
mocks.verify_partial_doubles = true
|
25
|
+
end
|
26
|
+
|
27
|
+
config.before(:each) do
|
28
|
+
stub_request(:get, /1\.2\.3\.4/).to_timeout
|
29
|
+
stub_request(:get, /4\.3\.2\.1/).to_raise(RuntimeError)
|
30
|
+
stub_request(:get, "http://192.168.1.100:8080/info/getVersion").
|
31
|
+
to_return(:status => 200, :body => system_info_json_as_string, :headers => {})
|
32
|
+
stub_request(:get, "http://192.168.1.100:8080/tv/tune?major=0").
|
33
|
+
to_return(:status => 200, :body => change_channel_fail_json_as_string, :headers => {})
|
34
|
+
stub_request(:get, "http://192.168.1.100:8080/tv/tune?major=10000").
|
35
|
+
to_return(:status => 200, :body => change_channel_fail_json_as_string, :headers => {})
|
36
|
+
stub_request(:get, "http://192.168.1.100:8080/tv/tune?major=7").
|
37
|
+
to_return(:status => 200, :body => change_channel_success_json_as_string, :headers => {})
|
38
|
+
stub_request(:get, "http://192.168.1.101:8080/tv/getTuned").
|
39
|
+
to_return(:status => 200, :body => currently_playing_tv_json_as_string, :headers => {})
|
40
|
+
stub_request(:get, "http://192.168.1.102:8080/tv/getTuned").
|
41
|
+
to_return(:status => 200, :body => currently_playing_movie_json_as_string, :headers => {})
|
42
|
+
stub_request(:get, "http://192.168.1.100:8080/remote/processKey?key=dash").
|
43
|
+
to_return(:status => 200, :body => send_dash_key_success_json_as_string, :headers => {})
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dtvcontroller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas M. Petty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2015-02-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
13
83
|
description: Allows control of DirecTV Set Top Boxes whoms Whole-Home -> External
|
14
84
|
Device settings are set to Allow
|
15
85
|
email:
|
@@ -18,9 +88,20 @@ executables: []
|
|
18
88
|
extensions: []
|
19
89
|
extra_rdoc_files: []
|
20
90
|
files:
|
91
|
+
- .gitignore
|
92
|
+
- Gemfile
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- dtvcontroller.gemspec
|
21
96
|
- lib/dtvcontroller.rb
|
97
|
+
- lib/dtvcontroller/constants.rb
|
98
|
+
- lib/dtvcontroller/set_top_box.rb
|
99
|
+
- lib/dtvcontroller/version.rb
|
100
|
+
- spec/dtvcontroller/set_top_box_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
22
102
|
homepage: http://github.com/nickpetty/dtvcontroller-gem
|
23
|
-
licenses:
|
103
|
+
licenses:
|
104
|
+
- MIT
|
24
105
|
metadata: {}
|
25
106
|
post_install_message:
|
26
107
|
rdoc_options: []
|
@@ -38,8 +119,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
38
119
|
version: '0'
|
39
120
|
requirements: []
|
40
121
|
rubyforge_project:
|
41
|
-
rubygems_version: 2.0.
|
122
|
+
rubygems_version: 2.0.14
|
42
123
|
signing_key:
|
43
124
|
specification_version: 4
|
44
125
|
summary: DirecTV STB Controller
|
45
|
-
test_files:
|
126
|
+
test_files:
|
127
|
+
- spec/dtvcontroller/set_top_box_spec.rb
|
128
|
+
- spec/spec_helper.rb
|