ruby_home 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.hound.yml +2 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +9 -0
  6. data/.travis.yml +21 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE +21 -0
  9. data/README.md +36 -0
  10. data/Rakefile +7 -0
  11. data/bin/console +14 -0
  12. data/bin/rubyhome +16 -0
  13. data/bin/setup +8 -0
  14. data/lib/ruby_home.rb +6 -0
  15. data/lib/ruby_home/accessory_info.rb +99 -0
  16. data/lib/ruby_home/broadcast.rb +31 -0
  17. data/lib/ruby_home/config/characteristics.yml +1692 -0
  18. data/lib/ruby_home/config/services.yml +416 -0
  19. data/lib/ruby_home/device_id.rb +30 -0
  20. data/lib/ruby_home/dns/service.rb +44 -0
  21. data/lib/ruby_home/dns/text_record.rb +100 -0
  22. data/lib/ruby_home/factories/accessory_factory.rb +78 -0
  23. data/lib/ruby_home/factories/characteristic_factory.rb +57 -0
  24. data/lib/ruby_home/factories/templates/characteristic_template.rb +43 -0
  25. data/lib/ruby_home/factories/templates/service_template.rb +50 -0
  26. data/lib/ruby_home/hap/accessory.rb +26 -0
  27. data/lib/ruby_home/hap/characteristic.rb +60 -0
  28. data/lib/ruby_home/hap/hex_pad.rb +13 -0
  29. data/lib/ruby_home/hap/hkdf_encryption.rb +34 -0
  30. data/lib/ruby_home/hap/http_decryption.rb +58 -0
  31. data/lib/ruby_home/hap/http_encryption.rb +43 -0
  32. data/lib/ruby_home/hap/service.rb +38 -0
  33. data/lib/ruby_home/http/application.rb +28 -0
  34. data/lib/ruby_home/http/cache.rb +30 -0
  35. data/lib/ruby_home/http/controllers/accessories_controller.rb +19 -0
  36. data/lib/ruby_home/http/controllers/application_controller.rb +37 -0
  37. data/lib/ruby_home/http/controllers/characteristics_controller.rb +49 -0
  38. data/lib/ruby_home/http/controllers/pair_setups_controller.rb +146 -0
  39. data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +81 -0
  40. data/lib/ruby_home/http/controllers/pairings_controller.rb +38 -0
  41. data/lib/ruby_home/http/hap_request.rb +56 -0
  42. data/lib/ruby_home/http/hap_response.rb +57 -0
  43. data/lib/ruby_home/http/hap_server.rb +65 -0
  44. data/lib/ruby_home/http/serializers/accessory_serializer.rb +21 -0
  45. data/lib/ruby_home/http/serializers/characteristic_serializer.rb +26 -0
  46. data/lib/ruby_home/http/serializers/characteristic_value_serializer.rb +21 -0
  47. data/lib/ruby_home/http/serializers/object_serializer.rb +39 -0
  48. data/lib/ruby_home/http/serializers/service_serializer.rb +20 -0
  49. data/lib/ruby_home/identifier_cache.rb +59 -0
  50. data/lib/ruby_home/rack/handler/hap_server.rb +26 -0
  51. data/lib/ruby_home/tlv.rb +83 -0
  52. data/lib/ruby_home/tlv/bytes.rb +19 -0
  53. data/lib/ruby_home/tlv/int.rb +15 -0
  54. data/lib/ruby_home/tlv/utf8.rb +18 -0
  55. data/lib/ruby_home/version.rb +3 -0
  56. data/rubyhome.gemspec +43 -0
  57. data/sbin/characteristic_generator.rb +83 -0
  58. data/sbin/service_generator.rb +69 -0
  59. metadata +352 -0
@@ -0,0 +1,26 @@
1
+ require 'webrick'
2
+ require_relative '../../http/hap_server'
3
+
4
+ module RubyHome
5
+ module Rack
6
+ module Handler
7
+ class HAPServer < ::Rack::Handler::WEBrick
8
+ def self.run(app, options={})
9
+ environment = ENV['RACK_ENV'] || 'development'
10
+ default_host = environment == 'development' ? 'localhost' : nil
11
+
12
+ options[:BindAddress] = options.delete(:Host) || default_host
13
+ options[:Port] ||= 8080
14
+ unless ENV['DEBUG']
15
+ options[:Logger] = WEBrick::Log.new("/dev/null")
16
+ options[:AccessLog] = []
17
+ end
18
+ @server = HTTP::HAPServer.new(options)
19
+ @server.mount '/', Handler::HAPServer, app
20
+ yield @server if block_given?
21
+ @server.start
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,83 @@
1
+ Dir[File.dirname(__FILE__) + '/tlv/*.rb'].each {|file| require file }
2
+
3
+ module RubyHome
4
+ module TLV
5
+ extend self
6
+
7
+ TLV = Struct.new(:type, :name, :handler)
8
+ TLVs = [
9
+ TLV.new('00', 'kTLVType_Method', Int),
10
+ TLV.new('01', 'kTLVType_Identifier', Utf8),
11
+ TLV.new('02', 'kTLVType_Salt', Bytes),
12
+ TLV.new('03', 'kTLVType_PublicKey', Bytes),
13
+ TLV.new('04', 'kTLVType_Proof', Bytes),
14
+ TLV.new('05', 'kTLVType_EncryptedData', Bytes),
15
+ TLV.new('06', 'kTLVType_State', Int),
16
+ TLV.new('07', 'kTLVType_Error', Int),
17
+ TLV.new('08', 'kTLVType_RetryDelay', Int),
18
+ TLV.new('09', 'kTLVType_Certificate', Bytes),
19
+ TLV.new('0a', 'kTLVType_Signature', Bytes),
20
+ TLV.new('0b', 'kTLVType_Permissions', Int),
21
+ TLV.new('0c', 'kTLVType_FragmentData', Bytes),
22
+ TLV.new('0d', 'kTLVType_FragmentLast', Bytes),
23
+ ].freeze
24
+
25
+ def pack(hash)
26
+ data = ''
27
+
28
+ pack_objects(hash).each do |type, value|
29
+ value.chars.each_slice(510).map(&:join).each do |value_slice|
30
+ length = Int.pack([value_slice].pack('H*').length)
31
+
32
+ data << type
33
+ data << length
34
+ data << value_slice
35
+ end
36
+ end
37
+
38
+ [data].pack('H*')
39
+ end
40
+
41
+ def pack_objects(objects)
42
+ objects.each_with_object({}) do |(unpacked_key, unpacked_value), memo|
43
+ tlv_value = TLVs.find { |tlv| tlv.name == unpacked_key }
44
+ packed_key = tlv_value.type
45
+ packed_value = tlv_value.handler.pack(unpacked_value)
46
+ memo[packed_key] = packed_value
47
+ end
48
+ end
49
+
50
+ def unpack(input)
51
+ data = input.unpack('H*')[0]
52
+ objects = {}
53
+ scanner_index = 0
54
+
55
+ while scanner_index < data.length do
56
+ type = data[scanner_index, 2]
57
+ scanner_index += 2
58
+
59
+ byte_length = Int.unpack(data[scanner_index, 2]) * 2
60
+ scanner_index += 2
61
+
62
+ newData = data[scanner_index, byte_length]
63
+ if objects[type]
64
+ objects[type] << newData
65
+ else
66
+ objects[type] = newData
67
+ end
68
+ scanner_index += byte_length
69
+ end
70
+
71
+ unpack_objects(objects)
72
+ end
73
+
74
+ def unpack_objects(objects)
75
+ objects.each_with_object({}) do |(packed_key, packed_value), memo|
76
+ tlv_value = TLVs.find { |tlv| tlv.type == packed_key }
77
+ unpacked_key = tlv_value.name
78
+ unpacked_value = tlv_value.handler.unpack(packed_value)
79
+ memo[unpacked_key] = unpacked_value
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,19 @@
1
+ module RubyHome
2
+ module TLV
3
+ module Bytes
4
+ extend self
5
+
6
+ def pack(input)
7
+ if input.length.odd?
8
+ input.insert(0, '0')
9
+ else
10
+ input
11
+ end
12
+ end
13
+
14
+ def unpack(input)
15
+ input
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module RubyHome
2
+ module TLV
3
+ module Int
4
+ extend self
5
+
6
+ def pack(input)
7
+ [input].pack('C*').unpack1('H*')
8
+ end
9
+
10
+ def unpack(input)
11
+ [input].pack('H*').unpack1('C*')
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module RubyHome
2
+ module TLV
3
+ module Utf8
4
+ extend self
5
+
6
+ def pack(input)
7
+ input.bytes.map { |b| b.to_s(16) }.join
8
+ end
9
+
10
+ def unpack(input)
11
+ [input]
12
+ .pack('H*')
13
+ .force_encoding('utf-8')
14
+ .encode('utf-8')
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module RubyHome
2
+ VERSION = '0.1.0'
3
+ end
data/rubyhome.gemspec ADDED
@@ -0,0 +1,43 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ruby_home/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'ruby_home'
8
+ spec.version = RubyHome::VERSION
9
+ spec.authors = ['Karl Entwistle']
10
+ spec.email = ['karl@entwistle.com']
11
+ spec.summary = 'Ruby HomeKit support'
12
+ spec.description = <<~DESCRIPTION
13
+ RubyHome is a lightweight service you can run on your home network that
14
+ emulates the iOS HomeKit API. It supports community contributed plugins, which
15
+ are modules that provide a bridge from HomeKit to various 3rd-party APIs
16
+ provided by manufacturers of smart home devices.
17
+ DESCRIPTION
18
+ spec.homepage = 'https://github.com/karlentwistle/ruby_home'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+ spec.bindir = 'exe'
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.add_dependency 'dnssd', '~> 3.0'
28
+ spec.add_dependency 'ed25519', '~> 1.2', '>= 1.2.3'
29
+ spec.add_dependency 'hkdf', '~> 0.3.0'
30
+ spec.add_dependency 'oj', '~> 3.4'
31
+ spec.add_dependency 'rbnacl', '~> 5.0'
32
+ spec.add_dependency 'rbnacl-libsodium', '~> 1.0', '>= 1.0.16'
33
+ spec.add_dependency 'ruby_home-srp', '~> 1.1.1'
34
+ spec.add_dependency 'sinatra', '~> 2.0'
35
+ spec.add_dependency 'wisper', '~> 1.6', '>= 1.6.1'
36
+ spec.add_dependency 'x25519', '~> 1.0', '>= 1.0.5'
37
+ spec.add_development_dependency 'bundler', '~> 1.16'
38
+ spec.add_development_dependency 'byebug', '~> 10.0'
39
+ spec.add_development_dependency 'plist', '~> 3.4'
40
+ spec.add_development_dependency 'rack-test', '~> 1.0.0'
41
+ spec.add_development_dependency 'rake', '~> 12.3'
42
+ spec.add_development_dependency 'rspec', '~> 3.0'
43
+ end
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'byebug'
4
+ require 'plist'
5
+ require 'yaml'
6
+
7
+ module RubyHome
8
+ class CharacteristicGenerator
9
+ class << self
10
+ def run
11
+ convert_binary_plist
12
+ File.open(file_path, 'w') do |file|
13
+ file.write generate_characteristics.to_yaml
14
+ end
15
+ end
16
+
17
+ def generate_characteristics
18
+ parsed_xml['Characteristics'].map do |characteristics_xml|
19
+ new(characteristics_xml).generate_characteristic_hash
20
+ end
21
+ end
22
+
23
+ def convert_binary_plist
24
+ system([
25
+ 'plutil -convert xml1 -o',
26
+ '/tmp/Accessory.xml',
27
+ "\'/Applications/Utilities/HomeKit\ Accessory\ Simulator.app/Contents/Frameworks/HAPAccessoryKit.framework/Versions/A/Resources/default.metadata.plist\'"
28
+ ].join(' '))
29
+ end
30
+
31
+ def parsed_xml
32
+ Plist.parse_xml('/tmp/Accessory.xml')
33
+ end
34
+
35
+ def file_path
36
+ File.dirname(__FILE__) + '/../lib/ruby_home/config/characteristics.yml'
37
+ end
38
+ end
39
+
40
+ def initialize(xml)
41
+ @constraints = xml["Constraints"]
42
+ @format = xml["Format"]
43
+ @name = xml["Name"]
44
+ @permissions = xml["Permissions"]
45
+ @properties = xml["Properties"]
46
+ @uuid = xml["UUID"]
47
+ @unit = xml["Unit"]
48
+ end
49
+
50
+ def generate_characteristic_hash
51
+ {
52
+ name: sanitized_name.to_sym,
53
+ description: name,
54
+ uuid: uuid,
55
+ format: format,
56
+ unit: sanitized_unit,
57
+ permissions: permissions,
58
+ properties: properties,
59
+ constraints: constraints,
60
+ }
61
+ end
62
+
63
+ private
64
+
65
+ def sanitized_name
66
+ name.downcase.gsub(' ', '_').gsub('.', '_')
67
+ end
68
+
69
+ def sanitized_unit
70
+ if unit
71
+ "\"#{unit}\""
72
+ else
73
+ "nil"
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ attr_reader :constraints, :format, :name, :permissions, :properties, :uuid, :unit
80
+ end
81
+ end
82
+
83
+ RubyHome::CharacteristicGenerator.run
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'byebug'
4
+ require 'plist'
5
+ require 'yaml'
6
+
7
+ module RubyHome
8
+ class ServiceGenerator
9
+ class << self
10
+ def run
11
+ convert_binary_plist
12
+ File.open(file_path, 'w') do |file|
13
+ file.write generate_services.to_yaml
14
+ end
15
+ end
16
+
17
+ def generate_services
18
+ parsed_xml['Services'].map do |services_xml|
19
+ new(services_xml).generate_service_hash
20
+ end
21
+ end
22
+
23
+ def convert_binary_plist
24
+ system([
25
+ 'plutil -convert xml1 -o',
26
+ '/tmp/Accessory.xml',
27
+ "\'/Applications/Utilities/HomeKit\ Accessory\ Simulator.app/Contents/Frameworks/HAPAccessoryKit.framework/Versions/A/Resources/default.metadata.plist\'"
28
+ ].join(' '))
29
+ end
30
+
31
+ def parsed_xml
32
+ Plist.parse_xml('/tmp/Accessory.xml')
33
+ end
34
+
35
+ def file_path
36
+ File.dirname(__FILE__) + '/../lib/ruby_home/config/services.yml'
37
+ end
38
+ end
39
+
40
+ def initialize(xml)
41
+ @name = xml["Name"]
42
+ @optional_characteristics = xml["OptionalCharacteristics"]
43
+ @required_characteristics = xml["RequiredCharacteristics"]
44
+ @uuid = xml["UUID"]
45
+ end
46
+
47
+ def generate_service_hash
48
+ {
49
+ name: sanitized_name.to_sym,
50
+ description: name,
51
+ uuid: uuid,
52
+ optional_characteristics_uuids: optional_characteristics,
53
+ required_characteristics_uuids: required_characteristics,
54
+ }
55
+ end
56
+
57
+ private
58
+
59
+ def sanitized_name
60
+ name.downcase.gsub(' ', '_')
61
+ end
62
+
63
+ private
64
+
65
+ attr_reader :name, :optional_characteristics, :required_characteristics, :uuid
66
+ end
67
+ end
68
+
69
+ RubyHome::ServiceGenerator.run
metadata ADDED
@@ -0,0 +1,352 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_home
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Karl Entwistle
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dnssd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ed25519
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.2.3
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.2'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.2.3
47
+ - !ruby/object:Gem::Dependency
48
+ name: hkdf
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.3.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.3.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: oj
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.4'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.4'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rbnacl
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rbnacl-libsodium
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.0'
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 1.0.16
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '1.0'
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 1.0.16
109
+ - !ruby/object:Gem::Dependency
110
+ name: ruby_home-srp
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: 1.1.1
116
+ type: :runtime
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: 1.1.1
123
+ - !ruby/object:Gem::Dependency
124
+ name: sinatra
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '2.0'
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '2.0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: wisper
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '1.6'
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 1.6.1
147
+ type: :runtime
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '1.6'
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: 1.6.1
157
+ - !ruby/object:Gem::Dependency
158
+ name: x25519
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: '1.0'
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: 1.0.5
167
+ type: :runtime
168
+ prerelease: false
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.0'
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: 1.0.5
177
+ - !ruby/object:Gem::Dependency
178
+ name: bundler
179
+ requirement: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - "~>"
182
+ - !ruby/object:Gem::Version
183
+ version: '1.16'
184
+ type: :development
185
+ prerelease: false
186
+ version_requirements: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - "~>"
189
+ - !ruby/object:Gem::Version
190
+ version: '1.16'
191
+ - !ruby/object:Gem::Dependency
192
+ name: byebug
193
+ requirement: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - "~>"
196
+ - !ruby/object:Gem::Version
197
+ version: '10.0'
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ requirements:
202
+ - - "~>"
203
+ - !ruby/object:Gem::Version
204
+ version: '10.0'
205
+ - !ruby/object:Gem::Dependency
206
+ name: plist
207
+ requirement: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - "~>"
210
+ - !ruby/object:Gem::Version
211
+ version: '3.4'
212
+ type: :development
213
+ prerelease: false
214
+ version_requirements: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - "~>"
217
+ - !ruby/object:Gem::Version
218
+ version: '3.4'
219
+ - !ruby/object:Gem::Dependency
220
+ name: rack-test
221
+ requirement: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - "~>"
224
+ - !ruby/object:Gem::Version
225
+ version: 1.0.0
226
+ type: :development
227
+ prerelease: false
228
+ version_requirements: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - "~>"
231
+ - !ruby/object:Gem::Version
232
+ version: 1.0.0
233
+ - !ruby/object:Gem::Dependency
234
+ name: rake
235
+ requirement: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - "~>"
238
+ - !ruby/object:Gem::Version
239
+ version: '12.3'
240
+ type: :development
241
+ prerelease: false
242
+ version_requirements: !ruby/object:Gem::Requirement
243
+ requirements:
244
+ - - "~>"
245
+ - !ruby/object:Gem::Version
246
+ version: '12.3'
247
+ - !ruby/object:Gem::Dependency
248
+ name: rspec
249
+ requirement: !ruby/object:Gem::Requirement
250
+ requirements:
251
+ - - "~>"
252
+ - !ruby/object:Gem::Version
253
+ version: '3.0'
254
+ type: :development
255
+ prerelease: false
256
+ version_requirements: !ruby/object:Gem::Requirement
257
+ requirements:
258
+ - - "~>"
259
+ - !ruby/object:Gem::Version
260
+ version: '3.0'
261
+ description: |
262
+ RubyHome is a lightweight service you can run on your home network that
263
+ emulates the iOS HomeKit API. It supports community contributed plugins, which
264
+ are modules that provide a bridge from HomeKit to various 3rd-party APIs
265
+ provided by manufacturers of smart home devices.
266
+ email:
267
+ - karl@entwistle.com
268
+ executables: []
269
+ extensions: []
270
+ extra_rdoc_files: []
271
+ files:
272
+ - ".gitignore"
273
+ - ".hound.yml"
274
+ - ".rspec"
275
+ - ".rubocop.yml"
276
+ - ".travis.yml"
277
+ - Gemfile
278
+ - LICENSE
279
+ - README.md
280
+ - Rakefile
281
+ - bin/console
282
+ - bin/rubyhome
283
+ - bin/setup
284
+ - lib/ruby_home.rb
285
+ - lib/ruby_home/accessory_info.rb
286
+ - lib/ruby_home/broadcast.rb
287
+ - lib/ruby_home/config/characteristics.yml
288
+ - lib/ruby_home/config/services.yml
289
+ - lib/ruby_home/device_id.rb
290
+ - lib/ruby_home/dns/service.rb
291
+ - lib/ruby_home/dns/text_record.rb
292
+ - lib/ruby_home/factories/accessory_factory.rb
293
+ - lib/ruby_home/factories/characteristic_factory.rb
294
+ - lib/ruby_home/factories/templates/characteristic_template.rb
295
+ - lib/ruby_home/factories/templates/service_template.rb
296
+ - lib/ruby_home/hap/accessory.rb
297
+ - lib/ruby_home/hap/characteristic.rb
298
+ - lib/ruby_home/hap/hex_pad.rb
299
+ - lib/ruby_home/hap/hkdf_encryption.rb
300
+ - lib/ruby_home/hap/http_decryption.rb
301
+ - lib/ruby_home/hap/http_encryption.rb
302
+ - lib/ruby_home/hap/service.rb
303
+ - lib/ruby_home/http/application.rb
304
+ - lib/ruby_home/http/cache.rb
305
+ - lib/ruby_home/http/controllers/accessories_controller.rb
306
+ - lib/ruby_home/http/controllers/application_controller.rb
307
+ - lib/ruby_home/http/controllers/characteristics_controller.rb
308
+ - lib/ruby_home/http/controllers/pair_setups_controller.rb
309
+ - lib/ruby_home/http/controllers/pair_verifies_controller.rb
310
+ - lib/ruby_home/http/controllers/pairings_controller.rb
311
+ - lib/ruby_home/http/hap_request.rb
312
+ - lib/ruby_home/http/hap_response.rb
313
+ - lib/ruby_home/http/hap_server.rb
314
+ - lib/ruby_home/http/serializers/accessory_serializer.rb
315
+ - lib/ruby_home/http/serializers/characteristic_serializer.rb
316
+ - lib/ruby_home/http/serializers/characteristic_value_serializer.rb
317
+ - lib/ruby_home/http/serializers/object_serializer.rb
318
+ - lib/ruby_home/http/serializers/service_serializer.rb
319
+ - lib/ruby_home/identifier_cache.rb
320
+ - lib/ruby_home/rack/handler/hap_server.rb
321
+ - lib/ruby_home/tlv.rb
322
+ - lib/ruby_home/tlv/bytes.rb
323
+ - lib/ruby_home/tlv/int.rb
324
+ - lib/ruby_home/tlv/utf8.rb
325
+ - lib/ruby_home/version.rb
326
+ - rubyhome.gemspec
327
+ - sbin/characteristic_generator.rb
328
+ - sbin/service_generator.rb
329
+ homepage: https://github.com/karlentwistle/ruby_home
330
+ licenses: []
331
+ metadata: {}
332
+ post_install_message:
333
+ rdoc_options: []
334
+ require_paths:
335
+ - lib
336
+ required_ruby_version: !ruby/object:Gem::Requirement
337
+ requirements:
338
+ - - ">="
339
+ - !ruby/object:Gem::Version
340
+ version: '0'
341
+ required_rubygems_version: !ruby/object:Gem::Requirement
342
+ requirements:
343
+ - - ">="
344
+ - !ruby/object:Gem::Version
345
+ version: '0'
346
+ requirements: []
347
+ rubyforge_project:
348
+ rubygems_version: 2.7.5
349
+ signing_key:
350
+ specification_version: 4
351
+ summary: Ruby HomeKit support
352
+ test_files: []