'Called on the client side to initiate a data readout.
Composes a message with the request and sends it to the device(s).
Does not block, the callback will be called when data is available.
Arguments:
from_jid        -- The jid of the requester
to_jid          -- The jid of the device(s)
callback        -- The callback function to call when data is available.
The callback function must support the following arguments:
from_jid    -- The jid of the responding device(s)
result      -- The current result status of the readout. Valid values are:
"accepted"  - Readout request accepted
"queued"    - Readout request accepted and queued
"rejected"  - Readout request rejected
"failure"   - Readout failed.
"cancelled" - Confirmation of request cancellation.
"started"   - Previously queued request is now started
"fields"    - Contains readout data.
"done"      - Indicates that the readout is complete.
nodeId      -- [optional] Mandatory when result == "fields" or "failure".
The node Id of the responding device. One callback will only
contain data from one device.
timestamp   -- [optional] Mandatory when result == "fields".
The timestamp of data in this callback. One callback will only
contain data from one timestamp.
fields      -- [optional] Mandatory when result == "fields".
List of field dictionaries representing the readout data.
Dictionary format:
typename:  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] Mandatory when result == "rejected" or "failure".
Details about why the request is rejected or failed.
"rejected" means that the request is stopped, but note that the
request will continue even after a "failure". "failure" only means
that communication was stopped to that specific device, other
device(s) (if any) will continue their readout.
nodeIds      -- [optional] Limits the request to the node Ids in this list.
fields       -- [optional] Limits the request to the field names in this list.
flags        -- [optional] Limits the request according to the flags, or sets
readout conditions such as timing.
Return value:
session      -- Session identifier. Client can use this as a reference to cancel
the request.'

def request_data(self, from_jid, to_jid, callback, nodeIds=None, fields=None, flags=None):

    iq = self.xmpp.Iq()
    iq['from'] = from_jid
    iq['to'] = to_jid
    iq['type'] = 'get'
    seqnr = self._get_new_seqnr()
    iq['id'] = seqnr
    iq['req']['seqnr'] = seqnr
    if (nodeIds is not None):
        for nodeId in nodeIds:
            iq['req'].add_node(nodeId)
    if (fields is not None):
        for field in fields:
            iq['req'].add_field(field)
    iq['req']._set_flags(flags)
    self.sessions[seqnr] = {'from': iq['from'], 'to': iq['to'], 'seqnr': seqnr, 'callback': callback}
    iq.send(block=False)
    return seqnr
