ruby_home 0.2.5 → 0.2.6

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 (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