samsung 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8765c385dabd7c0bf6e7c5550c869a5ac45221a9
4
+ data.tar.gz: f4dc04a698a7c8c6d1b766abe686e09cbbac44f8
5
+ SHA512:
6
+ metadata.gz: 4013b1151df8e1984a0aa2feb0d9dd6531200868d470ce8ae4629aacd7a67f3496c7b507c91e74a74e64b628196ffb558a8db76a889bfe9db04023ddb49565ae
7
+ data.tar.gz: fa33e3a1160fd73cd0e9fe6fbfcfb0121ff3de6f8097bcde62c7ae663df4762d12c293ac58424f1ee9aa7621bf75638ecbd895611acec77740e51a8589997664
@@ -0,0 +1,32 @@
1
+ = samsung
2
+
3
+ Remote control for Samsung SmartTVs.
4
+
5
+ == Quick start
6
+
7
+ Install the gem:
8
+
9
+ gem install samsung
10
+
11
+ Or add it to your Gemfile:
12
+
13
+ gem "samsung"
14
+
15
+ Use it:
16
+
17
+ require 'samsung'
18
+
19
+ remote = Samsung::Remote.new(IP)
20
+
21
+ # wait for TV to respond
22
+ remote.peek_frame
23
+
24
+ remote.send_key 'KEY_VOLUP'
25
+
26
+ == To Do
27
+
28
+ * Lots of things, this is POC-level code
29
+
30
+ == License
31
+
32
+ This gem is released under the {MIT License}[http://www.opensource.org/licenses/MIT].
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'samsung'
@@ -0,0 +1,6 @@
1
+ require_relative 'samsung/network'
2
+ require_relative 'samsung/protocol'
3
+ require_relative 'samsung/remote'
4
+
5
+ module Samsung
6
+ end
@@ -0,0 +1,11 @@
1
+ module Samsung
2
+ class Network
3
+ def local_ip
4
+ Socket.ip_address_list.find {|a| a.ipv4? and !a.ipv4_loopback? and a.ipv4_private? }.ip_address
5
+ end
6
+
7
+ def local_hw_address
8
+ `ifconfig -a | grep HWaddr | cut -c39- | head -n1`.strip
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'protocol/frame'
2
+ require_relative 'protocol/header_frame'
3
+ require_relative 'protocol/auth_frame'
4
+ require_relative 'protocol/key_frame'
5
+ require_relative 'protocol/response'
6
+
7
+ module Samsung
8
+ module Protocol
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module Samsung
2
+ module Protocol
3
+ class AuthFrame < Frame
4
+ def initialize(local_ip, app_id, name)
5
+ super()
6
+ push_int8(0x64)
7
+ push_int8(0x00)
8
+ push_string64(local_ip)
9
+ push_string64(app_id)
10
+ push_string64(name)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,88 @@
1
+ require 'base64'
2
+
3
+ module Samsung
4
+ module Protocol
5
+ class Frame
6
+ attr_accessor :data
7
+
8
+ def initialize data = ''
9
+ @data = data
10
+ end
11
+
12
+ def size
13
+ @data.size
14
+ end
15
+
16
+ def hex
17
+ data.split('').map do |c|
18
+ "0x%.2x" % c.ord
19
+ end.join(' ')
20
+ end
21
+
22
+ # String
23
+
24
+ def push_string(s)
25
+ push_int16(s.size)
26
+ self.data += s
27
+ end
28
+
29
+ def pop_string
30
+ len = pop_int16
31
+ data.slice!(0..len-1)
32
+ end
33
+
34
+ # Base64 string
35
+
36
+ def push_string64(s)
37
+ push_string(Base64.encode64(s))
38
+ end
39
+
40
+ def pop_string64
41
+ len = pop_int16
42
+ Base64.decode64(data.slice!(0..len-1))
43
+ end
44
+
45
+ # 8-bit integer
46
+
47
+ def push_int8(v)
48
+ self.data += [v].pack('C')
49
+ end
50
+
51
+ def pop_int8
52
+ data.slice!(0).unpack('C').first
53
+ end
54
+
55
+ # 16-bit integer
56
+
57
+ def push_int16(v)
58
+ self.data += [v].pack('S<')
59
+ end
60
+
61
+ def pop_int16
62
+ data.slice!(0..1).unpack('S<').first
63
+ end
64
+
65
+ # 32-bit integer
66
+
67
+ def push_int32(v)
68
+ self.data += [v].pack('L<')
69
+ end
70
+
71
+ def pop_int32
72
+ data.slice!(0..1).unpack('L<').first
73
+ end
74
+
75
+ # Frames
76
+
77
+ def push_frame(frame)
78
+ push_int16(frame.size)
79
+ self.data += frame.data
80
+ end
81
+
82
+ def pop_frame
83
+ frame_size = pop_int16
84
+ Frame.new(data.slice!(0..frame_size-1))
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,11 @@
1
+ module Samsung
2
+ module Protocol
3
+ class HeaderFrame < Frame
4
+ def initialize(app_name)
5
+ super()
6
+ push_int8(0)
7
+ push_string(app_name)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Samsung
2
+ module Protocol
3
+ class KeyFrame < Frame
4
+ def initialize(key)
5
+ super()
6
+ push_int8(0)
7
+ push_int8(0)
8
+ push_int8(0)
9
+ push_string64(key)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ module Samsung
2
+ module Protocol
3
+ class Response < Frame
4
+ attr_accessor :code, :app_name, :response_frame
5
+
6
+ def initialize data
7
+ @data = data
8
+ parse_response
9
+ end
10
+
11
+ def response_type
12
+ return :wait if r[0].ord == 0x0a
13
+ return :timeout if r[0].ord == 0x65
14
+ return :accepted if r[0].ord == 0x64 and r[2].ord == 0x01
15
+ return :rejected if r[0].ord == 0x64 and r[2].ord == 0x02
16
+ return :unknown
17
+ end
18
+
19
+ private
20
+
21
+ def parse_response
22
+ self.code = pop_int8
23
+ self.app_name = pop_string
24
+ self.response_frame = pop_frame
25
+ end
26
+
27
+ def r
28
+ response_frame.data
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,63 @@
1
+ require 'socket'
2
+
3
+ module Samsung
4
+ class Remote
5
+ PORT = 55000
6
+ APP_NAME = "net.kapati.samsung.remote"
7
+
8
+ attr_accessor :display_name, :ip
9
+
10
+ def initialize(ip, display_name = "Ruby")
11
+ self.ip = ip
12
+ self.display_name = display_name
13
+ connect
14
+ send_auth
15
+ end
16
+
17
+ def has_data?(wait = 0)
18
+ ready = IO.select([@socket], nil, nil, wait)
19
+ return ready != nil
20
+ end
21
+
22
+ def peek_frame(wait = 1)
23
+ return nil unless has_data?(wait)
24
+ read_frame
25
+ end
26
+
27
+ def read_frame
28
+ data = @socket.readpartial(512)
29
+ Protocol::Response.new(data)
30
+ end
31
+
32
+ def connect
33
+ @socket = TCPSocket.open ip, PORT
34
+ end
35
+
36
+ def send_frame(frame)
37
+ f = build_header
38
+ f.push_frame(frame)
39
+ @socket.write(f.data)
40
+ end
41
+
42
+ def send_key key_code
43
+ send_frame(Protocol::KeyFrame.new(key_code))
44
+ end
45
+
46
+ def send_auth
47
+ net = Network.new
48
+ send_frame(
49
+ Protocol::AuthFrame.new(
50
+ net.local_ip,
51
+ net.local_hw_address,
52
+ display_name
53
+ )
54
+ )
55
+ end
56
+
57
+ private
58
+
59
+ def build_header
60
+ Protocol::HeaderFrame.new(APP_NAME)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "samsung"
3
+ s.version = "1.0"
4
+ s.date = "2014-10-04"
5
+ s.summary = "Remote control for Samsung SmartTV."
6
+ s.description = "Control your Samsung StartTV with Ruby code"
7
+ s.authors = ["Robert Nasiadek"]
8
+ s.files = [
9
+ "init.rb",
10
+ "lib/samsung.rb",
11
+ "lib/samsung/remote.rb",
12
+ "lib/samsung/protocol.rb",
13
+ "lib/samsung/network.rb",
14
+ "lib/samsung/protocol/frame.rb",
15
+ "lib/samsung/protocol/key_frame.rb",
16
+ "lib/samsung/protocol/auth_frame.rb",
17
+ "lib/samsung/protocol/header_frame.rb",
18
+ "lib/samsung/protocol/response.rb",
19
+ "README.rdoc",
20
+ "samsung.gemspec"
21
+ ]
22
+ s.email = "robert@kapati.net"
23
+ s.homepage = "http://robzon.pl/"
24
+ s.license = "MIT"
25
+
26
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: samsung
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Robert Nasiadek
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Control your Samsung StartTV with Ruby code
14
+ email: robert@kapati.net
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.rdoc
20
+ - init.rb
21
+ - lib/samsung.rb
22
+ - lib/samsung/network.rb
23
+ - lib/samsung/protocol.rb
24
+ - lib/samsung/protocol/auth_frame.rb
25
+ - lib/samsung/protocol/frame.rb
26
+ - lib/samsung/protocol/header_frame.rb
27
+ - lib/samsung/protocol/key_frame.rb
28
+ - lib/samsung/protocol/response.rb
29
+ - lib/samsung/remote.rb
30
+ - samsung.gemspec
31
+ homepage: http://robzon.pl/
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.2.1
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Remote control for Samsung SmartTV.
55
+ test_files: []