Class: RUPNP::CP::RemoteService
- Defined in:
- lib/rupnp/cp/remote_service.rb
Overview
Service class for device’s services.
Actions
This class defines ruby methods from actions defined in service description, as provided by the device.
By example, from this description:
<action>
  <name>actionName</name>
  <argumentList>
  <argument>
    <name>argumentNameIn</name>
    <direction>in</direction>
    <relatedStateVariable>stateVariableName</relatedStateVariable>
  </argument>
  <argument>
    <name>argumentNameOut</name>
    <direction>out</direction>
    <relatedStateVariable>stateVariableName</relatedStateVariable>
  </argument>
</action>
a #action_name method is created. This method requires a hash with an element named argument_name_in. If no in argument is required, an empty hash ({}) must be passed to the method. Hash keys may not be symbols.
A Hash is returned, with a key for each out argument.
Evented variables
Some variables in state (see #state_table, +:@send_events variable attribute) are evented. Events to update these variables are received only after subscription. To subscribe, use #subscribe_to_event.
After subscribing to events, state variables are automagically updated on events. Their value may be accessed through #variables.
A block may be passed to #subscribe_to_event to do a user action on receiving events.
service.subscribe_to_event do |msg|
  puts "receive #{msg}"
end
Constant Summary collapse
- INTEGER_TYPES =
- %w(ui1 ui2 ui4 i1 i2 i4 int).freeze 
- FLOAT_TYPES =
- %w(r4 r8 number float).freeze 
- STRING_TYPES =
- %w(char string uuid).freeze 
- TRUE_TYPES =
- %w(1 true yes).freeze 
- FALSE_TYPES =
- %w(0 false no).freeze 
- @@event_sub_count =
- 0
Constants inherited from Base
Constants included from LogMixin
Instance Attribute Summary collapse
- 
  
    
      #actions  ⇒ Array<Hash> 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Available actions on this service. 
- 
  
    
      #control_url  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    URL for control. 
- 
  
    
      #device  ⇒ Device 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Get device to which this service belongs to. 
- 
  
    
      #event_sub_url  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    URL for eventing. 
- 
  
    
      #id  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Get service id. 
- 
  
    
      #scpd_url  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    URL for service description. 
- 
  
    
      #spec_version  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Define architecture on which the service is implemented. 
- 
  
    
      #state_table  ⇒ Array<Hash> 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    State table for the service. 
- 
  
    
      #type  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Get service type. 
- 
  
    
      #variables  ⇒ Hash 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Variables from state table. 
- 
  
    
      #xmlns  ⇒ String 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    XML namespace for device description. 
Class Method Summary collapse
- 
  
    
      .event_sub_count  ⇒ Integer 
    
    
  
  
  
  
  
  
  
  
  
    Get event subscription count for all services (unique ID for subscription). 
Instance Method Summary collapse
- 
  
    
      #fetch  ⇒ void 
    
    
  
  
  
  
  
  
  
  
  
    Get service from its description. 
- 
  
    
      #initialize(device, url_base, service)  ⇒ RemoteService 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    A new instance of RemoteService. 
- 
  
    
      #subscribe_to_event(options = {}) {|event, msg| ... } ⇒ Integer 
    
    
  
  
  
  
  
  
  
  
  
    Subscribe to event. 
Methods inherited from Base
Methods included from LogMixin
Methods included from Tools
#build_url, #snake_case, #urn_are_equivalent?, #usn2udn
Constructor Details
#initialize(device, url_base, service) ⇒ RemoteService
Returns a new instance of RemoteService.
| 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | # File 'lib/rupnp/cp/remote_service.rb', line 115 def initialize(device, url_base, service) super() @device = device @description = service @type = service[:service_type].to_s @id = service[:service_id].to_s @scpd_url = build_url(url_base, service[:scpdurl].to_s) @control_url = build_url(url_base, service[:control_url].to_s) @event_sub_url = build_url(url_base, service[:event_sub_url].to_s) @actions = [] @variables = {} @update_variables = EM::Channel.new @update_variables.subscribe do |var, value| @variables[var] = value log :debug, "varibale #{var} set to #{value}" end initialize_savon end | 
Instance Attribute Details
#actions ⇒ Array<Hash> (readonly)
Available actions on this service
| 104 105 106 | # File 'lib/rupnp/cp/remote_service.rb', line 104 def actions @actions end | 
#control_url ⇒ String (readonly)
URL for control
| 91 92 93 | # File 'lib/rupnp/cp/remote_service.rb', line 91 def control_url @control_url end | 
#device ⇒ Device (readonly)
Get device to which this service belongs to
| 78 79 80 | # File 'lib/rupnp/cp/remote_service.rb', line 78 def device @device end | 
#event_sub_url ⇒ String (readonly)
URL for eventing
| 94 95 96 | # File 'lib/rupnp/cp/remote_service.rb', line 94 def event_sub_url @event_sub_url end | 
#id ⇒ String (readonly)
Get service id
| 85 86 87 | # File 'lib/rupnp/cp/remote_service.rb', line 85 def id @id end | 
#scpd_url ⇒ String (readonly)
URL for service description
| 88 89 90 | # File 'lib/rupnp/cp/remote_service.rb', line 88 def scpd_url @scpd_url end | 
#spec_version ⇒ String (readonly)
Define architecture on which the service is implemented
| 101 102 103 | # File 'lib/rupnp/cp/remote_service.rb', line 101 def spec_version @spec_version end | 
#state_table ⇒ Array<Hash> (readonly)
State table for the service
| 107 108 109 | # File 'lib/rupnp/cp/remote_service.rb', line 107 def state_table @state_table end | 
#type ⇒ String (readonly)
Get service type
| 82 83 84 | # File 'lib/rupnp/cp/remote_service.rb', line 82 def type @type end | 
#variables ⇒ Hash (readonly)
Variables from state table
| 110 111 112 | # File 'lib/rupnp/cp/remote_service.rb', line 110 def variables @variables end | 
#xmlns ⇒ String (readonly)
XML namespace for device description
| 98 99 100 | # File 'lib/rupnp/cp/remote_service.rb', line 98 def xmlns @xmlns end | 
Class Method Details
.event_sub_count ⇒ Integer
Get event subscription count for all services (unique ID for subscription)
| 60 61 62 | # File 'lib/rupnp/cp/remote_service.rb', line 60 def self.event_sub_count @@event_sub_count += 1 end | 
Instance Method Details
#fetch ⇒ void
This method returns an undefined value.
Get service from its description
| 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | # File 'lib/rupnp/cp/remote_service.rb', line 139 def fetch scpd_getter = EM::DefaultDeferrable.new scpd_getter.errback do fail "cannot get SCPD from #@scpd_url" next end scpd_getter.callback do |scpd| if bad_description?(scpd) fail 'not a UPNP 1.0/1.1 SCPD' next end extract_service_state_table scpd extract_actions scpd succeed self end get_description @scpd_url, scpd_getter end | 
#subscribe_to_event(options = {}) {|event, msg| ... } ⇒ Integer
Subscribe to event
| 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 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 | # File 'lib/rupnp/cp/remote_service.rb', line 169 def subscribe_to_event(={}, &blk) cp = device.control_point cp.start_event_server port = cp.event_port num = self.class.event_sub_count @callback_url = "http://#{HOST_IP}:#{port}/events/#{num}" uri = URI(@event_sub_url) [:timeout] ||= EVENT_SUB_DEFAULT_TIMEOUT log :info, "send SUBSCRIBE request to #{uri}" con = EM::HttpRequest.new(@event_sub_url) http = con.setup_request(:subscribe, :head => { 'HOST' => "#{uri.host}:#{uri.port}", 'USER-AGENT' => RUPNP::USER_AGENT, 'CALLBACK' => @callback_url, 'NT' => 'upnp:event', 'TIMEOUT' => "Second-#{[:timeout]}"}) http.errback do |client| log :warn, "Cannot subscribe to event: #{client.error}" end http.callback do log :debug, 'Close connection to subscribe event URL' con.close if http.response_header.status != 200 log :warn, "Cannot subscribe to event #@event_sub_url:" + " #{http.response_header.http_reason}" else timeout = http.response_header['TIMEOUT'].match(/(\d+)/)[1] || 1800 event = Event.new(@event_sub_url, URI(@callback_url).path, http.response_header['SID'], timeout.to_i) EventServer.add_event event log :info, 'event subscribtion registered' log :debug, "event: #{event.inspect}" event.subscribe do |msg| log :debug, "event #{event} received" if msg.is_a? Hash and msg[:content].is_a? Hash msg[:content].each do |k, v| if @variables.has_key? k log :info, "update evented variable #{k}" type = get_data_type_from_table(k) @update_variables << [k, get_value_from_type(type, v)] end end end log :debug, "call user block" blk.call(msg) if blk end end end end |