itach 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/itach +29 -0
- data/lib/itach.rb +14 -0
- data/lib/itach/config.rb +30 -0
- data/lib/itach/detect.rb +62 -0
- data/lib/itach/remote.rb +100 -0
- data/lib/itach/version.rb +3 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a779a8cea99eb32c4c551ae4253b7443be72816f
|
4
|
+
data.tar.gz: f52417816e9e1cfd0b3eb312a1303324f3a0395e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 753167f776f9c2ea1620e491530db42d378183f60255403a9ea5c8fd47d60750e4341016160ec63f2456139d44b266e84bef8fa12091359e3cc6314ec4f30670
|
7
|
+
data.tar.gz: 8d9d5d017bdb4a8f54dcf42a924a9bb71bb8aa483373d3b8161eb4535879cf9f6fdeae6005eafa921cc4d9b3e94826fc58a0d20c32ae94d41a945b81e68ee73f
|
data/bin/itach
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
4
|
+
|
5
|
+
require 'itach'
|
6
|
+
|
7
|
+
@command = ARGV[0]
|
8
|
+
@repeat = ARGV[2] && ARGV[2].to_i || 1
|
9
|
+
@remote = ITACH::Remote.new
|
10
|
+
|
11
|
+
case @command
|
12
|
+
when "send"
|
13
|
+
if ARGV[1] =~ /combo/
|
14
|
+
@remote.send_combo ARGV[1]
|
15
|
+
else
|
16
|
+
@remote.send_command ARGV[1], @repeat
|
17
|
+
end
|
18
|
+
when "detect"
|
19
|
+
@detect = ITACH::Detect.new
|
20
|
+
puts @detect.find_device
|
21
|
+
when "update"
|
22
|
+
ITACH::Config.update
|
23
|
+
when "list"
|
24
|
+
puts @remote.available_actions
|
25
|
+
when "learn"
|
26
|
+
@remote.learn(true)
|
27
|
+
@remote.get_learning_responses { |resp| puts "ir_string = #{resp.inspect}" }
|
28
|
+
end
|
29
|
+
|
data/lib/itach.rb
ADDED
data/lib/itach/config.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module ITACH
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
@@config_path = ENV['ITACH_CONFIG'] || ENV['HOME'] + "/.itach.yml"
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def load
|
12
|
+
begin
|
13
|
+
YAML.load_file(@@config_path)
|
14
|
+
rescue Errno::ENOENT
|
15
|
+
puts "No config file found in #{@@config_path}. Add one there or set the ITACH_CONFIG variable in your environment."
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def update
|
21
|
+
config = load
|
22
|
+
config["RECEIVER"]["ip"] = Detect.ip
|
23
|
+
File.open(@@config_path, 'w') { |f| f.write config.to_yaml }
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/itach/detect.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module ITACH
|
2
|
+
|
3
|
+
class Detect
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_reader :ip
|
7
|
+
|
8
|
+
def ip
|
9
|
+
begin
|
10
|
+
@@ip
|
11
|
+
rescue
|
12
|
+
Detect.new.find_device
|
13
|
+
@@ip
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize options={}
|
19
|
+
@address = ENV['ITACH_ADDRESS'] || '239.255.250.250'
|
20
|
+
@port = ENV['ITACH_PORT'] || 9131
|
21
|
+
@timeout = options[:timeout] || 20
|
22
|
+
end
|
23
|
+
|
24
|
+
def ip
|
25
|
+
@ip ||= IPAddr.new(@address).hton + IPAddr.new("0.0.0.0").hton
|
26
|
+
end
|
27
|
+
|
28
|
+
def socket
|
29
|
+
begin
|
30
|
+
@socket = UDPSocket.new
|
31
|
+
@socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip)
|
32
|
+
@socket
|
33
|
+
rescue Errno::EADDRINUSE
|
34
|
+
@socket.close
|
35
|
+
socket
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_device
|
40
|
+
begin
|
41
|
+
Timeout::timeout(@timeout) do
|
42
|
+
begin
|
43
|
+
socket.bind(Socket::INADDR_ANY, @port)
|
44
|
+
loop do
|
45
|
+
msg, info = @socket.recvfrom(1024)
|
46
|
+
if info
|
47
|
+
@@ip = info[2]
|
48
|
+
return "iTach found at #{info[2]}."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
ensure
|
52
|
+
@socket.close
|
53
|
+
end
|
54
|
+
end
|
55
|
+
rescue Timeout::Error
|
56
|
+
puts "An iTach device was not fount within #{@timeout} seconds."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/itach/remote.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
module ITACH
|
2
|
+
|
3
|
+
class Remote
|
4
|
+
|
5
|
+
def initialize options={}
|
6
|
+
@config = Config.load
|
7
|
+
end
|
8
|
+
|
9
|
+
def address
|
10
|
+
@config['RECEIVER']['ip']
|
11
|
+
end
|
12
|
+
|
13
|
+
def port
|
14
|
+
@config['RECEIVER']['port']
|
15
|
+
end
|
16
|
+
|
17
|
+
def connected?
|
18
|
+
!!socket
|
19
|
+
end
|
20
|
+
|
21
|
+
def socket
|
22
|
+
@socket ||= TCPSocket.new address, port
|
23
|
+
end
|
24
|
+
|
25
|
+
def remote_exists? remote
|
26
|
+
@config['REMOTES'].keys.include?(remote)
|
27
|
+
end
|
28
|
+
|
29
|
+
def combo_exists? combo
|
30
|
+
@config['COMBOS'].keys.include?(combo.split("_").last)
|
31
|
+
end
|
32
|
+
|
33
|
+
def command_exists? command
|
34
|
+
remote, command, *action = command.split("_")
|
35
|
+
command = [command, action].join('_') unless action.empty?
|
36
|
+
raise RuntimeError, "No remote defined for #{remote}" unless remote_exists? remote
|
37
|
+
return true if @config['REMOTES'][remote].keys.include? command
|
38
|
+
raise RuntimeError, "No command #{command} defined for #{remote}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_command command, repeat = 1
|
42
|
+
if command_exists? command
|
43
|
+
remote, command, *action = command.split("_")
|
44
|
+
command = [command, action].join('_') unless action.empty?
|
45
|
+
repeat.times do
|
46
|
+
socket.puts "sendir,#{@config['REMOTES'][remote][command]}\r"
|
47
|
+
puts read_from_unblock_to_block
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def send_combo combo
|
53
|
+
raise RuntimeError, "No combo #{combo} defined." unless combo_exists? combo
|
54
|
+
@config['COMBOS'][combo.split("_").last].map { |c| send_command c }
|
55
|
+
end
|
56
|
+
|
57
|
+
def learn(state)
|
58
|
+
load_config
|
59
|
+
if state
|
60
|
+
socket.puts ("get_IRL\r")
|
61
|
+
puts "IR Learner Enabled\r"
|
62
|
+
else
|
63
|
+
socket.puts("stop_IRL\r")
|
64
|
+
puts "IR Learner Disabled\r"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_learning_responses(&block)
|
69
|
+
while connected?
|
70
|
+
str = ""
|
71
|
+
until str[-2..-1] == "\r\n"
|
72
|
+
str << read_block(1)
|
73
|
+
end
|
74
|
+
yield str
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def read(bytes)
|
81
|
+
socket.recv_nonblock(bytes)
|
82
|
+
rescue Errno::EAGAIN
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def read_block(bytes)
|
87
|
+
socket.recv(bytes)
|
88
|
+
end
|
89
|
+
|
90
|
+
def read_from_unblock_to_block
|
91
|
+
sleep(0.01) until result = read(1)
|
92
|
+
while byte = read(1)
|
93
|
+
result << byte
|
94
|
+
end
|
95
|
+
result.strip
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: itach
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- rob allen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dotenv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.1
|
27
|
+
description: A Ruby cli interface for the iTach IP to IR device
|
28
|
+
email: rob.all3n@gmail.com
|
29
|
+
executables:
|
30
|
+
- itach
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- bin/itach
|
35
|
+
- lib/itach.rb
|
36
|
+
- lib/itach/config.rb
|
37
|
+
- lib/itach/detect.rb
|
38
|
+
- lib/itach/remote.rb
|
39
|
+
- lib/itach/version.rb
|
40
|
+
homepage: ''
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata: {}
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 2.5.1
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: A Ruby cli interface for the iTach IP to IR device
|
64
|
+
test_files: []
|