itach 0.0.1

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: a779a8cea99eb32c4c551ae4253b7443be72816f
4
+ data.tar.gz: f52417816e9e1cfd0b3eb312a1303324f3a0395e
5
+ SHA512:
6
+ metadata.gz: 753167f776f9c2ea1620e491530db42d378183f60255403a9ea5c8fd47d60750e4341016160ec63f2456139d44b266e84bef8fa12091359e3cc6314ec4f30670
7
+ data.tar.gz: 8d9d5d017bdb4a8f54dcf42a924a9bb71bb8aa483373d3b8161eb4535879cf9f6fdeae6005eafa921cc4d9b3e94826fc58a0d20c32ae94d41a945b81e68ee73f
@@ -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
+
@@ -0,0 +1,14 @@
1
+ require "itach/version"
2
+ require "itach/detect"
3
+ require "itach/config"
4
+ require "itach/remote"
5
+ require "timeout"
6
+ require "dotenv"
7
+ require "ipaddr"
8
+ require "socket"
9
+ require "yaml"
10
+
11
+ Dotenv.load
12
+
13
+ module ITACH
14
+ end
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ module ITACH
2
+ VERSION = "0.1.0"
3
+ 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: []