message_sending.py
Go to the documentation of this file.
1 # -*- Python -*-
2 # -*- coding: utf-8 -*-
3 
4 '''rtsprofile
5 
6 Copyright (C) 2009-2010
7  Geoffrey Biggs
8  RT-Synthesis Research Group
9  Intelligent Systems Research Institute,
10  National Institute of Advanced Industrial Science and Technology (AIST),
11  Japan
12  All rights reserved.
13 Licensed under the Eclipse Public License -v 1.0 (EPL)
14 http://www.opensource.org/licenses/eclipse-1.0.txt
15 
16 File: message_sending.py
17 
18 Objects for the message sending interface.
19 
20 '''
21 
22 __version__ = '$Revision: $'
23 # $Source$
24 
25 
26 from rtsprofile import RTS_NS, RTS_NS_S, RTS_EXT_NS, RTS_EXT_NS_S, \
27  RTS_EXT_NS_YAML
28 from rtsprofile.exceptions import InvalidParticipantNodeError
29 from rtsprofile.targets import TargetExecutionContext
30 from rtsprofile.utils import get_direct_child_elements_xml, \
31  indent_string, validate_attribute
32 
33 
34 ##############################################################################
35 ## MessageSending base object
36 
37 class MessageSending(object):
38  '''Defines the orderings and conditions components in the RT system for
39  various actions.
40 
41  '''
42 
43  def __init__(self, targets=[]):
44  '''@param targets Orderings and conditions.'''
45  validate_attribute(targets, 'message_sending.Targets',
46  expected_type=list, required=False)
47  self._targets = targets
48 
49  def __str__(self):
50  result = self.__class__.__name__ + '\n'
51  if self.targets:
52  result += 'Targets:\n'
53  for t in self.targets:
54  result += '{0}\n'.format(indent_string(str(t)))
55  return result[:-1] # Lop off the last new line
56 
57  @property
58  def targets(self):
59  '''Orderings and conditions.'''
60  return self._targets
61 
62  @targets.setter
63  def targets(self, targets):
64  validate_attribute(targets, 'message_sending.targets',
65  expected_type=list, required=False)
66  self._targets = targets
67 
68  def parse_xml_node(self, node):
69  '''Parse an xml.dom Node object representing a message sending object
70  into this object.
71 
72  '''
73  self._targets = []
74  for c in node.getElementsByTagNameNS(RTS_NS, 'targets'):
75  if c.getElementsByTagNameNS(RTS_NS, 'WaitTime'):
76  new_target = WaitTime()
77  elif c.getElementsByTagNameNS(RTS_NS, 'Preceding'):
78  new_target = Preceding()
79  else:
80  new_target = Condition()
81  new_target.parse_xml_node(c)
82  self._targets.append(new_target)
83  return self
84 
85  def parse_yaml(self, y):
86  '''Parse a YAML speficication of a message sending object into this
87  object.
88 
89  '''
90  self._targets = []
91  if 'targets' in y:
92  for t in y['targets']:
93  if 'waitTime' in t['condition']:
94  new_target = WaitTime()
95  elif 'preceding' in t['condition']:
96  new_target = Preceding()
97  else:
98  new_target = Condition()
99  new_target.parse_yaml(t)
100  self._targets.append(new_target)
101  return self
102 
103  def save_xml(self, doc, element):
104  '''Save this message_sending object into an xml.dom.Element object.'''
105  for cond in self._targets:
106  new_element = doc.createElementNS(RTS_NS, RTS_NS_S + 'targets')
107  cond.save_xml(doc, new_element)
108  element.appendChild(new_element)
109 
110  def to_dict(self):
111  '''Save this message sending object into a dictionary.'''
112  targets = []
113  for cond in self._targets:
114  targets.append(cond.to_dict())
115  if targets:
116  return {'targets': targets}
117  else:
118  return {}
119 
120 
121 ##############################################################################
122 ## StartUp object
123 
125  '''Specifies the start order and conditions of components when the RT
126  system is started.
127 
128  '''
129  pass
130 
131 
132 ##############################################################################
133 ## ShutDown object
134 
135 class ShutDown(MessageSending):
136  '''Specifies the stop order and conditions of components when the RT system
137  is stopped.
138 
139  '''
140  pass
141 
142 
143 ##############################################################################
144 ## Activation object
145 
147  '''Specifies the activation order and conditions of components when the RT
148  system is activated.
149 
150  '''
151  pass
152 
153 
154 ##############################################################################
155 ## Deactivation object
156 
158  '''Specifies the deactivation order and conditions of components when the RT
159  system is deactivated.
160 
161  '''
162  pass
163 
164 
165 ##############################################################################
166 ## Resetting object
167 
169  '''Specifies the reset order and conditions of components when the RT
170  system is reset.
171 
172  '''
173  pass
174 
175 
176 ##############################################################################
177 ## Initialize object
178 
180  '''Specifies the initialisation order and conditions of components when the
181  RT system is initialised.
182 
183  '''
184  pass
185 
186 
187 ##############################################################################
188 ## Finalize object
189 
191  '''Specifies the finalisation order and conditions of components when the
192  RT system is finalised.
193 
194  '''
195  pass
196 
197 
198 ##############################################################################
199 ## Condition base object
200 
201 class Condition(object):
202  '''Specifies execution orderings and conditions for RT components in the RT
203  system.
204 
205  Execution conditions can include the time to wait before executing and
206  order of precedence for components. The involved RT component is specified
207  using @ref TargetExecutionContext.
208 
209  '''
210 
211  def __init__(self, sequence=0, target_component=TargetExecutionContext()):
212  '''Constructor.
213 
214  @param sequence Execution order of the target component.
215  @type sequence int
216  @param target_component The target of the condition.
217  @type target_component TargetComponent
218  '''
219  validate_attribute(sequence, 'conditions.sequence',
220  expected_type=int, required=False)
221  self._sequence = sequence
222  validate_attribute(target_component, 'conditions.TargetComponent',
223  expected_type=TargetExecutionContext,
224  required=True)
225  self._target_component = target_component
226  self._properties = {}
227 
228  def __str__(self):
229  result = 'Sequence: {0}\nTargetEC:\n{1}\n'.format(self.sequence,
230  indent_string(str(self.target_component)))
231  if self.properties:
232  result += 'Properties:\n'
233  for p in self.properties:
234  result += ' {0}: {1}\n'.format(p, self.properties[p])
235  return result[:-1] # Lop off the last new line
236 
237  @property
238  def sequence(self):
239  '''The execution order of the target components for the various
240  actions.
241 
242  '''
243  return self._sequence
244 
245  @sequence.setter
246  def sequence(self, sequence):
247  validate_attribute(sequence, 'conditions.sequence',
248  expected_type=int, required=False)
249  self._sequence = sequence
250 
251  @property
252  def target_component(self):
253  '''Target component of the condition.'''
254  return self._target_component
255 
256  @target_component.setter
257  def target_component(self, target_component):
258  validate_attribute(target_component, 'conditions.TargetComponent',
259  expected_type=TargetExecutionContext,
260  required=True)
261  self._target_component = target_component
262 
263  @property
264  def properties(self):
265  '''Miscellaneous properties.
266 
267  Stores key/value pair properties.
268 
269  Part of the extended profile.
270 
271  '''
272  return self._properties
273 
274  @properties.setter
275  def properties(self, properties):
276  validate_attribute(properties, 'conditions.ext.Properties',
277  expected_type=dict, required=False)
278  self._properties = properties
279 
280  def parse_xml_node(self, node):
281  '''Parse an xml.dom Node object representing a condition into this
282  object.
283 
284  '''
285  self.sequence = int(node.getAttributeNS(RTS_NS, 'sequence'))
286  c = node.getElementsByTagNameNS(RTS_NS, 'TargetComponent')
287  if c.length != 1:
288  raise InvalidParticipantNodeError
290  for c in get_direct_child_elements_xml(node, prefix=RTS_EXT_NS,
291  local_name='Properties'):
292  name, value = parse_properties_xml(c)
293  self._properties[name] = value
294  return self
295 
296  def parse_yaml(self, y):
297  '''Parse a YAML specification of a condition into this object.'''
298  self.sequence = int(y['sequence'])
299  self.target_component = \
300  TargetExecutionContext().parse_yaml(y['targetComponent'])
301  if RTS_EXT_NS_YAML + 'properties' in y:
302  for p in y.get(RTS_EXT_NS_YAML + 'properties'):
303  if 'value' in p:
304  value = p['value']
305  else:
306  value = None
307  self._properties[p['name']] = value
308  return self
309 
310  def save_xml(self, doc, element):
311  '''Save this condition into an xml.dom.Element object.'''
312  element.setAttributeNS(RTS_NS, RTS_NS_S + 'sequence',
313  str(self.sequence))
314  new_element = doc.createElementNS(RTS_NS, RTS_NS_S + 'TargetComponent')
315  self.target_component.save_xml(doc, new_element)
316  element.appendChild(new_element)
317  for p in self.properties:
318  new_prop_element = doc.createElementNS(RTS_EXT_NS,
319  RTS_EXT_NS_S + 'Properties')
320  properties_to_xml(new_prop_element, p, self.properties[p])
321  element.appendChild(new_prop_element)
322 
323  def to_dict(self):
324  '''Save this condition into a dictionary.'''
325  d = {'sequence': self.sequence,
326  'targetComponent': self.target_component.to_dict()}
327  props = []
328  for name in self.properties:
329  p = {'name': name}
330  if self.properties[name]:
331  p['value'] = str(self.properties[name])
332  props.append(p)
333  if props:
334  d[RTS_EXT_NS_YAML + 'properties'] = props
335  return d
336 
337 
338 ##############################################################################
339 ## Preceding object
340 
342  '''Specifies that the target RT component should precede other RT
343  components that are part of the same action (e.g. activation) when that
344  action is executed.
345 
346  '''
347 
348  def __init__(self, sequence=0, target_component=TargetExecutionContext(),
349  timeout=0, sending_timing='', preceding_components=[]):
350  '''Constructor.
351 
352  @param sequence Execution order of the target component.
353  @type sequence int
354  @param target_component The target of the condition.
355  @type target_component TargetComponent
356  @param timeout Status check timeout.
357  @type timeout int
358  @param sending_timing Timing for executing actions.
359  @type sending_timing str
360  @param preceding_components Preceding components of the condition.
361  @type preceding components list(TargetExecutionContext)
362 
363  '''
364  super(Preceding, self).__init__(sequence, target_component)
365  validate_attribute(timeout, 'preceding.timeout',
366  expected_type=int, required=False)
367  self._timeout = timeout
368  validate_attribute(sending_timing, 'preceding.sendingTiming',
369  expected_type=[str, unicode], required=False)
370  self._sending_timing = sending_timing
371  validate_attribute(preceding_components,
372  'preceding.PrecedingComponents',
373  expected_type=list, required=False)
374  self._preceding_components = preceding_components
375 
376  def __str__(self):
377  result = 'Timeout: {0}\nSending timing: {1}\n{2}'.format(self.timeout,
378  self.sending_timing, Condition.__str__(self))
379  if self.preceding_components:
380  for pc in self.preceding_components:
381  result += '\nPreceding component:\n{0}'.format(\
382  indent_string(str(pc)))
383  return result
384 
385  @property
386  def timeout(self):
387  '''Time out for checking if the target component has executed the
388  action successfully.
389 
390  Can be zero. Specified in milliseconds.
391 
392  '''
393  return self._timeout
394 
395  @timeout.setter
396  def timeout(self, timeout):
397  validate_attribute(timeout, 'preceding.timeout',
398  expected_type=int, required=False)
399  self._timeout = timeout
400 
401  @property
402  def sending_timing(self):
403  '''Timing for executing actions.
404 
405  Either wait for the preceding RT component to finish executing the
406  action (specified by "SYNC"), or execute the action without waiting for
407  the preceding RT component to finish (specified by "ASYNC"). When not
408  specified, the first option will be assumed.
409 
410  '''
411  return self._sending_timing
412 
413  @sending_timing.setter
414  def sending_timing(self, sending_timing):
415  validate_attribute(sending_timing, 'preceding.sendingTiming',
416  expected_type=[str, unicode], required=False)
417  self._sending_timing = sending_timing
418 
419  @property
421  '''Preceding components of this condition.'''
422  return self._preceding_components
423 
424  @preceding_components.setter
425  def preceding_components(self, preceding_components):
426  validate_attribute(sending_timing, 'preceding.PrecedingComponents',
427  expected_type=list, required=False)
428  self._preceding_components = preceding_components
429 
430  def parse_xml_node(self, node):
431  '''Parse an xml.dom Node object representing a preceding condition into
432  this object.
433 
434  '''
435  super(Preceding, self).parse_xml_node(node)
436  p_nodes = node.getElementsByTagNameNS(RTS_NS, 'Preceding')
437  if p_nodes.length != 1:
438  raise InvalidParticipantNodeError
439  p_node = p_nodes[0]
440  if p_node.hasAttributeNS(RTS_NS, 'timeout'):
441  self.timeout = int(p_node.getAttributeNS(RTS_NS, 'timeout'))
442  else:
443  self.timeout = 0
444  if p_node.hasAttributeNS(RTS_NS, 'sendingTiming'):
445  self.sending_timing = p_node.getAttributeNS(RTS_NS, 'sendingTiming')
446  else:
447  self.sending_timing = 'ASYNC'
448  self._preceding_components = []
449  for c in p_node.getElementsByTagNameNS(RTS_NS, 'PrecedingComponents'):
450  self._preceding_components.append(TargetExecutionContext().parse_xml_node(c))
451  return self
452 
453  def parse_yaml(self, y):
454  '''Parse a YAML specification of a preceding condition into this
455  object.
456 
457  '''
458  super(Preceding, self).parse_yaml(y)
459  c = y['condition']['preceding']
460  if 'timeout' in c:
461  self.timeout = int(c['timeout'])
462  else:
463  self.timeout = 0
464  if 'sendingTiming' in c:
465  self.sending_timing = c['sendingTiming']
466  else:
467  self.sending_timing = 'ASYNC'
468  self._preceding_components = []
469  if 'precedingComponents' in c:
470  for p in c.get('precedingComponents'):
471  self._preceding_components.append(TargetExecutionContext().parse_yaml(p))
472  return self
473 
474  def save_xml(self, doc, element):
475  '''Save this preceding condition into an xml.dom.Element object.'''
476  super(Preceding, self).save_xml(doc, element)
477  pre_element = doc.createElementNS(RTS_NS, RTS_NS_S + 'Preceding')
478  if self.timeout:
479  pre_element.setAttributeNS(RTS_NS, RTS_NS_S + 'timeout',
480  str(self.timeout))
481  if self.sending_timing:
482  pre_element.setAttributeNS(RTS_NS, RTS_NS_S + 'sendingTiming',
483  self.sending_timing)
484  for pc in self._preceding_components:
485  new_element = doc.createElementNS(RTS_NS,
486  RTS_NS_S + 'PrecedingComponents')
487  pc.save_xml(doc, new_element)
488  pre_element.appendChild(new_element)
489  element.appendChild(pre_element)
490 
491  def to_dict(self):
492  '''Save this preceding condition into a dictionary.'''
493  d = super(Preceding, self).to_dict()
494  e = {}
495  if self.timeout != 0:
496  e['timeout'] = self.timeout
497  if self.sending_timing:
498  e['sendingTiming'] = self.sending_timing
499  pcs = []
500  for pc in self._preceding_components:
501  pcs.append(pc.to_dict())
502  if pcs:
503  e['precedingComponents'] = pcs
504  d['condition'] = {'preceding': e}
505  return d
506 
507 
508 ##############################################################################
509 ## WaitTime object
510 
512  '''Specifies the time to wait before executing the specified action on the
513  target RT component. After the action command is received by the RT
514  component, it will wait the specified length of time before executing it.
515 
516  '''
517 
518  def __init__(self, wait_time=0, sequence=0,
519  target_component=TargetExecutionContext()):
520  '''Constructor.
521 
522  @param sequence Execution order of the target component.
523  @type sequence int
524  @param target_component The target of the condition.
525  @type target_component TargetComponent
526  @param wait_time The length of time to wait, in milliseconds.
527  @type wait_time int
528 
529  '''
530  super(WaitTime, self).__init__(sequence, target_component)
531  validate_attribute(wait_time, 'wait_time.waitTime',
532  expected_type=int, required=False)
533  self._wait_time = wait_time
534 
535  def __str__(self):
536  return 'Wait time: {0}\n{1}'.format(self.wait_time,
537  Condition.__str__(self))
538 
539  @property
540  def wait_time(self):
541  '''The length of time to wait before executing the specified action.
542 
543  In milliseconds.
544 
545  '''
546  return self._wait_time
547 
548  @wait_time.setter
549  def wait_time(self, wait_time):
550  validate_attribute(wait_time, 'wait_time.waitTime',
551  expected_type=int, required=False)
552  self._wait_time = wait_time
553 
554  def parse_xml_node(self, node):
555  '''Parse an xml.dom Node object representing a wait_time condition into
556  this object.
557 
558  '''
559  super(WaitTime, self).parse_xml_node(node)
560  wait_time_nodes = node.getElementsByTagNameNS(RTS_NS, 'WaitTime')
561  if wait_time_nodes.length != 1:
562  raise InvalidParticipantNodeError
563  self.wait_time = int(wait_time_nodes[0].getAttributeNS(RTS_NS,
564  'waitTime'))
565  return self
566 
567  def parse_yaml(self, y):
568  '''Parse a YAML specification of a wait_time condition into this
569  object.
570 
571  '''
572  super(WaitTime, self).parse_yaml(y)
573  self.wait_time = int(y['condition']['waitTime']['waitTime'])
574  return self
575 
576  def save_xml(self, doc, element):
577  '''Save this wait_time condition into an xml.dom.Element object.'''
578  super(WaitTime, self).save_xml(doc, element)
579  new_element = doc.createElementNS(RTS_NS, RTS_NS_S + 'WaitTime')
580  new_element.setAttributeNS(RTS_NS, RTS_NS_S + 'waitTime',
581  str(self.wait_time))
582  element.appendChild(new_element)
583 
584  def to_dict(self):
585  '''Save this wait_time condition into a dictionary.'''
586  d = super(WaitTime, self).to_dict()
587  d['condition'] = {'waitTime': {'waitTime': self.wait_time}}
588  return d
589 
590 
591 # vim: tw=79
592 
def properties_to_xml(element, name, value=None)
Definition: utils.py:86
def parse_properties_xml(node)
Definition: utils.py:77
def __init__(self, wait_time=0, sequence=0, target_component=TargetExecutionContext())
def validate_attribute(attr, name, expected_type=None, required=False)
Definition: utils.py:92
def get_direct_child_elements_xml(node, prefix=None, local_name=None)
Definition: utils.py:50
def __init__(self, sequence=0, target_component=TargetExecutionContext(), timeout=0, sending_timing='', preceding_components=[])
def save_xml(self, doc, element)
TargetExecutionContext object.
Definition: targets.py:241
def indent_string(string, num_spaces=2)
Definition: utils.py:65
def __init__(self, sequence=0, target_component=TargetExecutionContext())


rtsprofile
Author(s): Geoffrey Biggs
autogenerated on Fri Jun 7 2019 21:52:35