lib/ruby_home/factories/service_factory.rb
module RubyHome
class ServiceFactory
def self.create(service_name, accessory: Accessory.new, subtype: "default", **options)
new(
service_name: service_name,
accessory: accessory,
subtype: subtype,
**options
).create
end
def create
service = Service.new(
accessory: accessory,
description: template.description,
name: service_name,
uuid: template.uuid
)
if persisted_service
service.instance_id = persisted_service.instance_id
else
service.instance_id = accessory.next_available_instance_id
persist_service(service)
end
accessory.services << service
create_required_characteristics(service)
create_optional_characteristics(service)
unless accessory_information_factory?
create_accessory_information
end
service
end
private
ACCESSORY_INFORMATION_OPTIONS = [
:firmware_revision,
:manufacturer,
:model,
:name,
:serial_number
].freeze
def initialize(service_name:, accessory:, subtype:, **options)
@service_name = service_name.to_sym
@accessory = accessory
@subtype = subtype
@options = options
end
attr_reader :service_name, :accessory, :subtype, :options
def create_required_characteristics(service)
template.required_characteristics.each do |characteristic_template|
characteristic_name = characteristic_template.name
CharacteristicFactory.create(
characteristic_template.name,
service: service,
subtype: subtype,
value: options[characteristic_name]
)
end
end
def create_optional_characteristics(service)
optional_characteristic_templates.each do |characteristic_template|
characteristic_name = characteristic_template.name
CharacteristicFactory.create(
characteristic_name,
service: service,
subtype: subtype,
value: options[characteristic_name]
)
end
end
def optional_characteristic_templates
template.optional_characteristics.select do |characteristic_template|
options.key?(characteristic_template.name)
end
end
def accessory_information_factory?
service_name == :accessory_information
end
def create_accessory_information
return if accessory.has_accessory_information?
ServiceFactory.create(
:accessory_information,
accessory: accessory,
subtype: "accessory_information",
**options.slice(*ACCESSORY_INFORMATION_OPTIONS)
)
end
def template
@template ||= ServiceTemplate.find_by(name: service_name)
end
def persisted_service
IdentifierCache.find_by(
accessory_id: accessory.id,
uuid: template.uuid,
subtype: subtype
)
end
def persist_service(service)
IdentifierCache.create(
accessory_id: accessory.id,
instance_id: service.instance_id,
uuid: template.uuid,
subtype: subtype
)
end
end
end