ruby_home 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests.yml +4 -4
  3. data/.gitignore +2 -2
  4. data/.rubocop.yml +2 -9
  5. data/.standard.yml +3 -0
  6. data/CHANGELOG.md +6 -1
  7. data/Gemfile +2 -2
  8. data/Rakefile +4 -4
  9. data/examples/air_purifier.rb +7 -8
  10. data/examples/air_quality_sensor.rb +8 -9
  11. data/examples/battery_service.rb +2 -3
  12. data/examples/carbon_dioxide_sensor.rb +2 -3
  13. data/examples/carbon_monoxide_sensor.rb +3 -4
  14. data/examples/contact_sensor.rb +2 -3
  15. data/examples/door.rb +5 -6
  16. data/examples/fan.rb +2 -3
  17. data/examples/fan_v2.rb +2 -3
  18. data/examples/garage_door_opener.rb +9 -10
  19. data/examples/heater_cooler.rb +9 -10
  20. data/examples/humidifier_dehumidifier.rb +9 -10
  21. data/examples/humidity_sensor.rb +2 -3
  22. data/examples/leak_sensor.rb +2 -3
  23. data/examples/light_sensor.rb +2 -3
  24. data/examples/lightbulb.rb +2 -3
  25. data/examples/lock_mechanism.rb +6 -7
  26. data/examples/motion_sensor.rb +2 -3
  27. data/examples/occupancy_sensor.rb +2 -3
  28. data/examples/outlet.rb +2 -3
  29. data/examples/security_system.rb +12 -13
  30. data/examples/smoke_sensor.rb +2 -3
  31. data/examples/switch.rb +2 -3
  32. data/examples/television.rb +8 -13
  33. data/examples/temperature_sensor.rb +2 -3
  34. data/examples/thermostat.rb +10 -11
  35. data/examples/window.rb +5 -6
  36. data/examples/window_covering.rb +5 -6
  37. data/lib/ruby_home.rb +21 -21
  38. data/lib/ruby_home/accessory.rb +1 -1
  39. data/lib/ruby_home/accessory_collection.rb +6 -6
  40. data/lib/ruby_home/accessory_info.rb +18 -18
  41. data/lib/ruby_home/characteristic.rb +8 -8
  42. data/lib/ruby_home/characteristic_collection.rb +13 -13
  43. data/lib/ruby_home/config/characteristics.yml +30 -635
  44. data/lib/ruby_home/config/manual_characteristics.yml +278 -0
  45. data/lib/ruby_home/config/manual_services.yml +45 -0
  46. data/lib/ruby_home/config/services.yml +329 -370
  47. data/lib/ruby_home/configuration.rb +4 -4
  48. data/lib/ruby_home/device_id.rb +3 -3
  49. data/lib/ruby_home/dns/service.rb +4 -6
  50. data/lib/ruby_home/dns/text_record.rb +9 -9
  51. data/lib/ruby_home/errors.rb +1 -0
  52. data/lib/ruby_home/factories/characteristic_factory.rb +37 -37
  53. data/lib/ruby_home/factories/service_factory.rb +72 -72
  54. data/lib/ruby_home/factories/templates/characteristic_template.rb +5 -5
  55. data/lib/ruby_home/factories/templates/service_template.rb +11 -10
  56. data/lib/ruby_home/hap/crypto/chacha20poly1305.rb +2 -2
  57. data/lib/ruby_home/hap/crypto/hkdf.rb +4 -4
  58. data/lib/ruby_home/hap/crypto/session_key.rb +7 -7
  59. data/lib/ruby_home/hap/decrypter.rb +8 -8
  60. data/lib/ruby_home/hap/encrypter.rb +5 -6
  61. data/lib/ruby_home/hap/ev_response.rb +17 -17
  62. data/lib/ruby_home/hap/hap_request.rb +1 -1
  63. data/lib/ruby_home/hap/server.rb +4 -4
  64. data/lib/ruby_home/hap/server_handler.rb +8 -10
  65. data/lib/ruby_home/hap/session.rb +22 -22
  66. data/lib/ruby_home/hap/values/base_value.rb +3 -3
  67. data/lib/ruby_home/hap/values/bool_value.rb +4 -4
  68. data/lib/ruby_home/hap/values/float_value.rb +4 -4
  69. data/lib/ruby_home/hap/values/identify_value.rb +1 -1
  70. data/lib/ruby_home/hap/values/int32_value.rb +4 -4
  71. data/lib/ruby_home/hap/values/null_value.rb +1 -1
  72. data/lib/ruby_home/hap/values/string_value.rb +11 -11
  73. data/lib/ruby_home/hap/values/uint32_value.rb +5 -5
  74. data/lib/ruby_home/hap/values/uint8_value.rb +14 -14
  75. data/lib/ruby_home/hex_helper.rb +3 -3
  76. data/lib/ruby_home/http/application.rb +7 -7
  77. data/lib/ruby_home/http/controllers/accessories_controller.rb +3 -3
  78. data/lib/ruby_home/http/controllers/application_controller.rb +6 -6
  79. data/lib/ruby_home/http/controllers/characteristics_controller.rb +29 -29
  80. data/lib/ruby_home/http/controllers/identify_controller.rb +10 -10
  81. data/lib/ruby_home/http/controllers/pair_setups_controller.rb +18 -18
  82. data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +9 -9
  83. data/lib/ruby_home/http/controllers/pairings_controller.rb +5 -5
  84. data/lib/ruby_home/http/serializers/accessory_serializer.rb +5 -5
  85. data/lib/ruby_home/http/serializers/characteristic_serializer.rb +24 -24
  86. data/lib/ruby_home/http/serializers/characteristic_value_serializer.rb +5 -5
  87. data/lib/ruby_home/http/serializers/object_serializer.rb +1 -1
  88. data/lib/ruby_home/http/serializers/service_serializer.rb +9 -9
  89. data/lib/ruby_home/http/serializers/uuid_helper.rb +2 -2
  90. data/lib/ruby_home/http/services/session_notifier.rb +8 -8
  91. data/lib/ruby_home/http/services/start_srp_service.rb +3 -3
  92. data/lib/ruby_home/http/services/verify_finish_service.rb +22 -22
  93. data/lib/ruby_home/http/services/verify_srp_service.rb +22 -22
  94. data/lib/ruby_home/identifier_cache.rb +4 -5
  95. data/lib/ruby_home/password.rb +14 -14
  96. data/lib/ruby_home/persistable.rb +22 -7
  97. data/lib/ruby_home/service.rb +3 -3
  98. data/lib/ruby_home/service_collection.rb +1 -1
  99. data/lib/ruby_home/version.rb +1 -1
  100. data/rubyhome.gemspec +31 -31
  101. data/sbin/characteristic_generator.rb +22 -24
  102. data/sbin/service_generator.rb +36 -27
  103. metadata +25 -8
@@ -1,5 +1,5 @@
1
- require_relative 'object_serializer'
2
- require_relative 'uuid_helper'
1
+ require_relative "object_serializer"
2
+ require_relative "uuid_helper"
3
3
 
4
4
  module RubyHome
5
5
  module HTTP
@@ -9,11 +9,11 @@ module RubyHome
9
9
 
10
10
  def record_hash(characteristic)
11
11
  {
12
- 'iid' => characteristic.instance_id,
13
- 'type' => uuid_short_form(characteristic.uuid),
14
- 'perms' => perms(characteristic),
15
- 'format' => characteristic.format,
16
- 'description' => characteristic.description,
12
+ "iid" => characteristic.instance_id,
13
+ "type" => uuid_short_form(characteristic.uuid),
14
+ "perms" => perms(characteristic),
15
+ "format" => characteristic.format,
16
+ "description" => characteristic.description
17
17
  }
18
18
  .merge(value_hash(characteristic))
19
19
  .merge(valid_values_hash(characteristic))
@@ -21,27 +21,27 @@ module RubyHome
21
21
 
22
22
  private
23
23
 
24
- def perms(characteristic)
25
- characteristic.properties.map do |property|
26
- RubyHome::Characteristic::PROPERTIES[property]
27
- end.compact
28
- end
24
+ def perms(characteristic)
25
+ characteristic.properties.map do |property|
26
+ RubyHome::Characteristic::PROPERTIES[property]
27
+ end.compact
28
+ end
29
29
 
30
- def value_hash(characteristic)
31
- if characteristic.properties.include?('read')
32
- { 'value' => characteristic.value }
33
- else
34
- {}
35
- end
30
+ def value_hash(characteristic)
31
+ if characteristic.properties.include?("read")
32
+ {"value" => characteristic.value}
33
+ else
34
+ {}
36
35
  end
36
+ end
37
37
 
38
- def valid_values_hash(characteristic)
39
- if characteristic.valid_values.empty?
40
- {}
41
- else
42
- { 'valid-values' => characteristic.valid_values }
43
- end
38
+ def valid_values_hash(characteristic)
39
+ if characteristic.valid_values.empty?
40
+ {}
41
+ else
42
+ {"valid-values" => characteristic.valid_values}
44
43
  end
44
+ end
45
45
  end
46
46
  end
47
47
  end
@@ -1,4 +1,4 @@
1
- require_relative 'object_serializer'
1
+ require_relative "object_serializer"
2
2
 
3
3
  module RubyHome
4
4
  module HTTP
@@ -6,14 +6,14 @@ module RubyHome
6
6
  include ObjectSerializer
7
7
 
8
8
  def root
9
- 'characteristics'
9
+ "characteristics"
10
10
  end
11
11
 
12
12
  def record_hash(characteristic)
13
13
  {
14
- 'aid' => characteristic.accessory_id,
15
- 'iid' => characteristic.instance_id,
16
- 'value' => characteristic.value,
14
+ "aid" => characteristic.accessory_id,
15
+ "iid" => characteristic.instance_id,
16
+ "value" => characteristic.value
17
17
  }
18
18
  end
19
19
  end
@@ -1,4 +1,4 @@
1
- require 'facets/hash/symbolize_keys'
1
+ require "facets/hash/symbolize_keys"
2
2
 
3
3
  module RubyHome
4
4
  module HTTP
@@ -1,6 +1,6 @@
1
- require_relative 'characteristic_serializer'
2
- require_relative 'object_serializer'
3
- require_relative 'uuid_helper'
1
+ require_relative "characteristic_serializer"
2
+ require_relative "object_serializer"
3
+ require_relative "uuid_helper"
4
4
 
5
5
  module RubyHome
6
6
  module HTTP
@@ -10,11 +10,11 @@ module RubyHome
10
10
 
11
11
  def record_hash(service)
12
12
  {
13
- 'iid' => service.instance_id,
14
- 'type' => uuid_short_form(service.uuid),
15
- 'characteristics' => CharacteristicSerializer.new(service.characteristics).serializable_hash,
16
- 'primary' => service.primary,
17
- 'hidden' => service.hidden,
13
+ "iid" => service.instance_id,
14
+ "type" => uuid_short_form(service.uuid),
15
+ "characteristics" => CharacteristicSerializer.new(service.characteristics).serializable_hash,
16
+ "primary" => service.primary,
17
+ "hidden" => service.hidden
18
18
  }.merge(linked_services(service))
19
19
  end
20
20
 
@@ -24,7 +24,7 @@ module RubyHome
24
24
  if service.linked.empty?
25
25
  {}
26
26
  else
27
- { 'linked' => service.linked.map(&:instance_id) }
27
+ {"linked" => service.linked.map(&:instance_id)}
28
28
  end
29
29
  end
30
30
  end
@@ -1,7 +1,7 @@
1
1
  module RubyHome
2
2
  module HTTP
3
3
  module UUIDHelper
4
- APPLE_BASE_UUID = -'0000-1000-8000-0026BB765291'
4
+ APPLE_BASE_UUID = -"0000-1000-8000-0026BB765291"
5
5
 
6
6
  def uuid_short_form(uuid)
7
7
  return uuid unless apple_defined_uuid?(uuid)
@@ -14,7 +14,7 @@ module RubyHome
14
14
  end
15
15
 
16
16
  def trim_leading_zeros(input)
17
- input.gsub(/^0*/, '')
17
+ input.gsub(/^0*/, "")
18
18
  end
19
19
  end
20
20
  end
@@ -16,21 +16,21 @@ module RubyHome
16
16
 
17
17
  def ==(other)
18
18
  self.class == other.class &&
19
- self.session == other.session &&
20
- self.characteristic == other.characteristic
19
+ session == other.session &&
20
+ characteristic == other.characteristic
21
21
  end
22
22
 
23
23
  attr_reader :session, :characteristic
24
24
 
25
25
  private
26
26
 
27
- def send_ev_response
28
- HAP::EVResponse.new(session, serialized_characteristic).send_response
29
- end
27
+ def send_ev_response
28
+ HAP::EVResponse.new(session, serialized_characteristic).send_response
29
+ end
30
30
 
31
- def serialized_characteristic
32
- HTTP::CharacteristicValueSerializer.new([characteristic]).serialized_json
33
- end
31
+ def serialized_characteristic
32
+ HTTP::CharacteristicValueSerializer.new([characteristic]).serialized_json
33
+ end
34
34
  end
35
35
  end
36
36
  end
@@ -1,16 +1,16 @@
1
1
  module RubyHome
2
2
  class StartSRPService
3
- def initialize(username: , password:)
3
+ def initialize(username:, password:)
4
4
  @username = username
5
5
  @password = password
6
6
  end
7
7
 
8
8
  def salt_bytes
9
- [salt].pack('H*')
9
+ [salt].pack("H*")
10
10
  end
11
11
 
12
12
  def public_key_bytes
13
- [public_key].pack('H*')
13
+ [public_key].pack("H*")
14
14
  end
15
15
 
16
16
  def proof
@@ -1,6 +1,6 @@
1
1
  module RubyHome
2
2
  class VerifyFinishService
3
- def initialize(accessory_info: , encrypted_data: , session_key:, shared_secret:)
3
+ def initialize(accessory_info:, encrypted_data:, session_key:, shared_secret:)
4
4
  @accessory_info = accessory_info
5
5
  @encrypted_data = encrypted_data
6
6
  @session_key = session_key
@@ -23,34 +23,34 @@ module RubyHome
23
23
 
24
24
  private
25
25
 
26
- NONCE = -'PV-Msg03'
26
+ NONCE = -"PV-Msg03"
27
27
 
28
- attr_reader :accessory_info, :encrypted_data, :session_key, :shared_secret
28
+ attr_reader :accessory_info, :encrypted_data, :session_key, :shared_secret
29
29
 
30
- def paired_client_exists?
31
- accessory_info.paired_clients.any? do |paired_client|
32
- paired_client[:identifier] == identifier
33
- end
30
+ def paired_client_exists?
31
+ accessory_info.paired_clients.any? do |paired_client|
32
+ paired_client[:identifier] == identifier
34
33
  end
34
+ end
35
35
 
36
- def chacha20poly1305
37
- HAP::Crypto::ChaCha20Poly1305.new(session_key)
38
- end
36
+ def chacha20poly1305
37
+ HAP::Crypto::ChaCha20Poly1305.new(session_key)
38
+ end
39
39
 
40
- def nonce
41
- HexHelper.pad(NONCE)
42
- end
40
+ def nonce
41
+ HexHelper.pad(NONCE)
42
+ end
43
43
 
44
- def decrypted_data
45
- chacha20poly1305.decrypt(nonce, encrypted_data)
46
- end
44
+ def decrypted_data
45
+ chacha20poly1305.decrypt(nonce, encrypted_data)
46
+ end
47
47
 
48
- def unpacked_decrypted_data
49
- TLV.decode(decrypted_data)
50
- end
48
+ def unpacked_decrypted_data
49
+ TLV.decode(decrypted_data)
50
+ end
51
51
 
52
- def identifier
53
- unpacked_decrypted_data[:identifier]
54
- end
52
+ def identifier
53
+ unpacked_decrypted_data[:identifier]
54
+ end
55
55
  end
56
56
  end
@@ -1,8 +1,8 @@
1
1
  module RubyHome
2
2
  class VerifySRPService
3
- def initialize(device_proof: , public_key: , srp_session: )
4
- @device_proof_bytes = device_proof.to_s.unpack1('H*')
5
- @public_key_bytes = public_key.to_s.unpack1('H*')
3
+ def initialize(device_proof:, public_key:, srp_session:)
4
+ @device_proof_bytes = device_proof.to_s.unpack1("H*")
5
+ @public_key_bytes = public_key.to_s.unpack1("H*")
6
6
  @srp_session = srp_session
7
7
  end
8
8
 
@@ -20,29 +20,29 @@ module RubyHome
20
20
 
21
21
  private
22
22
 
23
- def valid_session?
24
- !!verify_session
25
- end
23
+ def valid_session?
24
+ !!verify_session
25
+ end
26
26
 
27
- def session_key
28
- srp_verifier.K
29
- end
27
+ def session_key
28
+ srp_verifier.K
29
+ end
30
30
 
31
- def verify_session_bytes
32
- [verify_session].pack('H*')
33
- end
31
+ def verify_session_bytes
32
+ [verify_session].pack("H*")
33
+ end
34
34
 
35
- def verify_session
36
- srp_verifier.verify_session(
37
- srp_session.merge({A: public_key_bytes}),
38
- device_proof_bytes
39
- )
40
- end
35
+ def verify_session
36
+ srp_verifier.verify_session(
37
+ srp_session.merge({A: public_key_bytes}),
38
+ device_proof_bytes
39
+ )
40
+ end
41
41
 
42
- def srp_verifier
43
- @_verifier ||= RubyHome::SRP::Verifier.new
44
- end
42
+ def srp_verifier
43
+ @_verifier ||= RubyHome::SRP::Verifier.new
44
+ end
45
45
 
46
- attr_reader :public_key_bytes, :device_proof_bytes, :srp_session
46
+ attr_reader :public_key_bytes, :device_proof_bytes, :srp_session
47
47
  end
48
48
  end
@@ -1,10 +1,10 @@
1
- require_relative 'persistable'
1
+ require_relative "persistable"
2
2
 
3
3
  module RubyHome
4
4
  class IdentifierCache
5
5
  include Persistable
6
6
 
7
- self.source = 'identifier_cache.yml'
7
+ self.source = "identifier_cache.yml"
8
8
 
9
9
  def self.all
10
10
  raw_items = read || []
@@ -33,7 +33,7 @@ module RubyHome
33
33
  end
34
34
  end
35
35
 
36
- def initialize(accessory_id:, instance_id:, service_uuid: nil, subtype: , uuid: )
36
+ def initialize(accessory_id:, instance_id:, subtype:, uuid:, service_uuid: nil)
37
37
  @accessory_id = accessory_id
38
38
  @instance_id = instance_id
39
39
  @subtype = subtype
@@ -52,10 +52,9 @@ module RubyHome
52
52
  instance_id: identifier.instance_id,
53
53
  subtype: identifier.subtype,
54
54
  service_uuid: identifier.service_uuid,
55
- uuid: identifier.uuid,
55
+ uuid: identifier.uuid
56
56
  }
57
57
  end
58
58
  end
59
59
  end
60
60
  end
61
-
@@ -1,21 +1,21 @@
1
1
  module RubyHome
2
2
  module Password
3
3
  class << self
4
- DELIMITER = '-'
4
+ DELIMITER = "-"
5
5
  LENGTH = 8
6
6
  INVALIDS = [
7
- '00000000',
8
- '11111111',
9
- '22222222',
10
- '33333333',
11
- '44444444',
12
- '55555555',
13
- '66666666',
14
- '77777777',
15
- '88888888',
16
- '99999999',
17
- '12345678',
18
- '87654321',
7
+ "00000000",
8
+ "11111111",
9
+ "22222222",
10
+ "33333333",
11
+ "44444444",
12
+ "55555555",
13
+ "66666666",
14
+ "77777777",
15
+ "88888888",
16
+ "99999999",
17
+ "12345678",
18
+ "87654321"
19
19
  ]
20
20
 
21
21
  # The Setup Code must conform to the format XXX-XX-XXX where each X is a
@@ -34,7 +34,7 @@ module RubyHome
34
34
  [
35
35
  digits[0...3],
36
36
  digits[3...5],
37
- digits[5...8],
37
+ digits[5...8]
38
38
  ].join(DELIMITER)
39
39
  end
40
40
 
@@ -1,15 +1,16 @@
1
- require 'facets/cattr'
1
+ require "facets/cattr"
2
2
 
3
3
  module RubyHome
4
4
  module Persistable
5
5
  def self.included(base)
6
6
  base.send(:cattr_accessor, :source)
7
+ base.send(:cattr_accessor, :cache)
7
8
  base.extend(ClassMethods)
8
9
  end
9
10
 
10
11
  module ClassMethods
11
12
  def persisted
12
- if yaml = read
13
+ if (yaml = read)
13
14
  new(**yaml)
14
15
  end
15
16
  end
@@ -19,15 +20,29 @@ module RubyHome
19
20
  end
20
21
 
21
22
  def write(collection)
22
- File.open(source, 'w') {|f| f.write(collection.to_yaml) }
23
+ self.cache = collection
24
+ persist
25
+
26
+ true
23
27
  end
24
28
 
25
- def read
26
- return false unless File.exist?(source)
29
+ def persist
30
+ File.write(source, cache.to_yaml)
31
+ end
27
32
 
33
+ def read_persisted
28
34
  YAML.load_file(source)
29
- rescue Errno::EBADF
30
- return false
35
+ rescue Errno::ENOENT
36
+ false
37
+ end
38
+
39
+ def read
40
+ self.cache ||= read_persisted
41
+ end
42
+
43
+ def reset
44
+ self.cache = nil
45
+ persist
31
46
  end
32
47
  end
33
48