Class: UPnP::Control::Device

Inherits:
Object
  • Object
show all
Defined in:
lib/UPnP/control/device.rb

Overview

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(device, url = nil) ⇒ Device

Creates a new Device from device which can be an REXML::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.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/UPnP/control/device.rb', line 157

def initialize(device, url = nil)
  @devices = []
  @sub_devices = []

  @services = []
  @sub_services = []

  case device
  when URI::Generic then
    description = REXML::Document.new open(device)

    @url = description.elements['root/URLBase']
    @url = @url ? URI.parse(@url.text.strip) : device + '/'

    device = parse_device description.elements['root/device']
  when REXML::Element then
    raise ArgumentError, 'url not provided with REXML::Element' if url.nil?
    @url = url
    parse_device device
  else
    raise ArgumentError, 'must be a URI or an REXML::Element'
  end
end

Instance Attribute Details

#devicesObject (readonly)

All embedded devices



28
29
30
# File 'lib/UPnP/control/device.rb', line 28

def devices
  @devices
end

#friendly_nameObject (readonly)

Short device description for the end user



33
34
35
# File 'lib/UPnP/control/device.rb', line 33

def friendly_name
  @friendly_name
end

#manufacturerObject (readonly)

Manufacturer’s name



38
39
40
# File 'lib/UPnP/control/device.rb', line 38

def manufacturer
  @manufacturer
end

#manufacturer_urlObject (readonly)

Manufacturer’s web site



43
44
45
# File 'lib/UPnP/control/device.rb', line 43

def manufacturer_url
  @manufacturer_url
end

#model_descriptionObject (readonly)

Long model description for the end user



48
49
50
# File 'lib/UPnP/control/device.rb', line 48

def model_description
  @model_description
end

#model_nameObject (readonly)

Model name



53
54
55
# File 'lib/UPnP/control/device.rb', line 53

def model_name
  @model_name
end

#model_numberObject (readonly)

Model number



58
59
60
# File 'lib/UPnP/control/device.rb', line 58

def model_number
  @model_number
end

#model_urlObject (readonly)

Web site for model



63
64
65
# File 'lib/UPnP/control/device.rb', line 63

def model_url
  @model_url
end

#nameObject (readonly)

Unique Device Name (UDN), a universally unique identifier for the device whether root or embedded.



69
70
71
# File 'lib/UPnP/control/device.rb', line 69

def name
  @name
end

#presentation_urlObject (readonly)

URL for device control via a browser



74
75
76
# File 'lib/UPnP/control/device.rb', line 74

def presentation_url
  @presentation_url
end

#serial_numberObject (readonly)

Serial number



79
80
81
# File 'lib/UPnP/control/device.rb', line 79

def serial_number
  @serial_number
end

#servicesObject (readonly)

All services provided by this device and its sub-devices.



84
85
86
# File 'lib/UPnP/control/device.rb', line 84

def services
  @services
end

#sub_devicesObject (readonly)

Devices embedded directly into this device.



89
90
91
# File 'lib/UPnP/control/device.rb', line 89

def sub_devices
  @sub_devices
end

#sub_servicesObject (readonly)

Services provided directly by this device.



94
95
96
# File 'lib/UPnP/control/device.rb', line 94

def sub_services
  @sub_services
end

#typeObject (readonly)

Type of UPnP device (URN)



99
100
101
# File 'lib/UPnP/control/device.rb', line 99

def type
  @type
end

#upcObject (readonly)

Universal Product Code



104
105
106
# File 'lib/UPnP/control/device.rb', line 104

def upc
  @upc
end

#urlObject (readonly)

Base URL for this device



109
110
111
# File 'lib/UPnP/control/device.rb', line 109

def url
  @url
end

Class Method Details

.create(device_url) ⇒ Object

If a concrete class exists for description it is used to instantiate the device, otherwise a concrete class is created subclassing Device and used.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/UPnP/control/device.rb', line 116

def self.create(device_url)
  description = REXML::Document.new open(device_url)
  url = device_url + '/'

  type = description.elements['root/device/deviceType'].text.strip
  klass_name = type.sub(/#{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.elements['root/device'], url
end

.search(ssdp = UPnP::SSDP.new) ⇒ Object

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.



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/UPnP/control/device.rb', line 138

def self.search(ssdp = UPnP::SSDP.new)
  responses = if self == UPnP::Control::Service then
                ssdp.search.select do |response|
                  response.type =~ /^#{UPnP::DEVICE_SCHEMA_PREFIX}/
                end
              else
                urns = constants.select { |name| name =~ /^URN_/ }
                devices = urns.map { |name| const_get name }
                ssdp.search(*devices)
              end

  responses.map { |response| create response.location }
end

Instance Method Details

#parse_device(description) ⇒ Object

Parses the REXML::Element description and fills in various attributes, sub-devices and sub-services



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/UPnP/control/device.rb', line 185

def parse_device(description)
  @friendly_name = description.elements['friendlyName'].text.strip

  @manufacturer = description.elements['manufacturer'].text.strip

  manufacturer_url = description.elements['manufacturerURL']
  @manufacturer_url = URI.parse manufacturer_url.text.strip if
    manufacturer_url

  model_description = description.elements['modelDescription']
  @model_description = model_description.text.strip if model_description

  @model_name = description.elements['modelName'].text.strip

  model_number = description.elements['modelNumber']
  @model_number = model_number.text.strip if model_number

  model_url = description.elements['modelURL']
  @model_url = URI.parse model_url.text.strip if model_url

  @name = description.elements['UDN'].text.strip

  presentation_url = description.elements['presentationURL']
  @presentation_url = URI.parse presentation_url.text.strip if
    presentation_url

  serial_number = description.elements['serialNumber']
  @serial_number = serial_number.text.strip if serial_number

  @type = description.elements['deviceType'].text.strip

  upc = description.elements['UPC']
  @upc = upc.text.strip if upc

  description.each_element 'deviceList/device' 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

  description.each_element 'serviceList/service' 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