bravtroller 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68dcd827b96c8dddcbf6723c1cfbc91f513b92c9
4
- data.tar.gz: 675598aee283db134b67f3244133043379680341
3
+ metadata.gz: 1e5a2d9ff7a5bd2ea66e36a38c24a53a03d93cd9
4
+ data.tar.gz: c8ee0410e7171bb40b079c6b9bdc4ebe537bddf6
5
5
  SHA512:
6
- metadata.gz: a39d66e9beaa1e7473078c9019472a7b869be43febbc88e08fae52c16e9c6498bad99bbf4a09a1101d6a8238f9a85cad19b651a9c27bacac16c413d05e7d8cf1
7
- data.tar.gz: 83de2af313aec84fb0dafe33d53b23e986a22957e1d2acad2f9835683382b1eaa0a452048c8d62f4fd67426071d412a772448afde1bcbfd26ebf91781be8634f
6
+ metadata.gz: bfcd5c7408e4adfe6dfb24c6bc917f5646c7830749c36498c6c8aa1b5bc2886ff64691e57476f06873dc164b4bf554d6e94741b074690e6921997d84e4814235
7
+ data.tar.gz: dca6881a1a3060ba680e3b888c948955e771224f3187f44084951917ea8193e307bb40793c5df2759228d954f9a4b6608cf23114e89668b8d6e9cbdb76fb7819
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # bravtroller
2
+ Controller for Sony Bravia KDL-50W700.
3
+
4
+ ## Installing
5
+
6
+ bravtroller is available on [Rubygems](https://rubygems.org). You can install it with:
7
+
8
+ ```
9
+ $ gem install bravtroller
10
+ ```
11
+
12
+ You can also add it to your Gemfile:
13
+
14
+ ```
15
+ gem 'bravtroller'
16
+ ```
17
+
18
+ ## What is it?
19
+
20
+ My Sony TV (a KDL-50W700) has an API. It's a weird combination of custom Sony JSON-over-HTTP and UPnP/SOAP. I wanted a Ruby library to control it, so I created this. I wouldn't be very surprised if other network-enabled Sony devices supported roughly the same interface.
21
+
22
+ ## Authentication
23
+
24
+ #### Summary
25
+
26
+ My TV requires that a device authenticate with it before controlling it remotely. You can use `Bravtroller::Authenticator` to do that. This is what happens:
27
+
28
+ 1. `Bravtroller::Authenticator` initiates an authentication request
29
+ 2. The TV displays a 4 digit security code
30
+ 3. A user-provided block is called to supply the security code (I just used `gets`)
31
+ 4. The security code is submitted to the TV, and `Bravtroller` will then be authenticated
32
+
33
+ #### Example
34
+
35
+ ```ruby
36
+ require 'bravtroller/client'
37
+ require 'bravtroller/authenticator'
38
+
39
+ auth = Bravtroller::Authenticator.new( Bravtroller::Client.new(BRAVIA_IP_ADDRESS) )
40
+
41
+ a.authorized?
42
+ # => false
43
+
44
+ # This will initiate the procedure described above. The string returned is a cookie used by the SOAP client
45
+ a.authorize { gets.strip }
46
+ # > 3
47
+ # => "auth=xxxxxxx"
48
+
49
+ a.authorized?
50
+ # => true
51
+ ```
52
+
53
+ ## Example usage
54
+
55
+ The below example assumes Bravtroller has already been authenticated:
56
+
57
+ #### Remote emulator
58
+
59
+ ```ruby
60
+ require 'bravtroller/client'
61
+ require 'bravtroller/remote'
62
+
63
+ remote = Bravtroller::Remote.create( Bravtroller::Client.new(BRAVIA_IP_ADDRESS) )
64
+
65
+ remote.buttons
66
+ # => ["PowerOff", "Input", "GGuide", "EPG", "Favorites", "Display", "Home", "Options", "Return", "Up", "Down", "Right", "Left", "Confirm", "Red", "Green", "Yellow", "Blue", "Num1", "Num2", "Num3", "Num4", "Num5", "Num6", "Num7", "Num8", "Num9", "Num0", "Num11", "Num12", "VolumeUp", "VolumeDown", "Mute", "ChannelUp", "ChannelDown", "SubTitle", "ClosedCaption", "Enter", "DOT", "Analog", "Teletext", "Exit", "Analog2", "*AD", "Digital", "Analog?", "BS", "CS", "BSCS", "Ddata", "PicOff", "Tv_Radio", "Theater", "SEN", "InternetWidgets", "InternetVideo", "Netflix", "SceneSelect", "Mode3D", "iManual", "Audio", "Wide", "Jump", "PAP", "MyEPG", "ProgramDescription", "WriteChapter", "TrackID", "TenKey", "AppliCast", "acTVila", "DeleteVideo", "PhotoFrame", "TvPause", "KeyPad", "Media", "SyncMenu", "Forward", "Play", "Rewind", "Prev", "Stop", "Next", "Rec", "Pause", "Eject", "FlashPlus", "FlashMinus", "TopMenu", "PopUpMenu", "RakurakuStart", "OneTouchTimeRec", "OneTouchView", "OneTouchRec", "OneTouchStop", "DUX", "FootballMode", "Social"]
67
+
68
+ remote.press_button('VolumeUp')
69
+ ```
70
+
71
+ #### Wake on LAN
72
+
73
+ You can also use `Bravtroller` to turn on the TV. Mine responds to the standard WOL magic packet, which is what the below method is doing. Assuming the same setup as above:
74
+
75
+ ```ruby
76
+ remote.power_on
77
+ # => true
78
+ ```
79
+
80
+ The caveat is that `remote` must be constructed while the TV is powered on. This is because:
81
+
82
+ 1. It needs to communicate with the TV to construct the SOAP client. This is an artificial limitation. It could cache the service definition.
83
+ 2. It need to determine the hardware address of the TV (necessary to construct the WOL packet). It does this by shelling out and calling `arp`. If the TV isn't in the ARP cache, it won't be able to determine the hardware address. Again -- an artificial limitation.
@@ -7,6 +7,26 @@ module Bravtroller
7
7
  @bravia_address = bravia_address
8
8
  end
9
9
 
10
+ def hw_addr
11
+ arp = `which arp`.strip
12
+
13
+ raise RuntimeError.new "Couldn't find arp binary" if arp.empty?
14
+
15
+ result = `#{arp} #{@bravia_address}`
16
+ hw_addr_match = result.match(/((?:[a-f0-9]{1,2}:?){6})/i)
17
+ if hw_addr_match.nil?
18
+ nil
19
+ else
20
+ # On my mac, octets with the most significant nibble = 0 show as "0" instead of "00"
21
+ hw_addr_match
22
+ .captures
23
+ .first
24
+ .split(':')
25
+ .map { |x| "#{x.length == 1 ? '0' : ''}#{x}" }
26
+ .join(':')
27
+ end
28
+ end
29
+
10
30
  def post_request(path, params = {}, headers = {})
11
31
  json = JSON.generate(params)
12
32
  uri = URI("http://#{@bravia_address}#{path}")
@@ -40,8 +40,18 @@ module Bravtroller
40
40
  @bravia_client = bravia_client
41
41
  end
42
42
 
43
+ def power_on
44
+ addr = ['<broadcast>', 9]
45
+ sock = UDPSocket.new
46
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
47
+ packet_data = (([255] * 6) + (@bravia_client.hw_addr.split(':').map(&:hex) * 16)).pack('C*')
48
+ sock.send(packet_data, 0, addr[0], addr[1])
49
+
50
+ true
51
+ end
52
+
43
53
  def press_button(button_key)
44
- raise RuntimeError.new "Undefined buton: #{button_key}" if ircc_codes[button_key].nil?
54
+ raise RuntimeError.new "Undefined button: #{button_key}" if ircc_codes[button_key].nil?
45
55
 
46
56
  @ircc_client.X_SendIRCC IRCCCode: ircc_codes[button_key]
47
57
  end
@@ -1,3 +1,3 @@
1
1
  module Bravtroller
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bravtroller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Mullins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-10 00:00:00.000000000 Z
11
+ date: 2015-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: easy_upnp
@@ -62,6 +62,7 @@ files:
62
62
  - Gemfile
63
63
  - Gemfile.lock
64
64
  - LICENSE
65
+ - README.md
65
66
  - Rakefile
66
67
  - bravtroller.gemspec
67
68
  - lib/bravtroller.rb