/// <summary> /// Loads the most recent Device telemetry. /// </summary> /// <param name="deviceId"> /// The ID of the Device for which telemetry should be returned. /// </param> /// <param name="minTime"> /// The minimum time of record of the telemetry that should be returned. /// </param> /// <returns> /// Telemetry for the Device specified by deviceId, inclusively since /// minTime. /// </returns> public async Task<IEnumerable<DeviceTelemetryModel>> LoadLatestDeviceTelemetryAsync( string deviceId, IList<DeviceTelemetryFieldModel> telemetryFields, DateTime minTime) { IEnumerable<DeviceTelemetryModel> result = new DeviceTelemetryModel[0]; IEnumerable<DeviceTelemetryModel> blobModels; var telemetryBlobReader = await _blobStorageManager.GetReader(_telemetryDataPrefix, minTime); foreach (var telemetryStream in telemetryBlobReader) { try { blobModels = LoadBlobTelemetryModels(telemetryStream.Data, telemetryFields); } catch { continue; } if (blobModels == null) { break; } int preFilterCount = blobModels.Count(); blobModels = blobModels.Where( t => (t != null) && t.Timestamp.HasValue && t.Timestamp.Value >= minTime); if (preFilterCount == 0) { break; } result = result.Concat(blobModels); } if (!string.IsNullOrEmpty(deviceId)) { result = result.Where(t => t.DeviceId == deviceId); } return result; }
/// <summary> /// Loads the most recent Device telemetry. /// </summary> /// <param name="deviceId"> /// The ID of the Device for which telemetry should be returned. /// </param> /// <param name="minTime"> /// The minimum time of record of the telemetry that should be returned. /// </param> /// <returns> /// Telemetry for the Device specified by deviceId, inclusively since /// minTime. /// </returns> public async Task<IEnumerable<DeviceTelemetryModel>> LoadLatestDeviceTelemetryAsync( string deviceId, DateTime minTime) { IEnumerable<DeviceTelemetryModel> blobModels; IEnumerable<IListBlobItem> blobs; CloudBlockBlob blockBlob; CloudBlobContainer container; int preFilterCount; IEnumerable<DeviceTelemetryModel> result; minTime = minTime.ToUniversalTime(); result = new DeviceTelemetryModel[0]; container = await BlobStorageHelper.BuildBlobContainerAsync( this._telemetryStoreConnectionString, _telemetryContainerName); blobs = await BlobStorageHelper.LoadBlobItemsAsync( async (token) => { return await container.ListBlobsSegmentedAsync( _telemetryDataPrefix, true, BlobListingDetails.None, null, token, null, null); }); blobs = blobs.OrderByDescending( t => BlobStorageHelper.ExtractBlobItemDate(t)); foreach (IListBlobItem blob in blobs) { if ((blockBlob = blob as CloudBlockBlob) == null) { continue; } try { blobModels = await LoadBlobTelemetryModelsAsync(blockBlob); } catch { continue; } if (blobModels == null) { break; } preFilterCount = blobModels.Count(); blobModels = blobModels.Where( t => (t != null) && t.Timestamp.HasValue && t.Timestamp.Value.ToUniversalTime() >= minTime); if (preFilterCount == 0) { break; } result = result.Concat(blobModels); if (preFilterCount != blobModels.Count()) { break; } } if (!string.IsNullOrEmpty(deviceId)) { result = result.Where(t => t.DeviceId == deviceId); } return result; }
private static List<DeviceTelemetryModel> LoadBlobTelemetryModels(Stream stream, IList<DeviceTelemetryFieldModel> telemetryFields) { Debug.Assert(stream != null, "stream is a null reference."); List<DeviceTelemetryModel> models = new List<DeviceTelemetryModel>(); TextReader reader = null; try { stream.Position = 0; reader = new StreamReader(stream); IEnumerable<StrDict> strdicts = ParsingHelper.ParseCsv(reader).ToDictionaries(); DeviceTelemetryModel model; string str; foreach (StrDict strdict in strdicts) { model = new DeviceTelemetryModel(); if (strdict.TryGetValue("deviceid", out str)) { model.DeviceId = str; } model.Timestamp = DateTime.Parse( strdict["eventenqueuedutctime"], CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces); IEnumerable<DeviceTelemetryFieldModel> fields; if (telemetryFields != null && telemetryFields.Count > 0) { fields = telemetryFields; } else { List<string> reservedColumns = new List<string> { "DeviceId", "EventEnqueuedUtcTime", "EventProcessedUtcTime", "IoTHub", "PartitionId" }; fields = strdict.Keys .Where((key) => !reservedColumns.Contains(key)) .Select((name) => new DeviceTelemetryFieldModel { Name = name, Type = "double" }); } foreach (var field in fields) { if (strdict.TryGetValue(field.Name, out str)) { switch (field.Type.ToLowerInvariant()) { case "int": case "int16": case "int32": case "int64": case "sbyte": case "byte": int intValue; if ( int.TryParse( str, NumberStyles.Integer, CultureInfo.InvariantCulture, out intValue) && !model.Values.ContainsKey(field.Name)) { model.Values.Add(field.Name, intValue); } break; case "double": case "decimal": case "single": double dblValue; if ( double.TryParse( str, NumberStyles.Float, CultureInfo.InvariantCulture, out dblValue) && !model.Values.ContainsKey(field.Name)) { model.Values.Add(field.Name, dblValue); } break; } } } models.Add(model); } } finally { IDisposable disp; if ((disp = stream) != null) { disp.Dispose(); } if ((disp = reader) != null) { disp.Dispose(); } } return models; }
private async static Task<List<DeviceTelemetryModel>> LoadBlobTelemetryModelsAsync( CloudBlockBlob blob) { DateTime date; IDisposable disp; DeviceTelemetryModel model; List<DeviceTelemetryModel> models; double number; TextReader reader; string str; IEnumerable<StrDict> strdicts; MemoryStream stream; Debug.Assert(blob != null, "blob is a null reference."); models = new List<DeviceTelemetryModel>(); reader = null; stream = null; try { stream = new MemoryStream(); await blob.DownloadToStreamAsync(stream); stream.Position = 0; reader = new StreamReader(stream); strdicts = ParsingHelper.ParseCsv(reader).ToDictionaries(); foreach (StrDict strdict in strdicts) { model = new DeviceTelemetryModel(); if (strdict.TryGetValue("DeviceId", out str)) { model.DeviceId = str; } if (strdict.TryGetValue("ExternalTemperature", out str) && double.TryParse(str, out number)) { model.ExternalTemperature = number; } if (strdict.TryGetValue("Humidity", out str) && double.TryParse(str, out number)) { model.Humidity = number; } if (strdict.TryGetValue("Temperature", out str) && double.TryParse(str, out number)) { model.Temperature = number; } if (strdict.TryGetValue("EventEnqueuedUtcTime", out str) && DateTime.TryParse(str, out date)) { model.Timestamp = date; } models.Add(model); } } finally { if ((disp = stream) != null) { disp.Dispose(); } if ((disp = reader) != null) { disp.Dispose(); } } return models; }