itach 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []