793 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			793 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
|     SleekXMPP: The Sleek XMPP Library
 | |
|     Implementation of xeps for Internet of Things
 | |
|     http://wiki.xmpp.org/web/Tech_pages/IoT_systems
 | |
|     Copyright (C) 2013 Sustainable Innovation, Joachim.lindborg@sust.se, bjorn.westrom@consoden.se
 | |
|     This file is part of SleekXMPP.
 | |
| 
 | |
|     See the file LICENSE for copying permission.
 | |
| """
 | |
| 
 | |
| from sleekxmpp import Iq, Message
 | |
| from sleekxmpp.xmlstream import register_stanza_plugin, ElementBase, ET, JID
 | |
| from re import match
 | |
| 
 | |
| class Sensordata(ElementBase):
 | |
|     """ Placeholder for the namespace, not used as a stanza """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'sensordata'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(tuple())
 | |
| 
 | |
| class FieldTypes():
 | |
|     """ 
 | |
|     All field types are optional booleans that default to False
 | |
|     """
 | |
|     field_types = set([ 'momentary','peak','status','computed','identity','historicalSecond','historicalMinute','historicalHour', \
 | |
|                         'historicalDay','historicalWeek','historicalMonth','historicalQuarter','historicalYear','historicalOther'])
 | |
| 
 | |
| class FieldStatus():
 | |
|     """ 
 | |
|     All field statuses are optional booleans that default to False
 | |
|     """
 | |
|     field_status = set([ 'missing','automaticEstimate','manualEstimate','manualReadout','automaticReadout','timeOffset','warning','error', \
 | |
|                          'signed','invoiced','endOfSeries','powerFailure','invoiceConfirmed'])
 | |
| 
 | |
| class Request(ElementBase):
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'req'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr','nodes','fields','serviceToken','deviceToken','userToken','from','to','when','historical','all'])
 | |
|     interfaces.update(FieldTypes.field_types);
 | |
|     _flags = set(['serviceToken','deviceToken','userToken','from','to','when','historical','all']);
 | |
|     _flags.update(FieldTypes.field_types);
 | |
|     
 | |
|     def __init__(self, xml=None, parent=None):
 | |
|         ElementBase.__init__(self, xml, parent);
 | |
|         self._nodes = set()
 | |
|         self._fields = set()
 | |
| 
 | |
|     def setup(self, xml=None):
 | |
|         """
 | |
|         Populate the stanza object using an optional XML object.
 | |
| 
 | |
|         Overrides ElementBase.setup
 | |
| 
 | |
|         Caches item information.
 | |
| 
 | |
|         Arguments:
 | |
|             xml -- Use an existing XML object for the stanza's values.
 | |
|         """
 | |
|         ElementBase.setup(self, xml)
 | |
|         self._nodes = set([node['nodeId'] for node in self['nodes']])
 | |
|         self._fields = set([field['name'] for field in self['fields']])
 | |
| 
 | |
|     def _get_flags(self):
 | |
|         """
 | |
|         Helper function for getting of flags. Returns all flags in 
 | |
|         dictionary format: { "flag name": "flag value" ... } 
 | |
|         """
 | |
|         flags = {};
 | |
|         for f in self._flags:
 | |
|             if not self[f] == "":
 | |
|                 flags[f] = self[f];
 | |
|         return flags;
 | |
| 
 | |
|     def _set_flags(self, flags):
 | |
|         """
 | |
|         Helper function for setting of flags. 
 | |
| 
 | |
|         Arguments:
 | |
|             flags -- Flags in dictionary format: { "flag name": "flag value" ... } 
 | |
|         """
 | |
|         for f in self._flags:
 | |
|             if flags is not None and f in flags:
 | |
|                 self[f] = flags[f];
 | |
|             else:
 | |
|                 self[f] = None;
 | |
| 
 | |
|     def add_node(self, nodeId, sourceId=None, cacheType=None):
 | |
|         """
 | |
|         Add a new node element. Each item is required to have a
 | |
|         nodeId, but may also specify a sourceId value and cacheType.
 | |
| 
 | |
|         Arguments:
 | |
|             nodeId    -- The ID for the node.
 | |
|             sourceId  -- [optional] identifying the data source controlling the device
 | |
|             cacheType -- [optional] narrowing down the search to a specific kind of node        
 | |
|         """
 | |
|         if nodeId not in self._nodes:
 | |
|             self._nodes.add((nodeId))
 | |
|             node = RequestNode(parent=self)
 | |
|             node['nodeId'] = nodeId
 | |
|             node['sourceId'] = sourceId
 | |
|             node['cacheType'] = cacheType
 | |
|             self.iterables.append(node)
 | |
|             return node
 | |
|         return None
 | |
| 
 | |
|     def del_node(self, nodeId):
 | |
|         """
 | |
|         Remove a single node.
 | |
| 
 | |
|         Arguments:
 | |
|             nodeId  -- Node ID of the item to remove.
 | |
|         """
 | |
|         if nodeId in self._nodes:
 | |
|             nodes = [i for i in self.iterables if isinstance(i, RequestNode)]
 | |
|             for node in nodes:
 | |
|                 if node['nodeId'] == nodeId:
 | |
|                     self.xml.remove(node.xml)
 | |
|                     self.iterables.remove(node)
 | |
|                     return True
 | |
|         return False
 | |
| 
 | |
|     def get_nodes(self):
 | |
|         """Return all nodes."""
 | |
|         nodes = []
 | |
|         for node in self['substanzas']:
 | |
|             if isinstance(node, RequestNode):
 | |
|                 nodes.append(node)
 | |
|         return nodes
 | |
| 
 | |
|     def set_nodes(self, nodes):
 | |
|         """
 | |
|         Set or replace all nodes. The given nodes must be in a
 | |
|         list or set where each item is a tuple of the form:
 | |
|             (nodeId, sourceId, cacheType)
 | |
| 
 | |
|         Arguments:
 | |
|             nodes -- A series of nodes in tuple format.
 | |
|         """
 | |
|         self.del_nodes()
 | |
|         for node in nodes:
 | |
|             if isinstance(node, RequestNode):
 | |
|                 self.add_node(node['nodeId'], node['sourceId'], node['cacheType'])
 | |
|             else:
 | |
|                 nodeId, sourceId, cacheType = node
 | |
|                 self.add_node(nodeId, sourceId, cacheType)
 | |
| 
 | |
|     def del_nodes(self):
 | |
|         """Remove all nodes."""
 | |
|         self._nodes = set()
 | |
|         nodes = [i for i in self.iterables if isinstance(i, RequestNode)]
 | |
|         for node in nodes:
 | |
|             self.xml.remove(node.xml)
 | |
|             self.iterables.remove(node)
 | |
| 
 | |
| 
 | |
|     def add_field(self, name):
 | |
|         """
 | |
|         Add a new field element. Each item is required to have a
 | |
|         name.
 | |
| 
 | |
|         Arguments:
 | |
|             name  -- The name of the field.
 | |
|         """
 | |
|         if name not in self._fields:
 | |
|             self._fields.add((name))
 | |
|             field = RequestField(parent=self)
 | |
|             field['name'] = name
 | |
|             self.iterables.append(field)
 | |
|             return field
 | |
|         return None
 | |
| 
 | |
|     def del_field(self, name):
 | |
|         """
 | |
|         Remove a single field.
 | |
| 
 | |
|         Arguments:
 | |
|             name  -- name of field to remove.
 | |
|         """
 | |
|         if name in self._fields:
 | |
|             fields = [i for i in self.iterables if isinstance(i, RequestField)]
 | |
|             for field in fields:
 | |
|                 if field['name'] == name:
 | |
|                     self.xml.remove(field.xml)
 | |
|                     self.iterables.remove(field)
 | |
|                     return True
 | |
|         return False
 | |
| 
 | |
|     def get_fields(self):
 | |
|         """Return all fields."""
 | |
|         fields = []
 | |
|         for field in self['substanzas']:
 | |
|             if isinstance(field, RequestField):
 | |
|                 fields.append(field)
 | |
|         return fields
 | |
| 
 | |
|     def set_fields(self, fields):
 | |
|         """
 | |
|         Set or replace all fields. The given fields must be in a
 | |
|         list or set where each item is RequestField or string
 | |
| 
 | |
|         Arguments:
 | |
|             fields -- A series of fields in RequestField or string format.
 | |
|         """
 | |
|         self.del_fields()
 | |
|         for field in fields:
 | |
|             if isinstance(field, RequestField):
 | |
|                 self.add_field(field['name'])
 | |
|             else:
 | |
|                 self.add_field(field)
 | |
| 
 | |
|     def del_fields(self):
 | |
|         """Remove all fields."""
 | |
|         self._fields = set()
 | |
|         fields = [i for i in self.iterables if isinstance(i, RequestField)]
 | |
|         for field in fields:
 | |
|             self.xml.remove(field.xml)
 | |
|             self.iterables.remove(field)
 | |
| 
 | |
| 
 | |
| class RequestNode(ElementBase):
 | |
|     """ Node element in a request """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'node'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['nodeId','sourceId','cacheType'])
 | |
| 
 | |
| class RequestField(ElementBase):
 | |
|     """ Field element in a request """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'field'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['name'])
 | |
| 
 | |
| class Accepted(ElementBase):
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'accepted'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr','queued'])
 | |
| 
 | |
| class Started(ElementBase):
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'started'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr'])
 | |
| 
 | |
| class Failure(ElementBase):
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'failure'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr','done'])
 | |
| 
 | |
| class Error(ElementBase):
 | |
|     """ Error element in a request failure """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'error'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['nodeId','timestamp','sourceId','cacheType','text'])
 | |
| 
 | |
|     def get_text(self):
 | |
|         """Return then contents inside the XML tag."""
 | |
|         return self.xml.text
 | |
| 
 | |
|     def set_text(self, value):
 | |
|         """Set then contents inside the XML tag.
 | |
| 
 | |
|         :param value: string
 | |
|         """
 | |
| 
 | |
|         self.xml.text = value;
 | |
|         return self
 | |
| 
 | |
|     def del_text(self):
 | |
|         """Remove the contents inside the XML tag."""
 | |
|         self.xml.text = ""
 | |
|         return self
 | |
| 
 | |
| class Rejected(ElementBase):
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'rejected'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr','error'])
 | |
|     sub_interfaces = set(['error'])
 | |
| 
 | |
| class Fields(ElementBase):
 | |
|     """ Fields element, top level in a response message with data """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'fields'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr','done','nodes'])
 | |
| 
 | |
|     def __init__(self, xml=None, parent=None):
 | |
|         ElementBase.__init__(self, xml, parent);
 | |
|         self._nodes = set()
 | |
| 
 | |
|     def setup(self, xml=None):
 | |
|         """
 | |
|         Populate the stanza object using an optional XML object.
 | |
| 
 | |
|         Overrides ElementBase.setup
 | |
| 
 | |
|         Caches item information.
 | |
| 
 | |
|         Arguments:
 | |
|             xml -- Use an existing XML object for the stanza's values.
 | |
|         """
 | |
|         ElementBase.setup(self, xml)
 | |
|         self._nodes = set([node['nodeId'] for node in self['nodes']])
 | |
| 
 | |
| 
 | |
|     def add_node(self, nodeId, sourceId=None, cacheType=None, substanzas=None):
 | |
|         """
 | |
|         Add a new node element. Each item is required to have a
 | |
|         nodeId, but may also specify a sourceId value and cacheType.
 | |
| 
 | |
|         Arguments:
 | |
|             nodeId  -- The ID for the node.
 | |
|             sourceId  -- [optional] identifying the data source controlling the device
 | |
|             cacheType -- [optional] narrowing down the search to a specific kind of node        
 | |
|         """
 | |
|         if nodeId not in self._nodes:
 | |
|             self._nodes.add((nodeId))
 | |
|             node = FieldsNode(parent=self)
 | |
|             node['nodeId'] = nodeId
 | |
|             node['sourceId'] = sourceId
 | |
|             node['cacheType'] = cacheType
 | |
|             if substanzas is not None:
 | |
|                 node.set_timestamps(substanzas)
 | |
| 
 | |
|             self.iterables.append(node)
 | |
|             return node
 | |
|         return None
 | |
| 
 | |
|     def del_node(self, nodeId):
 | |
|         """
 | |
|         Remove a single node.
 | |
| 
 | |
|         Arguments:
 | |
|             nodeId  -- Node ID of the item to remove.
 | |
|         """
 | |
|         if nodeId in self._nodes:
 | |
|             nodes = [i for i in self.iterables if isinstance(i, FieldsNode)]
 | |
|             for node in nodes:
 | |
|                 if node['nodeId'] == nodeId:
 | |
|                     self.xml.remove(node.xml)
 | |
|                     self.iterables.remove(node)
 | |
|                     return True
 | |
|         return False
 | |
| 
 | |
|     def get_nodes(self):
 | |
|         """Return all nodes."""
 | |
|         nodes = []
 | |
|         for node in self['substanzas']:
 | |
|             if isinstance(node, FieldsNode):
 | |
|                 nodes.append(node)
 | |
|         return nodes
 | |
| 
 | |
|     def set_nodes(self, nodes):
 | |
|         """
 | |
|         Set or replace all nodes. The given nodes must be in a
 | |
|         list or set where each item is a tuple of the form:
 | |
|             (nodeId, sourceId, cacheType)
 | |
| 
 | |
|         Arguments:
 | |
|             nodes -- A series of nodes in tuple format.
 | |
|         """
 | |
|         #print(str(id(self)) + " set_nodes: got " + str(nodes))
 | |
|         self.del_nodes()
 | |
|         for node in nodes:
 | |
|             if isinstance(node, FieldsNode):
 | |
|                 self.add_node(node['nodeId'], node['sourceId'], node['cacheType'], substanzas=node['substanzas'])
 | |
|             else:
 | |
|                 nodeId, sourceId, cacheType = node
 | |
|                 self.add_node(nodeId, sourceId, cacheType)
 | |
| 
 | |
|     def del_nodes(self):
 | |
|         """Remove all nodes."""
 | |
|         self._nodes = set()
 | |
|         nodes = [i for i in self.iterables if isinstance(i, FieldsNode)]
 | |
|         for node in nodes:
 | |
|             self.xml.remove(node.xml)
 | |
|             self.iterables.remove(node)
 | |
| 
 | |
| 
 | |
| class FieldsNode(ElementBase):
 | |
|     """ Node element in response fields """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'node'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['nodeId','sourceId','cacheType','timestamps'])
 | |
| 
 | |
|     def __init__(self, xml=None, parent=None):
 | |
|         ElementBase.__init__(self, xml, parent);
 | |
|         self._timestamps = set()
 | |
| 
 | |
|     def setup(self, xml=None):
 | |
|         """
 | |
|         Populate the stanza object using an optional XML object.
 | |
| 
 | |
|         Overrides ElementBase.setup
 | |
| 
 | |
|         Caches item information.
 | |
| 
 | |
|         Arguments:
 | |
|             xml -- Use an existing XML object for the stanza's values.
 | |
|         """
 | |
|         ElementBase.setup(self, xml)
 | |
|         self._timestamps = set([ts['value'] for ts in self['timestamps']])
 | |
| 
 | |
|     def add_timestamp(self, timestamp, substanzas=None):
 | |
|         """
 | |
|         Add a new timestamp element. 
 | |
| 
 | |
|         Arguments:
 | |
|             timestamp  -- The timestamp in ISO format.
 | |
|         """
 | |
|         #print(str(id(self)) + " add_timestamp: " + str(timestamp))
 | |
| 
 | |
|         if timestamp not in self._timestamps:
 | |
|             self._timestamps.add((timestamp))
 | |
|             ts = Timestamp(parent=self)
 | |
|             ts['value'] = timestamp
 | |
|             if not substanzas is None:
 | |
|                 ts.set_datas(substanzas);
 | |
|                 #print("add_timestamp with substanzas: " + str(substanzas))
 | |
|             self.iterables.append(ts)
 | |
|             #print(str(id(self)) + " added_timestamp: " + str(id(ts)))
 | |
|             return ts
 | |
|         return None
 | |
| 
 | |
|     def del_timestamp(self, timestamp):
 | |
|         """
 | |
|         Remove a single timestamp.
 | |
| 
 | |
|         Arguments:
 | |
|             timestamp  -- timestamp (in ISO format) of the item to remove.
 | |
|         """
 | |
|         #print("del_timestamp: ")
 | |
|         if timestamp in self._timestamps:
 | |
|             timestamps = [i for i in self.iterables if isinstance(i, Timestamp)]
 | |
|             for ts in timestamps:
 | |
|                 if ts['value'] == timestamp:
 | |
|                     self.xml.remove(ts.xml)
 | |
|                     self.iterables.remove(ts)
 | |
|                     return True
 | |
|         return False
 | |
| 
 | |
|     def get_timestamps(self):
 | |
|         """Return all timestamps."""
 | |
|         #print(str(id(self)) + " get_timestamps: ")
 | |
|         timestamps = []
 | |
|         for timestamp in self['substanzas']:
 | |
|             if isinstance(timestamp, Timestamp):
 | |
|                 timestamps.append(timestamp)
 | |
|         return timestamps
 | |
| 
 | |
|     def set_timestamps(self, timestamps):
 | |
|         """
 | |
|         Set or replace all timestamps. The given timestamps must be in a
 | |
|         list or set where each item is a timestamp
 | |
| 
 | |
|         Arguments:
 | |
|             timestamps -- A series of timestamps.
 | |
|         """
 | |
|         #print(str(id(self)) + " set_timestamps: got " + str(timestamps))
 | |
|         self.del_timestamps()
 | |
|         for timestamp in timestamps:
 | |
|             #print("set_timestamps: subset " + str(timestamp))
 | |
|             #print("set_timestamps: subset.substanzas " + str(timestamp['substanzas']))
 | |
|             if isinstance(timestamp, Timestamp):
 | |
|                 self.add_timestamp(timestamp['value'], substanzas=timestamp['substanzas'])
 | |
|             else:
 | |
|                 #print("set_timestamps: got " + str(timestamp))
 | |
|                 self.add_timestamp(timestamp)
 | |
| 
 | |
|     def del_timestamps(self):
 | |
|         """Remove all timestamps."""
 | |
|         #print(str(id(self)) + " del_timestamps: ")
 | |
|         self._timestamps = set()
 | |
|         timestamps = [i for i in self.iterables if isinstance(i, Timestamp)]
 | |
|         for timestamp in timestamps:
 | |
|             self.xml.remove(timestamp.xml)
 | |
|             self.iterables.remove(timestamp)
 | |
| 
 | |
| class Field(ElementBase):
 | |
|     """ 
 | |
|     Field element in response Timestamp. This is a base class,
 | |
|     all instances of fields added to Timestamp must be of types:
 | |
|         DataNumeric
 | |
|         DataString
 | |
|         DataBoolean
 | |
|         DataDateTime
 | |
|         DataTimeSpan
 | |
|         DataEnum
 | |
|     """    
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'field'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['name','module','stringIds']);
 | |
|     interfaces.update(FieldTypes.field_types);
 | |
|     interfaces.update(FieldStatus.field_status);
 | |
| 
 | |
|     _flags = set();
 | |
|     _flags.update(FieldTypes.field_types);
 | |
|     _flags.update(FieldStatus.field_status);
 | |
| 
 | |
|     def set_stringIds(self, value):
 | |
|         """Verifies stringIds according to regexp from specification XMPP-0323.
 | |
| 
 | |
|         :param value: string
 | |
|         """
 | |
| 
 | |
|         pattern = re.compile("^\d+([|]\w+([.]\w+)*([|][^,]*)?)?(,\d+([|]\w+([.]\w+)*([|][^,]*)?)?)*$")
 | |
|         if pattern.match(value) is not None:
 | |
|             self.xml.stringIds = value;
 | |
|         else:
 | |
|             # Bad content, add nothing
 | |
|             pass
 | |
| 
 | |
|         return self
 | |
| 
 | |
|     def _get_flags(self):
 | |
|         """
 | |
|         Helper function for getting of flags. Returns all flags in 
 | |
|         dictionary format: { "flag name": "flag value" ... } 
 | |
|         """
 | |
|         flags = {};
 | |
|         for f in self._flags:
 | |
|             if not self[f] == "":
 | |
|                 flags[f] = self[f];
 | |
|         return flags;
 | |
| 
 | |
|     def _set_flags(self, flags):
 | |
|         """
 | |
|         Helper function for setting of flags. 
 | |
| 
 | |
|         Arguments:
 | |
|             flags -- Flags in dictionary format: { "flag name": "flag value" ... } 
 | |
|         """
 | |
|         for f in self._flags:
 | |
|             if flags is not None and f in flags:
 | |
|                 self[f] = flags[f];
 | |
|             else:
 | |
|                 self[f] = None;
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "invalid type, use subclasses!";
 | |
| 
 | |
| 
 | |
| class Timestamp(ElementBase):
 | |
|     """ Timestamp element in response Node """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'timestamp'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value','datas'])
 | |
| 
 | |
|     def __init__(self, xml=None, parent=None):
 | |
|         ElementBase.__init__(self, xml, parent);
 | |
|         self._datas = set()
 | |
| 
 | |
|     def setup(self, xml=None):
 | |
|         """
 | |
|         Populate the stanza object using an optional XML object.
 | |
| 
 | |
|         Overrides ElementBase.setup
 | |
| 
 | |
|         Caches item information.
 | |
| 
 | |
|         Arguments:
 | |
|             xml -- Use an existing XML object for the stanza's values.
 | |
|         """
 | |
|         ElementBase.setup(self, xml)
 | |
|         self._datas = set([data['name'] for data in self['datas']])
 | |
| 
 | |
|     def add_data(self, typename, name, value, module=None, stringIds=None, unit=None, dataType=None, flags=None):
 | |
|         """
 | |
|         Add a new data element. 
 | |
| 
 | |
|         Arguments:
 | |
|             typename   -- The type of data element (numeric, string, boolean, dateTime, timeSpan or enum)
 | |
|             value      -- The value of the data element
 | |
|             module     -- [optional] language module to use for the data element
 | |
|             stringIds  -- [optional] The stringIds used to find associated text in the language module
 | |
|             unit       -- [optional] The unit. Only applicable for type numeric
 | |
|             dataType   -- [optional] The dataType. Only applicable for type enum
 | |
|         """
 | |
|         if name not in self._datas:
 | |
|             dataObj = None;
 | |
|             if typename == "numeric":
 | |
|                 dataObj = DataNumeric(parent=self);
 | |
|                 dataObj['unit'] = unit;
 | |
|             elif typename == "string":
 | |
|                 dataObj = DataString(parent=self);
 | |
|             elif typename == "boolean":
 | |
|                 dataObj = DataBoolean(parent=self);
 | |
|             elif typename == "dateTime":
 | |
|                 dataObj = DataDateTime(parent=self);
 | |
|             elif typename == "timeSpan":
 | |
|                 dataObj = DataTimeSpan(parent=self);
 | |
|             elif typename == "enum":
 | |
|                 dataObj = DataEnum(parent=self);
 | |
|                 dataObj['dataType'] = dataType;
 | |
| 
 | |
|             dataObj['name'] = name;
 | |
|             dataObj['value'] = value;
 | |
|             dataObj['module'] = module;
 | |
|             dataObj['stringIds'] = stringIds;
 | |
| 
 | |
|             if flags is not None:
 | |
|                 dataObj._set_flags(flags);
 | |
| 
 | |
|             self._datas.add(name)
 | |
|             self.iterables.append(dataObj)
 | |
|             return dataObj
 | |
|         return None
 | |
| 
 | |
|     def del_data(self, name):
 | |
|         """
 | |
|         Remove a single data element.
 | |
| 
 | |
|         Arguments:
 | |
|             data_name  -- The data element name to remove.
 | |
|         """
 | |
|         if name in self._datas:
 | |
|             datas = [i for i in self.iterables if isinstance(i, Field)]
 | |
|             for data in datas:
 | |
|                 if data['name'] == name:
 | |
|                     self.xml.remove(data.xml)
 | |
|                     self.iterables.remove(data)
 | |
|                     return True
 | |
|         return False
 | |
| 
 | |
|     def get_datas(self):
 | |
|         """ Return all data elements. """
 | |
|         datas = []
 | |
|         for data in self['substanzas']:
 | |
|             if isinstance(data, Field):
 | |
|                 datas.append(data)
 | |
|         return datas
 | |
| 
 | |
|     def set_datas(self, datas):
 | |
|         """
 | |
|         Set or replace all data elements. The given elements must be in a
 | |
|         list or set where each item is a data element (numeric, string, boolean, dateTime, timeSpan or enum)
 | |
| 
 | |
|         Arguments:
 | |
|             datas -- A series of data elements.
 | |
|         """
 | |
|         self.del_datas()
 | |
|         for data in datas:
 | |
|             self.add_data(typename=data._get_typename(), name=data['name'], value=data['value'], module=data['module'], stringIds=data['stringIds'], unit=data['unit'], dataType=data['dataType'], flags=data._get_flags())
 | |
| 
 | |
|     def del_datas(self):
 | |
|         """Remove all data elements."""
 | |
|         self._datas = set()
 | |
|         datas = [i for i in self.iterables if isinstance(i, Field)]
 | |
|         for data in datas:
 | |
|             self.xml.remove(data.xml)
 | |
|             self.iterables.remove(data)
 | |
| 
 | |
| class DataNumeric(Field):
 | |
|     """ 
 | |
|     Field data of type numeric. 
 | |
|     Note that the value is expressed as a string. 
 | |
|     """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'numeric'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value', 'unit']);
 | |
|     interfaces.update(Field.interfaces);
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "numeric"    
 | |
| 
 | |
| class DataString(Field):
 | |
|     """ 
 | |
|     Field data of type string 
 | |
|     """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'string'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value']);
 | |
|     interfaces.update(Field.interfaces);
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "string"    
 | |
| 
 | |
| class DataBoolean(Field):
 | |
|     """ 
 | |
|     Field data of type boolean.
 | |
|     Note that the value is expressed as a string. 
 | |
|     """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'boolean'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value']);
 | |
|     interfaces.update(Field.interfaces);
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "boolean"    
 | |
| 
 | |
| class DataDateTime(Field):
 | |
|     """ 
 | |
|     Field data of type dateTime.
 | |
|     Note that the value is expressed as a string. 
 | |
|     """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'dateTime'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value']);
 | |
|     interfaces.update(Field.interfaces);
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "dateTime"    
 | |
| 
 | |
| class DataTimeSpan(Field):
 | |
|     """ 
 | |
|     Field data of type timeSpan.
 | |
|     Note that the value is expressed as a string. 
 | |
|     """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'timeSpan'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value']);
 | |
|     interfaces.update(Field.interfaces);
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "timeSpan"    
 | |
| 
 | |
| class DataEnum(Field):
 | |
|     """ 
 | |
|     Field data of type enum.
 | |
|     Note that the value is expressed as a string. 
 | |
|     """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'enum'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['value', 'dataType']);
 | |
|     interfaces.update(Field.interfaces);
 | |
| 
 | |
|     def _get_typename(self):
 | |
|         return "enum"    
 | |
| 
 | |
| class Done(ElementBase):
 | |
|     """ Done element used to signal that all data has been transferred """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'done'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr'])
 | |
| 
 | |
| class Cancel(ElementBase):
 | |
|     """ Cancel element used to signal that a request shall be cancelled """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'cancel'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr'])
 | |
| 
 | |
| class Cancelled(ElementBase):
 | |
|     """ Cancelled element used to signal that cancellation is confirmed """
 | |
|     namespace = 'urn:xmpp:iot:sensordata'
 | |
|     name = 'cancelled'
 | |
|     plugin_attrib = name
 | |
|     interfaces = set(['seqnr'])
 | |
| 
 | |
| 
 | |
| register_stanza_plugin(Iq, Request)
 | |
| register_stanza_plugin(Request, RequestNode, iterable=True)
 | |
| register_stanza_plugin(Request, RequestField, iterable=True)
 | |
| 
 | |
| register_stanza_plugin(Iq, Accepted)
 | |
| register_stanza_plugin(Message, Failure)
 | |
| register_stanza_plugin(Failure, Error)
 | |
| 
 | |
| register_stanza_plugin(Iq, Rejected)
 | |
| 
 | |
| register_stanza_plugin(Message, Fields)
 | |
| register_stanza_plugin(Fields, FieldsNode, iterable=True)
 | |
| register_stanza_plugin(FieldsNode, Timestamp, iterable=True)
 | |
| register_stanza_plugin(Timestamp, Field, iterable=True)
 | |
| register_stanza_plugin(Timestamp, DataNumeric, iterable=True)
 | |
| register_stanza_plugin(Timestamp, DataString, iterable=True)
 | |
| register_stanza_plugin(Timestamp, DataBoolean, iterable=True)
 | |
| register_stanza_plugin(Timestamp, DataDateTime, iterable=True)
 | |
| register_stanza_plugin(Timestamp, DataTimeSpan, iterable=True)
 | |
| register_stanza_plugin(Timestamp, DataEnum, iterable=True)
 | |
| 
 | |
| register_stanza_plugin(Message, Started)
 | |
| 
 | |
| register_stanza_plugin(Iq, Cancel)
 | |
| register_stanza_plugin(Iq, Cancelled)
 | 
