A device on a UPnP control point.
A Device holds information about a device and its associated sub-devices and services.
Devices should be created using ::create instead of ::new. This allows a subclass of Device to be automatically instantiated.
When creating a device subclass, it must have a URN_version constant set to the schema URN for that version.
For details on UPnP devices, see www.upnp.org/resources/documents.asp
All embedded devices
Short device description for the end user
Manufacturer’s name
Manufacturer’s web site
Long model description for the end user
Model name
Model number
Web site for model
Unique Device Name (UDN), a universally unique identifier for the device whether root or embedded.
URL for device control via a browser
Serial number
All services provided by this device and its sub-devices.
Devices embedded directly into this device.
Services provided directly by this device.
Type of UPnP device (URN)
Universal Product Code
Base URL for this device
If a concrete class exists for description
it is used to
instantiate the device, otherwise a concrete class is created subclassing
Device and used.
# File lib/UPnP/control/device.rb, line 117 def self.create(device_url) description = Nokogiri::XML open(device_url) url = device_url + '/' type = description.at('root > device > deviceType').text klass_name = type.sub(%r#{UPnP::DEVICE_SCHEMA_PREFIX}:([^:]+):.*/, '\1') begin klass = const_get klass_name rescue NameError klass = const_set klass_name, Class.new(self) klass.const_set :URN_1, "#{UPnP::DEVICE_SCHEMA_PREFIX}:#{klass.name}:1" end klass.new description.at('root > device'), url rescue NameError end
Creates a new Device from device
which can be an Nokogiri::XML::Element describing the device or a URI for
the device’s description. If an XML description is provided, the parent
device’s url
must also be provided.
# File lib/UPnP/control/device.rb, line 159 def initialize(device, url = nil) @devices = [] @sub_devices = [] @services = [] @sub_services = [] case device when URI::Generic then description = Nokogiri::XML open(device) @url = description.at 'root > URLBase' @url = @url ? URI.parse(@url.text.strip) : device + '/' device = parse_device description.at('root > device') when Nokogiri::XML::Element then raise ArgumentError, 'url not provided with Nokogiri::XML::Element' if url.nil? @url = url parse_device device else raise ArgumentError, 'must be a URI or a Nokogiri::XML::Element' end end
Searches for devices using ssdp
and instantiates Device objects for them. By calling this method on
a subclass only devices of that type will be returned.
# File lib/UPnP/control/device.rb, line 140 def self.search(ssdp = UPnP::SSDP.new) responses = if self == UPnP::Control::Service then ssdp.search.select do |response| response.type =~ %r^#{UPnP::DEVICE_SCHEMA_PREFIX}/ end else urns = constants.select { |name| name =~ %r^URN_/ } devices = urns.map { |name| const_get name } ssdp.search(*devices) end responses.map { |response| create response.location } end
Parses the Nokogiri::XML::Element description
and fills in
various attributes, sub-devices and sub-services
# File lib/UPnP/control/device.rb, line 188 def parse_device(description) @friendly_name = description.at('friendlyName').text.strip @manufacturer = description.at('manufacturer').text.strip manufacturer_url = description.at('manufacturerURL') @manufacturer_url = URI.parse manufacturer_url.text.strip if manufacturer_url model_description = description.at 'modelDescription' @model_description = model_description.text.strip if model_description @model_name = description.at('modelName').text.strip model_number = description.at 'modelNumber' @model_number = model_number.text.strip if model_number model_url = description.at 'modelURL' @model_url = URI.parse model_url.text.strip if model_url @name = description.at('UDN').text.strip presentation_url = description.at 'presentationURL' @presentation_url = URI.parse presentation_url.text.strip if presentation_url serial_number = description.at 'serialNumber' @serial_number = serial_number.text.strip if serial_number @type = description.at('deviceType').text.strip upc = description.at 'UPC' @upc = upc.text.strip if upc sub_devices = description.xpath './xmlns:deviceList/xmlns:device' sub_devices.each do |sub_device_description| sub_device = UPnP::Control::Device.new sub_device_description, @url @sub_devices << sub_device end @devices = @sub_devices.map do |device| [device, device.devices] end.flatten sub_services = description.xpath './xmlns:serviceList/xmlns:service' sub_services.each do |service_description| service = UPnP::Control::Service.create service_description, @url @sub_services << service end @services = (@sub_services + @devices.map { |device| device.services }.flatten).uniq end