maxcube-client 0.4.0

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +32 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE.md +21 -0
  5. data/README.md +35 -0
  6. data/Rakefile +6 -0
  7. data/bin/console +8 -0
  8. data/bin/maxcube-client +31 -0
  9. data/bin/sample_server +13 -0
  10. data/bin/sample_socket +13 -0
  11. data/bin/setup +6 -0
  12. data/data/load/del +6 -0
  13. data/data/load/meta +20 -0
  14. data/data/load/ntp +6 -0
  15. data/data/load/set_temp +13 -0
  16. data/data/load/set_temp_mode +12 -0
  17. data/data/load/set_valve +11 -0
  18. data/data/load/url +4 -0
  19. data/data/load/wake +4 -0
  20. data/lib/maxcube/messages.rb +148 -0
  21. data/lib/maxcube/messages/handler.rb +154 -0
  22. data/lib/maxcube/messages/parser.rb +34 -0
  23. data/lib/maxcube/messages/serializer.rb +59 -0
  24. data/lib/maxcube/messages/tcp.rb +18 -0
  25. data/lib/maxcube/messages/tcp/handler.rb +70 -0
  26. data/lib/maxcube/messages/tcp/parser.rb +46 -0
  27. data/lib/maxcube/messages/tcp/serializer.rb +47 -0
  28. data/lib/maxcube/messages/tcp/type/a.rb +32 -0
  29. data/lib/maxcube/messages/tcp/type/c.rb +248 -0
  30. data/lib/maxcube/messages/tcp/type/f.rb +33 -0
  31. data/lib/maxcube/messages/tcp/type/h.rb +70 -0
  32. data/lib/maxcube/messages/tcp/type/l.rb +131 -0
  33. data/lib/maxcube/messages/tcp/type/m.rb +185 -0
  34. data/lib/maxcube/messages/tcp/type/n.rb +44 -0
  35. data/lib/maxcube/messages/tcp/type/q.rb +18 -0
  36. data/lib/maxcube/messages/tcp/type/s.rb +246 -0
  37. data/lib/maxcube/messages/tcp/type/t.rb +38 -0
  38. data/lib/maxcube/messages/tcp/type/u.rb +19 -0
  39. data/lib/maxcube/messages/tcp/type/z.rb +36 -0
  40. data/lib/maxcube/messages/udp.rb +9 -0
  41. data/lib/maxcube/messages/udp/handler.rb +40 -0
  42. data/lib/maxcube/messages/udp/parser.rb +50 -0
  43. data/lib/maxcube/messages/udp/serializer.rb +30 -0
  44. data/lib/maxcube/messages/udp/type/h.rb +24 -0
  45. data/lib/maxcube/messages/udp/type/i.rb +23 -0
  46. data/lib/maxcube/messages/udp/type/n.rb +21 -0
  47. data/lib/maxcube/network.rb +14 -0
  48. data/lib/maxcube/network/tcp.rb +11 -0
  49. data/lib/maxcube/network/tcp/client.rb +174 -0
  50. data/lib/maxcube/network/tcp/client/commands.rb +286 -0
  51. data/lib/maxcube/network/tcp/sample_server.rb +96 -0
  52. data/lib/maxcube/network/udp.rb +11 -0
  53. data/lib/maxcube/network/udp/client.rb +52 -0
  54. data/lib/maxcube/network/udp/sample_socket.rb +65 -0
  55. data/lib/maxcube/version.rb +4 -0
  56. data/maxcube-client.gemspec +29 -0
  57. metadata +155 -0
@@ -0,0 +1,96 @@
1
+ require 'maxcube/network/tcp'
2
+
3
+ module MaxCube
4
+ module Network
5
+ module TCP
6
+ class SampleServer
7
+ def initialize(port = PORT)
8
+ @port = port
9
+ @server = TCPServer.new(port)
10
+
11
+ @ntp_servers = %w[nl.pool.ntp.org ntp.homematic.com]
12
+ end
13
+
14
+ def run
15
+ puts "Starting server on port #{@port} ...\n\n"
16
+ loop do
17
+ Thread.start(@server.accept) do |client|
18
+ puts "Accepting #{client.addr[3]}:#{client.addr[1]} ..."
19
+ send_msg(client, msg_h)
20
+ send_msg(client, msg_l)
21
+ loop do
22
+ run_loop(client)
23
+ end
24
+ end
25
+ end
26
+ rescue Interrupt
27
+ close
28
+ end
29
+
30
+ def send_msg(client, msg)
31
+ client.puts(msg << "\r\n")
32
+ end
33
+
34
+ private
35
+
36
+ def run_loop(client)
37
+ msgs = client.gets
38
+ raise IOError unless msgs
39
+ msgs.split("\r\n").each do |msg|
40
+ raise IOError if msg == 'q:'
41
+ puts "Income message: '#{msg}'"
42
+ cmd(client, msg)
43
+ end
44
+ rescue IOError
45
+ puts "Closing #{client.addr[3]}:#{client.addr[1]} ..."
46
+ client.close
47
+ Thread.stop
48
+ end
49
+
50
+ def cmd(client, msg)
51
+ type, body = msg.split(':')
52
+ method_str = "msg_#{type}"
53
+ return unless respond_to?(method_str, true)
54
+ send_msg(client, method(method_str).call(body))
55
+ end
56
+
57
+ def msg_a(_body = nil)
58
+ 'A:'
59
+ end
60
+
61
+ alias msg_t msg_a
62
+ alias msg_z msg_a
63
+
64
+ def msg_c(_body = nil)
65
+ 'C:01b491,EQG0kQUAEg9KRVEwMzA1MjA1'
66
+ end
67
+
68
+ def msg_h(_body = nil)
69
+ 'H:KEQ0523864,097f2c,0113,00000000,477719c0,00,32,0d0c09,1404,03,0000'
70
+ end
71
+
72
+ def msg_l(_body = nil)
73
+ 'L:Cw/a7QkSGBgoAMwACw/DcwkSGBgoAM8ACw/DgAkSGBgoAM4A'
74
+ end
75
+
76
+ def msg_n(_body = nil)
77
+ 'N:Aw4VzExFUTAwMTUzNDD/'
78
+ end
79
+
80
+ def msg_f(body = nil)
81
+ @ntp_servers = body.split(',') if body
82
+ 'F:' + @ntp_servers.join(',')
83
+ end
84
+
85
+ def msg_s(_body = nil)
86
+ 'S:00,0,31'
87
+ end
88
+
89
+ def close
90
+ puts "\nClosing server ..."
91
+ @server.close
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,11 @@
1
+ require 'maxcube/network'
2
+ require 'maxcube/messages/udp/parser'
3
+ require 'maxcube/messages/udp/serializer'
4
+
5
+ module MaxCube
6
+ module Network
7
+ module UDP
8
+ PORT = 23_272
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,52 @@
1
+ require 'maxcube/network/udp'
2
+
3
+ module MaxCube
4
+ module Network
5
+ module UDP
6
+ class Client
7
+ def initialize(port = PORT)
8
+ @socket = UDPSocket.new
9
+ @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
10
+ @port = port
11
+
12
+ @parser = Messages::UDP::Parser.new
13
+ @serializer = Messages::UDP::Serializer.new
14
+ end
15
+
16
+ def send_msg(msg, addr = BROADCAST)
17
+ @socket.send(msg, 0, addr, @port)
18
+ end
19
+
20
+ def recv_msg
21
+ msg, addr = @socket.recvfrom(1024)
22
+ port = addr[1]
23
+ ipaddr = addr[3]
24
+ [msg, ipaddr, port]
25
+ rescue Interrupt
26
+ puts 'Aborted'
27
+ end
28
+
29
+ def send_recv_hash(hash, addr = BROADCAST)
30
+ msg = @serializer.serialize_udp_hash(hash)
31
+ send_msg(msg, addr)
32
+ msg, addr, port = recv_msg
33
+ return nil unless msg
34
+ hash = @parser.parse_udp_msg(msg)
35
+ puts "'#{hash[:type]}' response from #{addr}:#{port}:\n" \
36
+ "#{hash.to_yaml}\n"
37
+ hash
38
+ end
39
+
40
+ def discovery
41
+ puts "Starting discovery ...\n\n"
42
+ send_recv_hash(type: 'I')
43
+ end
44
+
45
+ def close
46
+ puts "\nClosing client ..."
47
+ @socket.close
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,65 @@
1
+ require 'maxcube/network/udp'
2
+
3
+ module MaxCube
4
+ module Network
5
+ module UDP
6
+ class SampleSocket
7
+ def initialize(port = PORT)
8
+ @port = port
9
+ @socket = UDPSocket.new
10
+ @socket.bind('0.0.0.0', port)
11
+
12
+ @parser = Messages::UDP::Parser.new
13
+ @serializer = Messages::UDP::Serializer.new
14
+ end
15
+
16
+ def run
17
+ puts "Starting socket on port #{@port} ...\n\n"
18
+ loop do
19
+ msg, addr = @socket.recvfrom(1024)
20
+ port = addr[1]
21
+ ipaddr = addr[3]
22
+ puts "Income message from #{ipaddr}:#{port}: '#{msg}'"
23
+ cmd(msg, ipaddr, port) if @serializer.valid_udp_msg(msg)
24
+ end
25
+ rescue Interrupt
26
+ close
27
+ end
28
+
29
+ def send_msg(msg, addr, port)
30
+ @socket.send(msg, 0, addr, port)
31
+ end
32
+
33
+ private
34
+
35
+ def cmd(msg, addr, port)
36
+ type = @serializer.check_msg_msg_type(msg)
37
+ puts "Message type: #{type}"
38
+
39
+ method_str = "msg_#{type.downcase}"
40
+ return unless respond_to?(method_str, true)
41
+ send_msg(send(method_str), addr, port)
42
+ end
43
+
44
+ def msg_i
45
+ "eQ3MaxApKEQ0523864>I\x00\x09\x7f\x2c\x01\x13"
46
+ end
47
+
48
+ def msg_n
49
+ 'eQ3MaxApKEQ0565026>N' \
50
+ "\xc0\xa8\x00\xde\xc0\xa8\x00\x01\xff\xff\x00\x00" \
51
+ "\xc0\xa8\x00\x01\xc0\xa8\x00\x01"
52
+ end
53
+
54
+ def msg_h
55
+ "eQ3MaxApKEQ0565026>h\x00Pmax.eq-3.de,/cube"
56
+ end
57
+
58
+ def close
59
+ puts "\nClosing socket ..."
60
+ @socket.close
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module MaxCube
3
+ VERSION = '0.4.0'.freeze
4
+ end
@@ -0,0 +1,29 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "maxcube/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "maxcube-client"
8
+ spec.version = MaxCube::VERSION
9
+ spec.authors = ["Tomáš Kolárik"]
10
+ spec.email = ["tomaqa@gmail.com"]
11
+
12
+ spec.summary = %q{Terminal client for eQ3/ELV MAX! Cube devices written in Ruby.}
13
+ spec.homepage = "https://github.com/Tomaqa/ruby-maxcube-client"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.required_ruby_version = '>= 2.2'
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.16"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ spec.add_development_dependency "rubocop", "~> 0.50"
29
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: maxcube-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Tomáš Kolárik
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.50'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.50'
69
+ description:
70
+ email:
71
+ - tomaqa@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".rubocop.yml"
77
+ - Gemfile
78
+ - LICENSE.md
79
+ - README.md
80
+ - Rakefile
81
+ - bin/console
82
+ - bin/maxcube-client
83
+ - bin/sample_server
84
+ - bin/sample_socket
85
+ - bin/setup
86
+ - data/load/del
87
+ - data/load/meta
88
+ - data/load/ntp
89
+ - data/load/set_temp
90
+ - data/load/set_temp_mode
91
+ - data/load/set_valve
92
+ - data/load/url
93
+ - data/load/wake
94
+ - lib/maxcube/messages.rb
95
+ - lib/maxcube/messages/handler.rb
96
+ - lib/maxcube/messages/parser.rb
97
+ - lib/maxcube/messages/serializer.rb
98
+ - lib/maxcube/messages/tcp.rb
99
+ - lib/maxcube/messages/tcp/handler.rb
100
+ - lib/maxcube/messages/tcp/parser.rb
101
+ - lib/maxcube/messages/tcp/serializer.rb
102
+ - lib/maxcube/messages/tcp/type/a.rb
103
+ - lib/maxcube/messages/tcp/type/c.rb
104
+ - lib/maxcube/messages/tcp/type/f.rb
105
+ - lib/maxcube/messages/tcp/type/h.rb
106
+ - lib/maxcube/messages/tcp/type/l.rb
107
+ - lib/maxcube/messages/tcp/type/m.rb
108
+ - lib/maxcube/messages/tcp/type/n.rb
109
+ - lib/maxcube/messages/tcp/type/q.rb
110
+ - lib/maxcube/messages/tcp/type/s.rb
111
+ - lib/maxcube/messages/tcp/type/t.rb
112
+ - lib/maxcube/messages/tcp/type/u.rb
113
+ - lib/maxcube/messages/tcp/type/z.rb
114
+ - lib/maxcube/messages/udp.rb
115
+ - lib/maxcube/messages/udp/handler.rb
116
+ - lib/maxcube/messages/udp/parser.rb
117
+ - lib/maxcube/messages/udp/serializer.rb
118
+ - lib/maxcube/messages/udp/type/h.rb
119
+ - lib/maxcube/messages/udp/type/i.rb
120
+ - lib/maxcube/messages/udp/type/n.rb
121
+ - lib/maxcube/network.rb
122
+ - lib/maxcube/network/tcp.rb
123
+ - lib/maxcube/network/tcp/client.rb
124
+ - lib/maxcube/network/tcp/client/commands.rb
125
+ - lib/maxcube/network/tcp/sample_server.rb
126
+ - lib/maxcube/network/udp.rb
127
+ - lib/maxcube/network/udp/client.rb
128
+ - lib/maxcube/network/udp/sample_socket.rb
129
+ - lib/maxcube/version.rb
130
+ - maxcube-client.gemspec
131
+ homepage: https://github.com/Tomaqa/ruby-maxcube-client
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '2.2'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.7.3
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Terminal client for eQ3/ELV MAX! Cube devices written in Ruby.
155
+ test_files: []