public DeviceTableEntity(DeviceDocument deviceDoc) { this.PartitionKey = deviceDoc.GatewayName; this.RowKey = deviceDoc.DeviceName; this.Timestamp = DateTime.UtcNow; this.DeviceDoc = deviceDoc; this.Text = JsonConvert.SerializeObject(deviceDoc); }
public static async Task HandleMessageBatch( List <BACNetIoTHubMessage> messageBatch, List <DeviceDocument> knownDeviceDocuments, IAsyncCollector <DeviceDocument> deviceDocumentsWriteCollector, IAsyncCollector <string> eventCollector, IAsyncCollector <DeviceTableEntity> unprovisionedDeviceCollector, ILogger log, CancellationToken cancellationToken) { List <string> unprovisioned = new List <string>(); foreach (var bacNetIoTHubMsg in messageBatch) { if (cancellationToken.IsCancellationRequested) { log.LogWarning("Function was cancelled."); break; } DeviceDocument deviceDoc = GetKnownOrNewDeviceDoc(knownDeviceDocuments, bacNetIoTHubMsg.BACNetMsg.name); //update the device doc with inbound telemetry (value, timestamp, status, etc.) deviceDoc = ApplyTelemetryToDeviceDoc(bacNetIoTHubMsg, deviceDoc); //UpSERT the device document to Cosmos await deviceDocumentsWriteCollector.AddAsync(deviceDoc, cancellationToken); if (String.Equals(deviceDoc.DeviceStatus, DEVICE_STATUS_UNPROVISIONED, StringComparison.OrdinalIgnoreCase)) { //Handle Unprovisioned Devices here unprovisioned.Add(bacNetIoTHubMsg.BACNetMsg.name); await unprovisionedDeviceCollector.AddAsync(new DeviceTableEntity(bacNetIoTHubMsg), cancellationToken); } else { //Provisioned Device only code await eventCollector.AddAsync(JsonConvert.SerializeObject(deviceDoc), cancellationToken); } } if (unprovisioned.Any()) { Interlocked.Increment(ref unprovisionedCount); log.LogError($"Unprovisioned DeviceIds encountered: {String.Join(',', unprovisioned)} "); } }
private static DeviceDocument GetKnownOrNewDeviceDoc( List <DeviceDocument> knownDeviceDocuments, string deviceId) { //Lookup Known Devices in CosmosDB by Id var deviceDoc = knownDeviceDocuments.SingleOrDefault( document => document.id == deviceId); if (deviceDoc == null) //not found, so create a new one and mark it unprovisioned { deviceDoc = new DeviceDocument() { id = deviceId, DeviceStatus = DEVICE_STATUS_UNPROVISIONED }; } return(deviceDoc); }
public static DeviceDocument ApplyTelemetryToDeviceDoc( BACNetIoTHubMessage bacNetIoTHubMessage, DeviceDocument inputDeviceDocument) { //Todo figure out how this function becomes modularized/configurable var parsedDeviceName = ((string)bacNetIoTHubMessage.BACNetMsg.name).Split('_'); string unparsedValue = bacNetIoTHubMessage.BACNetMsg.value.ToString(); (string value, string unit) = ParseValueUnit(unparsedValue, parsedDeviceName[2]); inputDeviceDocument.PresentValue = value; inputDeviceDocument.ValueUnits = unit; inputDeviceDocument.DeviceTimestamp = DateTimeOffset.Parse((string)bacNetIoTHubMessage.BACNetMsg.timestamp, styles: DateTimeStyles.RoundtripKind); //preserve Unprovisioned status if (!String.Equals(inputDeviceDocument.DeviceStatus, DEVICE_STATUS_UNPROVISIONED, StringComparison.OrdinalIgnoreCase)) { inputDeviceDocument.DeviceStatus = bacNetIoTHubMessage.BACNetMsg.status; } inputDeviceDocument.EventEnqueuedUtcTime = bacNetIoTHubMessage.SystemProperties?.EnqueuedTimeUtc ?? DateTime.UtcNow; return(inputDeviceDocument); }