code: def FromReadings(cls, uuid, readings, events, report_id=IOTileReading.InvalidReadingID,
                       selector=0xFFFF, streamer=0x100, sent_timestamp=0, received_time=None):
          lowest_id = IOTileReading.InvalidReadingID
          highest_id = IOTileReading.InvalidReadingID
          for item in itertools.chain(iter(readings), iter(events)):
              if item.reading_id == IOTileReading.InvalidReadingID:
                  continue
              if lowest_id == IOTileReading.InvalidReadingID or item.reading_id < lowest_id:
                  lowest_id = item.reading_id
              if highest_id == IOTileReading.InvalidReadingID or item.reading_id > highest_id:
                  highest_id = item.reading_id
          reading_list = [x.asdict() for x in readings]
          event_list = [x.asdict() for x in events]
          report_dict = {
              "format": cls.FORMAT_TAG,
              "device": uuid,
              "streamer_index": streamer,
              "streamer_selector": selector,
              "incremental_id": report_id,
              "lowest_id": lowest_id,
              "highest_id": highest_id,
              "device_sent_timestamp": sent_timestamp,
              "events": event_list,
              "data": reading_list
          }
          encoded = msgpack.packb(report_dict, default=_encode_datetime, use_bin_type=True)
          return FlexibleDictionaryReport(encoded, signed=False, encrypted=False, received_time=received_time)