'Starts a data readout. Verifies the requested fields,
refreshes the data (if needed) and calls the callback
with requested data.
Arguments:
fields   -- List of field names to readout
flags    -- [optional] data classifier flags for the field, e.g. momentary
Formatted as a dictionary like { "flag name": "flag value" ... }
session  -- Session id, only used in the callback as identifier
callback -- Callback function to call when data is available.
The callback function must support the following arguments:
session  -- Session id, as supplied in the request_fields call
nodeId   -- Identifier for this device
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 request_fields(self, fields, flags, session, callback):

    logging.debug('request_fields    called    looking    for    fields    %s', fields)
    if (len(fields) > 0):
        for f in fields:
            if (f not in self.fields.keys()):
                self._send_reject(session, callback)
                return False
    else:
        fields = self.fields.keys()
    logging.debug('about    to    refresh    device    fields    %s', fields)
    self.refresh(fields)
    if ((('momentary' in flags) and (flags['momentary'] == 'true')) or (('all' in flags) and (flags['all'] == 'true'))):
        ts_block = {}
        timestamp = ''
        if (len(self.momentary_timestamp) > 0):
            timestamp = self.momentary_timestamp
        else:
            timestamp = self._get_timestamp()
        field_block = []
        for f in self.momentary_data:
            if (f in fields):
                field_block.append({'name': f, 'type': self.fields[f]['type'], 'unit': self.fields[f]['unit'], 'dataType': self.fields[f]['dataType'], 'value': self.momentary_data[f]['value'], 'flags': self.momentary_data[f]['flags']})
        ts_block['timestamp'] = timestamp
        ts_block['fields'] = field_block
        callback(session, result='done', nodeId=self.nodeId, timestamp_block=ts_block)
        return
    from_flag = self._datetime_flag_parser(flags, 'from')
    to_flag = self._datetime_flag_parser(flags, 'to')
    for ts in sorted(self.timestamp_data.keys()):
        tsdt = datetime.datetime.strptime(ts, '%Y-%m-%dT%H:%M:%S')
        if (not (from_flag is None)):
            if (tsdt < from_flag):
                continue
        if (not (to_flag is None)):
            if (tsdt > to_flag):
                continue
        ts_block = {}
        field_block = []
        for f in self.timestamp_data[ts]:
            if (f in fields):
                field_block.append({'name': f, 'type': self.fields[f]['type'], 'unit': self.fields[f]['unit'], 'dataType': self.fields[f]['dataType'], 'value': self.timestamp_data[ts][f]['value'], 'flags': self.timestamp_data[ts][f]['flags']})
        ts_block['timestamp'] = ts
        ts_block['fields'] = field_block
        callback(session, result='fields', nodeId=self.nodeId, timestamp_block=ts_block)
    callback(session, result='done', nodeId=self.nodeId, timestamp_block=None)
