'Callback function called by the devices when they have any additional data.
Composes a message with the data and sends it back to the client, and resets
the timeout timer for the device.
Arguments:
session         -- The request session id
nodeId          -- The device id which initiated the callback
result          -- The current result status of the readout. Valid values are:
"error"  - Readout failed.
"fields" - Contains readout data.
"done"   - Indicates that the readout is complete. May contain
readout data.
timestamp_block -- [optional] Only applies when result != "error"
The readout data. Structured as a dictionary:
timestamp:     timestamp for this datablock,
fields:        list of field dictionary (one per readout field).
readout field dictionary format:
type:      The field type (numeric, boolean, dateTime, timeSpan, string, enum)
name:      The field name
value:     The field value
unit:      The unit of the field. Only applies to type numeric.
dataType:  The datatype of the field. Only applies to type enum.
flags:     [optional] data classifier flags for the field, e.g. momentary
Formatted as a dictionary like { "flag name": "flag value" ... }
error_msg        -- [optional] Only applies when result == "error".
Error details when a request failed.'

def _device_field_request_callback(self, session, nodeId, result, timestamp_block, error_msg=None):

    if (not (session in self.sessions)):
        return
    if (result == 'error'):
        self.sessions[session]['commTimers'][nodeId].cancel()
        msg = self.xmpp.Message()
        msg['from'] = self.sessions[session]['to']
        msg['to'] = self.sessions[session]['from']
        msg['failure']['seqnr'] = self.sessions[session]['seqnr']
        msg['failure']['error']['text'] = error_msg
        msg['failure']['error']['nodeId'] = nodeId
        msg['failure']['error']['timestamp'] = datetime.datetime.now().replace(microsecond=0).isoformat()
        self.sessions[session]['nodeDone'][nodeId] = True
        if self._all_nodes_done(session):
            msg['failure']['done'] = 'true'
            del self.sessions[session]
        msg.send()
    else:
        msg = self.xmpp.Message()
        msg['from'] = self.sessions[session]['to']
        msg['to'] = self.sessions[session]['from']
        msg['fields']['seqnr'] = self.sessions[session]['seqnr']
        if ((timestamp_block is not None) and (len(timestamp_block) > 0)):
            node = msg['fields'].add_node(nodeId)
            ts = node.add_timestamp(timestamp_block['timestamp'])
            for f in timestamp_block['fields']:
                data = ts.add_data(typename=f['type'], name=f['name'], value=f['value'], unit=f['unit'], dataType=f['dataType'], flags=f['flags'])
        if (result == 'done'):
            self.sessions[session]['commTimers'][nodeId].cancel()
            self.sessions[session]['nodeDone'][nodeId] = True
            if self._all_nodes_done(session):
                del self.sessions[session]
                msg['fields']['done'] = 'true'
        else:
            self.sessions[session]['commTimers'][nodeId].reset()
        msg.send()
