// Sends device telemetry data to IoT Hub private async Task <bool> SendDeviceEventAsync(LoRaDevice loRaDevice, Rxpk rxpk, object decodedValue, LoRaPayloadData loRaPayloadData, LoRaOperationTimeWatcher timeWatcher) { var deviceTelemetry = new LoRaDeviceTelemetry(rxpk, loRaPayloadData, decodedValue) { DeviceEUI = loRaDevice.DevEUI, GatewayID = this.configuration.GatewayID, Edgets = (long)(timeWatcher.Start - DateTime.UnixEpoch).TotalMilliseconds }; Dictionary <string, string> eventProperties = null; if (loRaPayloadData.IsUpwardAck()) { eventProperties = new Dictionary <string, string>(); Logger.Log(loRaDevice.DevEUI, $"Message ack received for C2D message id {loRaDevice.LastConfirmedC2DMessageID}", LogLevel.Information); eventProperties.Add(C2D_MSG_PROPERTY_VALUE_NAME, loRaDevice.LastConfirmedC2DMessageID ?? C2D_MSG_ID_PLACEHOLDER); loRaDevice.LastConfirmedC2DMessageID = null; } var macCommand = loRaPayloadData.GetMacCommands(); if (macCommand.MacCommand.Count > 0) { eventProperties = eventProperties ?? new Dictionary <string, string>(); for (int i = 0; i < macCommand.MacCommand.Count; i++) { eventProperties[macCommand.MacCommand[i].Cid.ToString()] = JsonConvert.SerializeObject(macCommand.MacCommand[i], Formatting.None); // in case it is a link check mac, we need to send it downstream. if (macCommand.MacCommand[i].Cid == CidEnum.LinkCheckCmd) { // linkCheckCmdResponse = new LinkCheckCmd(rxPk.GetModulationMargin(), 1).ToBytes(); } } } if (await loRaDevice.SendEventAsync(deviceTelemetry, eventProperties)) { var payloadAsRaw = deviceTelemetry.Data as string; if (payloadAsRaw == null && deviceTelemetry.Data != null) { payloadAsRaw = JsonConvert.SerializeObject(deviceTelemetry.Data, Formatting.None); } Logger.Log(loRaDevice.DevEUI, $"message '{payloadAsRaw}' sent to hub", LogLevel.Information); return(true); } return(false); }