Exemplo n.º 1
0
        static async Task DeviceTelemetrySend(DeviceClient deviceClient, PayloadUplink payloadObject)
        {
            JObject telemetryEvent = new JObject
            {
                { "DeviceEUI", payloadObject.DeviceEui },
                { "Retry", payloadObject.IsRetry },
                { "Counter", payloadObject.Counter },
                { "DeviceID", payloadObject.DeviceId },
                { "ApplicationID", payloadObject.ApplicationId },
                { "Port", payloadObject.Port },
                { "PayloadRaw", payloadObject.PayloadRaw },
                { "ReceivedAtUTC", payloadObject.Metadata.ReceivedAtUtc }
            };

            // If the payload has been unpacked in TTN backend add fields to telemetry event payload
            if (payloadObject.PayloadFields != null)
            {
                EnumerateChildren(telemetryEvent, payloadObject.PayloadFields);
            }

            // Send the message to Azure IoT Hub/Azure IoT Central
            using (Message ioTHubmessage = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(telemetryEvent))))
            {
                // Ensure the displayed time is the acquired time rather than the uploaded time. esp. important for when messages that ended up
                // in poison queue are returned to the processing queue.
                ioTHubmessage.Properties.Add("iothub-creation-time-utc", payloadObject.Metadata.ReceivedAtUtc.ToString("s", CultureInfo.InvariantCulture));
                await deviceClient.SendEventAsync(ioTHubmessage);
            }
        }
Exemplo n.º 2
0
        public static async Task UplinkRun(
            [QueueTrigger("%UplinkQueueName%", Connection = "AzureStorageConnectionString")]
            PayloadUplink payload,
            ILogger log)
        {
            // Quick n dirty hack to see what difference (if any) not processing retries makes
            if (payload.IsRetry)
            {
                log.LogInformation("DevID:{DeviceId} Counter:{Counter} AppID:{ApplicationId} Uplink message retry", payload.DeviceId, payload.Counter, payload.ApplicationId);
                return;
            }

            log.LogInformation("DevID:{DeviceId} Counter:{Counter} AppID:{ApplicationId} Uplink message device processing start", payload.DeviceId, payload.Counter, payload.ApplicationId);

            ApplicationConfiguration.Initialise();

            string registrationId = ApplicationConfiguration.RegistrationIdResolve(payload.ApplicationId, payload.Port, payload.DeviceId);

            CacheItemPolicy cacheItemPolicy = new CacheItemPolicy()
            {
                SlidingExpiration = new TimeSpan(1, 0, 0, 0),
                //RemovedCallback
            };

            DeviceContext deviceContext = new DeviceContext()
            {
                Uplink   = null,
                Downlink = new Uri(payload.DownlinkUrl)
            };

            // See if the device has already been provisioned or is being provisioned on another thread.
            if (DeviceClients.Add(registrationId, deviceContext, cacheItemPolicy))
            {
                log.LogInformation("RegID:{registrationId} Device provisioning start", registrationId);

                try
                {
                    // Get DeviceClient if first time device seen
                    deviceContext.Uplink = await DeviceRegistration(payload.ApplicationId, payload.DeviceId, payload.Port);
                }
                catch (Exception ex)
                {
                    if (DeviceClients.Remove(registrationId) == null)
                    {
                        log.LogWarning("RegID:{registrationID} Device Registration TryRemove failed", registrationId);
                    }

                    log.LogError(ex, "RegID:{registrationID} Device Registration failed", registrationId);
                    throw;
                }

                DeviceClients.Set(registrationId, deviceContext, cacheItemPolicy);

                log.LogInformation("RegID:{registrationId} Assigned to IoTHub", registrationId);
            }

            // Wait for the Device Provisioning Service to complete on this or other thread
            log.LogInformation("RegID:{registrationId} Device provisioning polling start", payload.DeviceId);

            int deviceProvisioningPollingDelay = ApplicationConfiguration.DpsDeviceProvisioningPollingDelay();

            // Wait for the deviceClient to be configured if process kicked off on another thread, no timeout as will get taken care of by function timeout...
            do
            {
                deviceContext = (DeviceContext)DeviceClients.Get(registrationId);
                if (deviceContext == null)
                {
                    log.LogError("RegID:{registrationId} DeviceContext provisioning polling Get failed", registrationId);

                    throw new ApplicationException($"RegID:{registrationId} DeviceContext provisioning polling Get failed");
                }

                if (deviceContext.Uplink == null)
                {
                    log.LogInformation($"RegID:{registrationId} Device provisioning polling delay:{deviceProvisioningPollingDelay}mSec", registrationId, deviceProvisioningPollingDelay);
                    await Task.Delay(deviceProvisioningPollingDelay);
                }
            }while (deviceContext.Uplink == null);

            log.LogInformation("DevID:{DeviceId} Counter:{counter} Payload Send start", payload.DeviceId, payload.Counter);

            try
            {
                await DeviceTelemetrySend(deviceContext.Uplink, payload);
            }
            catch (Exception ex)
            {
                if (DeviceClients.Remove(registrationId) == null)
                {
                    log.LogWarning("DevID:{DeviceId} Counter:{Counter} Payload SendEventAsync TryRemove failed", payload.DeviceId, payload.Counter);
                }

                log.LogError(ex, "DevID:{DeviceId} Counter:{Counter} Telemetry event send failed", payload.DeviceId, payload.Counter);
                throw;
            }

            log.LogInformation("DevID:{DeviceId} Counter:{Counter} Uplink message device processing completed", payload.DeviceId, payload.Counter);
        }