Ejemplo n.º 1
0
        private void Rfm9XDevice_OnReceive(object sender, Rfm9XDevice.OnDataReceivedEventArgs e)
        {
            LoggingFields messageHandlerLoggingFields = new LoggingFields();

#if DEBUG
            Debug.WriteLine($"{DateTime.UtcNow:HH:mm:ss}-OnReceive From:{BitConverter.ToString(e.Address)} PacketSnr:{e.PacketSnr:0.0} Packet RSSI:{e.PacketRssi}dBm RSSI:{e.Rssi}dBm Length:{e.Data.Length}");
#endif
            messageHandlerLoggingFields.AddString("PacketSNR", e.PacketSnr.ToString("F1"));
            messageHandlerLoggingFields.AddInt32("PacketRSSI", e.PacketRssi);
            messageHandlerLoggingFields.AddInt32("RSSI", e.Rssi);

            string addressBcdText = BitConverter.ToString(e.Address);
            messageHandlerLoggingFields.AddInt32("DeviceAddressLength", e.Address.Length);
            messageHandlerLoggingFields.AddString("DeviceAddressBCD", addressBcdText);

            if (messageHandler != null)
            {
                try
                {
                    messageHandler.Rfm9XOnReceive(e);
                }
                catch (Exception ex)
                {
                    messageHandlerLoggingFields.AddString("MessageHandler Exception", ex.ToString());
                    this.logging.LogEvent("Rfm9XDevice_OnReceive", messageHandlerLoggingFields, LoggingLevel.Error);
                    return;
                }
            }
            this.logging.LogEvent("Rfm9XDevice_OnReceive", messageHandlerLoggingFields, LoggingLevel.Information);
        }
Ejemplo n.º 2
0
        private async Task <MethodResponse> DeviceSendAsync(MethodRequest methodRequest, object userContext)
        {
            LoggingFields sendLoggingInfo = new LoggingFields();

            this.logging.LogEvent("Send BCD initiated");

            try
            {
                // Initially use a dynamic maybe use a decorated class in future
                dynamic json = JValue.Parse(methodRequest.DataAsJson);

                string deviceAddressBcd = json.DeviceAddress;
                sendLoggingInfo.AddString("DeviceAddressBCD", deviceAddressBcd);
                Debug.WriteLine($"DeviceSendAsync DeviceAddressBCD {deviceAddressBcd}");

                byte[] deviceAddressBytes = deviceAddressBcd.Split('-').Select(x => byte.Parse(x, NumberStyles.HexNumber)).ToArray();
                sendLoggingInfo.AddInt32("DeviceAddressBytes Length", deviceAddressBytes.Length);
                Debug.WriteLine($"DeviceSendAsync DeviceAddressLength {deviceAddressBytes.Length}");

                if ((deviceAddressBytes.Length < Rfm9XDevice.AddressLengthMinimum) || (deviceAddressBytes.Length > Rfm9XDevice.AddressLengthMaximum))
                {
                    this.logging.LogEvent("DeviceSendAsync failed device address bytes length", sendLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(414));
                }

                string messagedBcd = json.DevicePayload;
                sendLoggingInfo.AddString("MessageBCD", messagedBcd);

                byte[] messageBytes = messagedBcd.Split('-').Select(x => byte.Parse(x, NumberStyles.HexNumber)).ToArray();                 // changed the '-' to ' '
                sendLoggingInfo.AddInt32("MessageBytesLength", messageBytes.Length);
                Debug.WriteLine($"DeviceSendAsync DeviceAddress:{deviceAddressBcd} Payload:{messagedBcd}");

                if ((messageBytes.Length < Rfm9XDevice.MessageLengthMinimum) || (messageBytes.Length > Rfm9XDevice.MessageLengthMaximum))
                {
                    this.logging.LogEvent("DeviceSendAsync failed payload Length", sendLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(413));
                }

                if (sendMessageQueue.TryAdd(deviceAddressBytes, messageBytes))
                {
                    this.logging.LogEvent("DeviceSendAsync failed message already queued", sendLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(409));
                }

                this.logging.LogEvent("DeviceSendAsync success", sendLoggingInfo, LoggingLevel.Information);
            }
            catch (Exception ex)
            {
                sendLoggingInfo.AddString("Exception", ex.ToString());
                this.logging.LogEvent("DeviceSendAsync failed exception", sendLoggingInfo, LoggingLevel.Error);
                return(new MethodResponse(400));
            }

            return(new MethodResponse(200));
        }
Ejemplo n.º 3
0
        async Task PayloadText(DeviceClient azureIoTHubClient, Rfm9XDevice.OnDataReceivedEventArgs e)
        {
            JObject       telemetryDataPoint   = new JObject();
            LoggingFields processLoggingFields = new LoggingFields();

            processLoggingFields.AddString("PacketSNR", e.PacketSnr.ToString("F1"));
            telemetryDataPoint.Add("PacketSNR", e.PacketSnr.ToString("F1"));
            processLoggingFields.AddInt32("PacketRSSI", e.PacketRssi);
            telemetryDataPoint.Add("PacketRSSI", e.PacketRssi);
            processLoggingFields.AddInt32("RSSI", e.Rssi);
            telemetryDataPoint.Add("RSSI", e.Rssi);

            string addressBcdText = BitConverter.ToString(e.Address);

            processLoggingFields.AddInt32("DeviceAddressLength", e.Address.Length);
            processLoggingFields.AddString("DeviceAddressBCD", addressBcdText);
            telemetryDataPoint.Add("DeviceAddressBCD", addressBcdText);

            string messageBcdText = BitConverter.ToString(e.Data);

            processLoggingFields.AddInt32("MessageLength", e.Data.Length);
            processLoggingFields.AddString("MessageBCD", messageBcdText);

            try
            {
                string messageText = UTF8Encoding.UTF8.GetString(e.Data);
                processLoggingFields.AddString("MessageText", messageText);
                telemetryDataPoint.Add("Payload", messageText);
            }
            catch (Exception)
            {
                this.logging.LogEvent("PayloadProcess failure converting payload to text", processLoggingFields, LoggingLevel.Warning);
                return;
            }

            try
            {
                using (Message message = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(telemetryDataPoint))))
                {
                    Debug.WriteLine(" {0:HH:mm:ss} AzureIoTHubClient SendEventAsync start", DateTime.UtcNow);
                    await this.azureIoTHubClient.SendEventAsync(message);

                    Debug.WriteLine(" {0:HH:mm:ss} AzureIoTHubClient SendEventAsync finish", DateTime.UtcNow);
                }
                this.logging.LogEvent("SendEventAsync Text payload", processLoggingFields, LoggingLevel.Information);
            }
            catch (Exception ex)
            {
                processLoggingFields.AddString("Exception", ex.ToString());
                this.logging.LogEvent("SendEventAsync Text payload", processLoggingFields, LoggingLevel.Error);
            }
        }
Ejemplo n.º 4
0
        private void WriteLog(string text,
                              LoggingLevel loggingLevel               = LoggingLevel.Verbose,
                              [CallerMemberName] string memberName    = "",
                              [CallerFilePath] string sourceFilePath  = "",
                              [CallerLineNumber] int sourceLineNumber = 0)
        {
            Debug.WriteLine($"[Log::{Enum.GetName(typeof(LoggingLevel), loggingLevel)}][{memberName}] {text}");

            if (_session == null || _channel == null)
            {
                Debug.WriteLine("Error: Logger is not initialized");
                return;
            }

            try
            {
                string message =
                    "Message: " + text + Environment.NewLine + Environment.NewLine +
                    "Member name: " + memberName + Environment.NewLine +
                    "Source file path: " + sourceFilePath + Environment.NewLine +
                    "Source line number: " + sourceLineNumber + Environment.NewLine;

                var fields = new LoggingFields();
                fields.AddString("MemberName", memberName);
                fields.AddString("SourceFilePath", sourceFilePath);
                fields.AddInt32("SourceLineNumber", sourceLineNumber);
                fields.AddString("Message", text);

                _channel.LogEvent("LogEvent", fields, loggingLevel);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("[Log] " + ex);
            }
        }
Ejemplo n.º 5
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            LoggingFields startupInformation = new LoggingFields();

            this.logging.LogEvent("Application starting");

            try
            {
                this.mediaCapture = new MediaCapture();
                this.mediaCapture.InitializeAsync().AsTask().Wait();
                Debug.WriteLine("Camera configuration success");

                GpioController gpioController = GpioController.GetDefault();

                this.interruptGpioPin = gpioController.OpenPin(InterruptPinNumber);
                this.interruptGpioPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
                this.interruptGpioPin.ValueChanged += this.InterruptGpioPin_ValueChanged;
                Debug.WriteLine("Digital Input Interrupt configuration success");
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera or digital input configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            startupInformation.AddString("PrimaryUse", this.mediaCapture.VideoDeviceController.PrimaryUse.ToString());
            startupInformation.AddInt32("Interrupt pin", InterruptPinNumber);

            this.logging.LogEvent("Application started", startupInformation);

            // enable task to continue running in background
            this.backgroundTaskDeferral = taskInstance.GetDeferral();
        }
        void IMessageHandler.Rfm9XOnReceive(Rfm9XDevice.OnDataReceivedEventArgs e)
        {
            LoggingFields processReceiveLoggingFields = new LoggingFields();

            processReceiveLoggingFields.AddString("PacketSNR", e.PacketSnr.ToString("F1"));
            processReceiveLoggingFields.AddInt32("PacketRSSI", e.PacketRssi);
            processReceiveLoggingFields.AddInt32("RSSI", e.Rssi);

            string addressBcdText = BitConverter.ToString(e.Address);

            processReceiveLoggingFields.AddInt32("DeviceAddressLength", e.Address.Length);
            processReceiveLoggingFields.AddString("DeviceAddressBCD", addressBcdText);

            string payloadBcdText = BitConverter.ToString(e.Data);

            processReceiveLoggingFields.AddInt32("PayloadLength", e.Data.Length);
            processReceiveLoggingFields.AddString("DeviceAddressBCD", payloadBcdText);

            this.Logging.LogEvent("Rfm9XOnReceive", processReceiveLoggingFields, LoggingLevel.Information);
        }
Ejemplo n.º 7
0
        public void ResizeVisibleComplete(int viewId)
        {
            if (!GetTraceLoggingProviderEnabled())
            {
                return;
            }

            LoggingFields fields = new LoggingFields();

            PopulateAppInfo(fields);
            fields.AddInt32("ViewId", viewId);
            LogAppLifecycleEvent("ModernAppResize_VisibleComplete", fields);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Logs an exception and returns it.
        /// </summary>
        /// <param name="msg">A message associated with the exception.</param>
        /// <param name="exception">The exception.</param>
        /// <returns>The exception.</returns>
        public static Exception LogException(string msg, Exception exception)
        {
            Debug.WriteLine("Exception: " + msg);
            Debug.WriteLine("Message: " + exception.Message);

            LoggingFields fields = new LoggingFields();

            fields.AddString("Error message", msg);
            fields.AddString("Exception message", exception.Message);
            fields.AddInt32("HResult", exception.HResult);

            Instance().channel.LogEvent("Exception", fields, LoggingLevel.Error);

            return(exception);
        }
Ejemplo n.º 9
0
 private static void PushException(ref LoggingFields a, Exception m)
 {
     if (m != null)
     {
         a.BeginStruct("Exception");
         a.AddString("Type", m.GetType().Name);
         a.AddString("Message", m.Message ?? string.Empty);
         a.AddString("Source", m.Source ?? string.Empty);
         a.AddInt32("HResult", m.HResult);
         a.AddString("StackTrace", m.StackTrace ?? string.Empty);
         PushException(ref a, m.InnerException);
         a.EndStruct();
     }
     else
     {
         return;
     }
 }
Ejemplo n.º 10
0
        private async Task <MethodResponse> RestartAsync(MethodRequest methodRequest, object userContext)
        {
            LoggingFields restartLoggingInfo = new LoggingFields();

#if CLOUD_DEVICE_SEND
            restartLoggingInfo.AddInt32("Send message queue count", sendMessageQueue.Count);
#endif
            restartLoggingInfo.AddTimeSpan("Device restart period", DeviceRestartPeriod);

            // Disconnect the transmit and receive callbacks, once messages Send & Push need to consider what todo with queued outbound messages
            rfm9XDevice.OnReceive  -= Rfm9XDevice_OnReceive;
            rfm9XDevice.OnTransmit -= Rfm9XDevice_OnTransmit;

            this.logging.LogEvent("Restart initiated", restartLoggingInfo, LoggingLevel.Information);

            ShutdownManager.BeginShutdown(ShutdownKind.Restart, DeviceRestartPeriod);

            return(new MethodResponse(200));
        }
Ejemplo n.º 11
0
        private async Task <MethodResponse> DeviceBondAsync(MethodRequest methodRequest, object userContext)
        {
            LoggingFields bondLoggingInfo = new LoggingFields();

            try
            {
                dynamic json = JValue.Parse(methodRequest.DataAsJson);

                string deviceAddressBcd = json.DeviceAddressBCD;
                bondLoggingInfo.AddString("DeviceAddressBCD", deviceAddressBcd);
                Debug.WriteLine($"DeviceBondAsync DeviceAddressBCD {deviceAddressBcd}");

                byte[] deviceAddressBytes = deviceAddressBcd.Split('-').Select(x => byte.Parse(x, NumberStyles.HexNumber)).ToArray();
                bondLoggingInfo.AddInt32("DeviceAddressBytes Length", deviceAddressBytes.Length);
                Debug.WriteLine($"DeviceBondAsync DeviceAddressLength {deviceAddressBytes.Length}");

                if ((deviceAddressBytes.Length < Rfm9XDevice.AddressLengthMinimum) || (deviceAddressBytes.Length > Rfm9XDevice.AddressLengthMaximum))
                {
                    this.logging.LogEvent("DeviceBondAsync failed device address bytes length", bondLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(414));
                }

                // Empty payload for bond message
                byte[] payloadBytes = {};

                rfm9XDevice.Send(deviceAddressBytes, payloadBytes);

                this.logging.LogEvent("DeviceBondAsync success", bondLoggingInfo, LoggingLevel.Information);
            }
            catch (Exception ex)
            {
                bondLoggingInfo.AddString("Exception", ex.ToString());
                this.logging.LogEvent("DeviceBondAsync exception", bondLoggingInfo, LoggingLevel.Error);
                return(new MethodResponse(400));
            }

            return(new MethodResponse(200));
        }
        private async void Rfm9XDevice_OnReceive(object sender, Rfm9XDevice.OnDataReceivedEventArgs e)
        {
            string addressBcdText;
            string messageBcdText;
            string messageText = "";

            char[] sensorReadingSeparator    = new char[] { ',' };
            char[] sensorIdAndValueSeparator = new char[] { ' ' };

            addressBcdText = BitConverter.ToString(e.Address);

            messageBcdText = BitConverter.ToString(e.Data);
            try
            {
                messageText = UTF8Encoding.UTF8.GetString(e.Data);
            }
            catch (Exception)
            {
                this.logging.LogMessage("Failure converting payload to text", LoggingLevel.Error);
                return;
            }

#if DEBUG
            Debug.WriteLine(@"{0:HH:mm:ss}-RX From {1} PacketSnr {2:0.0} Packet RSSI {3}dBm RSSI {4}dBm = {5} byte message ""{6}""", DateTime.Now, addressBcdText, e.PacketSnr, e.PacketRssi, e.Rssi, e.Data.Length, messageText);
#endif
            LoggingFields messagePayload = new LoggingFields();
            messagePayload.AddInt32("AddressLength", e.Address.Length);
            messagePayload.AddString("Address-BCD", addressBcdText);
            messagePayload.AddInt32("Message-Length", e.Data.Length);
            messagePayload.AddString("Message-BCD", messageBcdText);
            messagePayload.AddString("Nessage-Unicode", messageText);
            messagePayload.AddDouble("Packet SNR", e.PacketSnr);
            messagePayload.AddInt32("Packet RSSI", e.PacketRssi);
            messagePayload.AddInt32("RSSI", e.Rssi);
            this.logging.LogEvent("Message Data", messagePayload, LoggingLevel.Verbose);


            // Check the address is not to short/long
            if (e.Address.Length < AddressLengthMinimum)
            {
                this.logging.LogMessage("From address too short", LoggingLevel.Warning);
                return;
            }

            if (e.Address.Length > MessageLengthMaximum)
            {
                this.logging.LogMessage("From address too long", LoggingLevel.Warning);
                return;
            }

            // Check the payload is not too short/long
            if (e.Data.Length < MessageLengthMinimum)
            {
                this.logging.LogMessage("Message too short to contain any data", LoggingLevel.Warning);
                return;
            }

            if (e.Data.Length > MessageLengthMaximum)
            {
                this.logging.LogMessage("Message too long to contain valid data", LoggingLevel.Warning);
                return;
            }

            // Adafruit IO is case sensitive & onlye does lower case ?
            string deviceId = addressBcdText.ToLower();

            // Chop up the CSV text payload
            string[] sensorReadings = messageText.Split(sensorReadingSeparator, StringSplitOptions.RemoveEmptyEntries);
            if (sensorReadings.Length == 0)
            {
                this.logging.LogMessage("Payload contains no sensor readings", LoggingLevel.Warning);
                return;
            }

            Group_feed_data groupFeedData = new Group_feed_data();

            LoggingFields sensorData = new LoggingFields();
            sensorData.AddString("DeviceID", deviceId);

            // Chop up each sensor reading into an ID & value
            foreach (string sensorReading in sensorReadings)
            {
                string[] sensorIdAndValue = sensorReading.Split(sensorIdAndValueSeparator, StringSplitOptions.RemoveEmptyEntries);

                // Check that there is an id & value
                if (sensorIdAndValue.Length != 2)
                {
                    this.logging.LogMessage("Sensor reading invalid format", LoggingLevel.Warning);
                    return;
                }

                string sensorId = sensorIdAndValue[0].ToLower();
                string value    = sensorIdAndValue[1];

                // Construct the sensor ID from SensordeviceID & Value ID
                groupFeedData.Feeds.Add(new Anonymous2()
                {
                    Key = string.Format("{0}{1}", deviceId, sensorId), Value = value
                });

                sensorData.AddString(sensorId, value);

                Debug.WriteLine(" Sensor {0}{1} Value {2}", deviceId, sensorId, value);
            }

            this.logging.LogEvent("Sensor readings", sensorData, LoggingLevel.Verbose);

            try
            {
                Debug.WriteLine(" CreateGroupDataAsync start");
                await this.adaFruitIOClient.CreateGroupDataAsync(this.applicationSettings.AdaFruitIOUserName, this.applicationSettings.AdaFruitIOGroupName.ToLower(), groupFeedData);

                Debug.WriteLine(" CreateGroupDataAsync finish");
            }
            catch (Exception ex)
            {
                Debug.WriteLine(" CreateGroupDataAsync failed {0}", ex.Message);
                this.logging.LogMessage("CreateGroupDataAsync failed " + ex.Message, LoggingLevel.Error);
            }
        }
Ejemplo n.º 13
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            TimeSpan      imageUpdateDue;
            TimeSpan      imageUpdatePeriod;

            this.logging.LogEvent("Application starting");

            // Log the Application build, OS version information etc.
            LoggingFields startupInformation = new LoggingFields();

            startupInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            startupInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            startupInformation.AddString("MachineName", Environment.MachineName);

            // This is from the application manifest
            Package        package   = Package.Current;
            PackageId      packageId = package.Id;
            PackageVersion version   = packageId.Version;

            startupInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));

            try
            {
                // see if the configuration file is present if not copy minimal sample one from application directory
                if (localFolder.TryGetItemAsync(ConfigurationFilename).AsTask().Result == null)
                {
                    StorageFile templateConfigurationfile = Package.Current.InstalledLocation.GetFileAsync(ConfigurationFilename).AsTask().Result;
                    templateConfigurationfile.CopyAsync(localFolder, ConfigurationFilename).AsTask();
                }

                IConfiguration configuration = new ConfigurationBuilder().AddJsonFile(Path.Combine(localFolder.Path, ConfigurationFilename), false, true).Build();

                this.interruptPinNumber = int.Parse(configuration.GetSection("InterruptPinNumber").Value);
                startupInformation.AddInt32("Interrupt pin", this.interruptPinNumber);

                this.interruptTriggerOn = (GpioPinEdge)Enum.Parse(typeof(GpioPinEdge), configuration.GetSection("interruptTriggerOn").Value);
                startupInformation.AddString("Interrupt Trigger on", this.interruptTriggerOn.ToString());

                this.displayPinNumber = int.Parse(configuration.GetSection("DisplayPinNumber").Value);
                startupInformation.AddInt32("Display pin", this.interruptPinNumber);

                this.azureIoTHubConnectionString = configuration.GetSection("AzureIoTHubConnectionString").Value;
                startupInformation.AddString("AzureIoTHubConnectionString", this.azureIoTHubConnectionString);

                this.transportType = (TransportType)Enum.Parse(typeof(TransportType), configuration.GetSection("TransportType").Value);
                startupInformation.AddString("TransportType", this.transportType.ToString());
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load or settings retrieval failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            #region AzureIoT Hub connection string creation
            try
            {
                this.azureIoTHubClient = DeviceClient.CreateFromConnectionString(this.azureIoTHubConnectionString, this.transportType);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("AzureIOT Hub DeviceClient.CreateFromConnectionString failed " + ex.Message, LoggingLevel.Error);
                return;
            }
            #endregion

            #region Report device and application properties to AzureIoT Hub
            try
            {
                TwinCollection reportedProperties = new TwinCollection();

                // This is from the OS
                reportedProperties["Timezone"]    = TimeZoneSettings.CurrentTimeZoneDisplayName;
                reportedProperties["OSVersion"]   = Environment.OSVersion.VersionString;
                reportedProperties["MachineName"] = Environment.MachineName;

                reportedProperties["ApplicationDisplayName"] = package.DisplayName;
                reportedProperties["ApplicationName"]        = packageId.Name;
                reportedProperties["ApplicationVersion"]     = string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}");

                // Unique identifier from the hardware
                SystemIdentificationInfo systemIdentificationInfo = SystemIdentification.GetSystemIdForPublisher();
                using (DataReader reader = DataReader.FromBuffer(systemIdentificationInfo.Id))
                {
                    byte[] bytes = new byte[systemIdentificationInfo.Id.Length];
                    reader.ReadBytes(bytes);
                    reportedProperties["SystemId"] = BitConverter.ToString(bytes);
                }

                this.azureIoTHubClient.UpdateReportedPropertiesAsync(reportedProperties).Wait();
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client UpdateReportedPropertiesAsync failed " + ex.Message, LoggingLevel.Error);
                return;
            }
            #endregion

            #region Retrieve device twin settings
            try
            {
                LoggingFields configurationInformation = new LoggingFields();

                Twin deviceTwin = this.azureIoTHubClient.GetTwinAsync().GetAwaiter().GetResult();

                if (!deviceTwin.Properties.Desired.Contains("ImageUpdateDue") || !TimeSpan.TryParse(deviceTwin.Properties.Desired["ImageUpdateDue"].value.ToString(), out imageUpdateDue))
                {
                    this.logging.LogMessage("DeviceTwin.Properties ImageUpdateDue setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                configurationInformation.AddTimeSpan("ImageUpdateDue", imageUpdateDue);

                if (!deviceTwin.Properties.Desired.Contains("ImageUpdatePeriod") || !TimeSpan.TryParse(deviceTwin.Properties.Desired["ImageUpdatePeriod"].value.ToString(), out imageUpdatePeriod))
                {
                    this.logging.LogMessage("DeviceTwin.Properties ImageUpdatePeriod setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                configurationInformation.AddTimeSpan("ImageUpdatePeriod", imageUpdatePeriod);

                if (!deviceTwin.Properties.Desired.Contains("ModelType") || (!Enum.TryParse(deviceTwin.Properties.Desired["ModelType"].value.ToString(), out modelType)))
                {
                    this.logging.LogMessage("DeviceTwin.Properties ModelType setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                configurationInformation.AddString("ModelType", modelType.ToString());

                if (!deviceTwin.Properties.Desired.Contains("ModelPublishedName") || (string.IsNullOrWhiteSpace(deviceTwin.Properties.Desired["ModelPublishedName"].value.ToString())))
                {
                    this.logging.LogMessage("DeviceTwin.Properties ModelPublishedName setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                modelPublishedName = deviceTwin.Properties.Desired["ModelPublishedName"].value.ToString();
                configurationInformation.AddString("ModelPublishedName", modelPublishedName);

                if (!deviceTwin.Properties.Desired.Contains("ProjectID") || (!Guid.TryParse(deviceTwin.Properties.Desired["ProjectID"].value.ToString(), out projectId)))
                {
                    this.logging.LogMessage("DeviceTwin.Properties ProjectId setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                configurationInformation.AddGuid("ProjectID", projectId);

                if (!deviceTwin.Properties.Desired.Contains("ProbabilityThreshold") || (!Double.TryParse(deviceTwin.Properties.Desired["ProbabilityThreshold"].value.ToString(), out probabilityThreshold)))
                {
                    this.logging.LogMessage("DeviceTwin.Properties ProbabilityThreshold setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                configurationInformation.AddDouble("ProbabilityThreshold", probabilityThreshold);

                if (!deviceTwin.Properties.Desired.Contains("AzureCognitiveServicesEndpoint") || (string.IsNullOrWhiteSpace(deviceTwin.Properties.Desired["AzureCognitiveServicesEndpoint"].value.ToString())))
                {
                    this.logging.LogMessage("DeviceTwin.Properties AzureCognitiveServicesEndpoint setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                azureCognitiveServicesEndpoint = deviceTwin.Properties.Desired["AzureCognitiveServicesEndpoint"].value.ToString();
                configurationInformation.AddString("AzureCognitiveServicesEndpoint", modelPublishedName);

                if (!deviceTwin.Properties.Desired.Contains("AzureCognitiveServicesSubscriptionKey") || (string.IsNullOrWhiteSpace(deviceTwin.Properties.Desired["AzureCognitiveServicesSubscriptionKey"].value.ToString())))
                {
                    this.logging.LogMessage("DeviceTwin.Properties AzureCognitiveServicesSubscriptionKey setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                azureCognitiveServicesSubscriptionKey = deviceTwin.Properties.Desired["AzureCognitiveServicesSubscriptionKey"].value.ToString();
                configurationInformation.AddString("AzureCognitiveServicesSubscriptionKey", azureCognitiveServicesSubscriptionKey);

                if (!deviceTwin.Properties.Desired.Contains("DebounceTimeout") || !TimeSpan.TryParse(deviceTwin.Properties.Desired["DebounceTimeout"].value.ToString(), out debounceTimeout))
                {
                    this.logging.LogMessage("DeviceTwin.Properties DebounceTimeout setting missing or invalid format", LoggingLevel.Warning);
                    return;
                }
                configurationInformation.AddTimeSpan("DebounceTimeout", debounceTimeout);

                this.logging.LogEvent("Configuration settings", configurationInformation);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client GetTwinAsync failed or property missing/invalid" + ex.Message, LoggingLevel.Error);
                return;
            }
            #endregion

            try
            {
                this.customVisionClient = new CustomVisionPredictionClient(new System.Net.Http.DelegatingHandler[] { })
                {
                    ApiKey   = this.azureCognitiveServicesSubscriptionKey,
                    Endpoint = this.azureCognitiveServicesEndpoint,
                };
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure Cognitive Services Custom Vision Client configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                this.mediaCapture = new MediaCapture();
                this.mediaCapture.InitializeAsync().AsTask().Wait();
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            this.displayOffTimer = new Timer(this.TimerCallback, null, Timeout.Infinite, Timeout.Infinite);

            #region Wire up interupt handler for image capture request
            if (this.interruptPinNumber != 0)
            {
                try
                {
                    GpioController gpioController = GpioController.GetDefault();
                    this.interruptGpioPin = gpioController.OpenPin(this.interruptPinNumber);
                    this.interruptGpioPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
                    this.interruptGpioPin.ValueChanged += this.InterruptGpioPin_ValueChanged;

                    this.displayGpioPin = gpioController.OpenPin(this.displayPinNumber);
                    this.displayGpioPin.SetDriveMode(GpioPinDriveMode.Output);
                    this.displayGpioPin.Write(GpioPinValue.Low);
                }
                catch (Exception ex)
                {
                    this.logging.LogMessage("Digital input configuration failed " + ex.Message, LoggingLevel.Error);
                    return;
                }
            }
            #endregion

            #region Wire up command handler for image capture request
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("ImageCapture", this.ImageUpdateHandler, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client ImageCapture SetMethodHandlerAsync failed " + ex.Message, LoggingLevel.Error);
                return;
            }
            #endregion

            #region Wire up command handler for device reboot request
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("DeviceReboot", this.DeviceRebootAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client DeviceReboot SetMethodHandlerAsync failed " + ex.Message, LoggingLevel.Error);
                return;
            }
            #endregion

            if ((imageUpdateDue != TimeSpan.MinValue) || (imageUpdatePeriod != TimeSpan.MinValue))
            {
                this.imageUpdatetimer = new Timer(this.ImageUpdateTimerCallback, null, imageUpdateDue, imageUpdatePeriod);
            }

            this.logging.LogEvent("Application started", startupInformation);

            // enable task to continue running in background
            this.backgroundTaskDeferral = taskInstance.GetDeferral();
        }
Ejemplo n.º 14
0
        private async Task ImageUpdate(bool isCommand)
        {
            DateTime currentTime = DateTime.UtcNow;

            // Just incase - stop code being called while photo already in progress
            if (this.cameraBusy)
            {
                return;
            }
            this.cameraBusy = true;
            this.displayGpioPin.Write(GpioPinValue.High);

            // Check that enough time has passed for picture to be taken
            if ((currentTime - this.imageLastCapturedAtUtc) < this.debounceTimeout)
            {
                this.displayOffTimer.Change(this.timerPeriodDetectIlluminated, this.timerPeriodInfinite);
                return;
            }

            this.imageLastCapturedAtUtc = currentTime;

            try
            {
                ImagePrediction imagePrediction;

                using (Windows.Storage.Streams.InMemoryRandomAccessStream captureStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
                {
                    this.mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), captureStream).AsTask().Wait();
                    captureStream.FlushAsync().AsTask().Wait();
                    captureStream.Seek(0);

                    IStorageFile photoFile = await KnownFolders.PicturesLibrary.CreateFileAsync(ImageFilename, CreationCollisionOption.ReplaceExisting);

                    ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
                    await this.mediaCapture.CapturePhotoToStorageFileAsync(imageProperties, photoFile);

                    switch (modelType)
                    {
                    case ModelType.Classification:
                        imagePrediction = await this.customVisionClient.ClassifyImageAsync(this.projectId, this.modelPublishedName, captureStream.AsStreamForRead());

                        break;

                    case ModelType.Detection:
                        imagePrediction = await this.customVisionClient.DetectImageAsync(this.projectId, this.modelPublishedName, captureStream.AsStreamForRead());

                        break;

                    default:
                        throw new ArgumentException("ModelType Invalid");
                    }
                    Debug.WriteLine($"Prediction count {imagePrediction.Predictions.Count}");
                }

                JObject       telemetryDataPoint = new JObject();
                LoggingFields imageInformation   = new LoggingFields();

                imageInformation.AddDateTime("TakenAtUTC", currentTime);
                imageInformation.AddBoolean("IsCommand", isCommand);
                imageInformation.AddDouble("Probability threshold", probabilityThreshold);
                imageInformation.AddInt32("Predictions", imagePrediction.Predictions.Count);

                // Display and log the results of the prediction
                foreach (var prediction in imagePrediction.Predictions)
                {
                    Debug.WriteLine($" Tag:{prediction.TagName} {prediction.Probability}");
                    imageInformation.AddDouble($"Tag:{prediction.TagName}", prediction.Probability);
                }

                // Post process the predictions based on the type of model
                switch (modelType)
                {
                case ModelType.Classification:
                    // Use only the tags above the specified minimum probability
                    foreach (var prediction in imagePrediction.Predictions)
                    {
                        if (prediction.Probability >= probabilityThreshold)
                        {
                            // Display and log the individual tag probabilities
                            Debug.WriteLine($" Tag valid:{prediction.TagName} {prediction.Probability:0.00}");
                            imageInformation.AddDouble($"Tag valid:{prediction.TagName}", prediction.Probability);

                            telemetryDataPoint.Add(prediction.TagName, prediction.Probability);
                        }
                    }
                    break;

                case ModelType.Detection:
                    // Group the tags to get the count, include only the predictions above the specified minimum probability
                    var groupedPredictions = from prediction in imagePrediction.Predictions
                                             where prediction.Probability >= probabilityThreshold
                                             group prediction by new { prediction.TagName }
                    into newGroup
                        select new
                    {
                        TagName = newGroup.Key.TagName,
                        Count   = newGroup.Count(),
                    };

                    // Display and log the agregated predictions
                    foreach (var prediction in groupedPredictions)
                    {
                        Debug.WriteLine($" Tag valid:{prediction.TagName} {prediction.Count}");
                        imageInformation.AddInt32($"Tag valid:{prediction.TagName}", prediction.Count);
                        telemetryDataPoint.Add(prediction.TagName, prediction.Count);
                    }
                    break;

                default:
                    throw new ArgumentException("ModelType Invalid");
                }

                this.logging.LogEvent("Captured image processed by Cognitive Services", imageInformation);

                try
                {
                    using (Message message = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(telemetryDataPoint))))
                    {
                        Debug.WriteLine(" {0:HH:mm:ss} AzureIoTHubClient SendEventAsync start", DateTime.UtcNow);
                        await this.azureIoTHubClient.SendEventAsync(message);

                        Debug.WriteLine(" {0:HH:mm:ss} AzureIoTHubClient SendEventAsync finish", DateTime.UtcNow);
                    }
                    this.logging.LogEvent("SendEventAsync payload", imageInformation, LoggingLevel.Information);
                }
                catch (Exception ex)
                {
                    imageInformation.AddString("Exception", ex.ToString());
                    this.logging.LogEvent("SendEventAsync payload", imageInformation, LoggingLevel.Error);
                }
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera photo or save failed " + ex.Message, LoggingLevel.Error);
            }
            finally
            {
                this.displayGpioPin.Write(GpioPinValue.Low);
                this.cameraBusy = false;
            }
        }
Ejemplo n.º 15
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            int           imageUpdateDueSeconds;
            int           imageUpdatePeriodSeconds;

            this.logging.LogEvent("Application starting");

            // Log the Application build, OS version information etc.
            LoggingFields startupInformation = new LoggingFields();

            startupInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            startupInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            startupInformation.AddString("MachineName", Environment.MachineName);

            // This is from the application manifest
            Package        package   = Package.Current;
            PackageId      packageId = package.Id;
            PackageVersion version   = packageId.Version;

            startupInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));

            try
            {
                // see if the configuration file is present if not copy minimal sample one from application directory
                if (localFolder.TryGetItemAsync(ConfigurationFilename).AsTask().Result == null)
                {
                    StorageFile templateConfigurationfile = Package.Current.InstalledLocation.GetFileAsync(ConfigurationFilename).AsTask().Result;
                    templateConfigurationfile.CopyAsync(localFolder, ConfigurationFilename).AsTask();

                    this.logging.LogMessage("JSON configuration file missing, templated created", LoggingLevel.Warning);
                    return;
                }

                IConfiguration configuration = new ConfigurationBuilder().AddJsonFile(Path.Combine(localFolder.Path, ConfigurationFilename), false, true).Build();

                localImageFilenameLatestFormat = configuration.GetSection("ImageFilenameFormatLatest").Value;
                startupInformation.AddString("ImageFilenameLatestFormat", localImageFilenameLatestFormat);

                localFolderNameHistoryFormat = configuration.GetSection("FolderNameFormatHistory").Value;
                startupInformation.AddString("ContainerNameHistoryFormat", localFolderNameHistoryFormat);

                localImageFilenameHistoryFormat = configuration.GetSection("ImageFilenameFormatHistory").Value;
                startupInformation.AddString("ImageFilenameHistoryFormat", localImageFilenameHistoryFormat);

                imageUpdateDueSeconds = int.Parse(configuration.GetSection("ImageUpdateDueSeconds").Value);
                startupInformation.AddInt32("ImageUpdateDueSeconds", imageUpdateDueSeconds);

                imageUpdatePeriodSeconds = int.Parse(configuration.GetSection("ImageUpdatePeriodSeconds").Value);
                startupInformation.AddInt32("ImageUpdatePeriodSeconds", imageUpdatePeriodSeconds);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load or settings retrieval failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                mediaCapture = new MediaCapture();
                mediaCapture.InitializeAsync().AsTask().Wait();
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            ImageUpdatetimer = new Timer(ImageUpdateTimerCallback, null, new TimeSpan(0, 0, imageUpdateDueSeconds), new TimeSpan(0, 0, imageUpdatePeriodSeconds));

            this.logging.LogEvent("Application started", startupInformation);

            //enable task to continue running in background
            backgroundTaskDeferral = taskInstance.GetDeferral();
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Asynchronously attempts to unlock the document file.
        /// </summary>
        /// <remarks>
        /// Algorithm is as of this writing (11/5/2012):
        /// 0. Use UTF8 encoding with no BOM.
        /// 1. Read header.
        /// 2. Compute SHA256 hash of header.
        /// 3. Decrypt the rest of the viewModel using header parameters.
        ///     Relies on:
        ///         a. MasterSeed.Length == 32
        ///             Write masterseed to stream
        ///         b. GenerateKey32(_transformSeed, KeyEncryptionRounds)
        ///             Create raw32 (CreateRawCompositeKey32)
        ///                 Concatenate all data and Sha256
        ///             TransformKey(raw32, _transformSeed, numRounds)
        ///                 Init Rijndael:
        ///                     128 bit (16 byte) blocks
        ///                     ECB mode
        ///                     k = _transformSeed
        ///                     For numRounds:
        ///                         Transform in place raw32[0:15]
        ///                         Transform in place raw32[16:31]
        ///         c. Write 32 bytes of Key32 to stream
        ///         d. aesKey = Sha256 the stream
        ///         e. DecryptStream with aesKey and _encryptionIV
        /// 4. Verify the first 32 bytes of the decrypted viewModel match up with
        ///     "StreamStartBytes" from the header.
        /// 5. Read from the decrypted viewModel as a "HashedBlockStream"
        ///
        /// File format at the time of this writing (11/5/2012):
        ///
        /// 4 bytes: SIG1
        /// 4 bytes: SIG2
        /// Failure to match these constants results in a parse Result.
        ///
        /// 4 bytes: File version
        ///
        /// Header fields:
        /// 1 byte: Field ID
        /// 2 bytes: Field size (n)
        /// n bytes: Data
        /// </remarks>
        /// <param name="stream">An IRandomAccessStream containing the document to unlock (including the header).</param>
        /// <param name="rawKey">The aggregate raw key to use for decrypting the database.</param>
        /// <param name="token">A token allowing the parse to be cancelled.</param>
        /// <returns>A Task representing the result of the descryiption operation.</returns>
        public async Task <KdbxDecryptionResult> DecryptFile(IRandomAccessStream stream, IBuffer rawKey, CancellationToken token)
        {
            if (HeaderData == null)
            {
                throw new InvalidOperationException("Cannot decrypt database before ReadHeader has been called.");
            }

            // Init a SHA256 hash buffer and append the master seed to it
            HashAlgorithmProvider sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
            CryptographicHash     hash   = sha256.CreateHash();

            hash.Append(HeaderData.MasterSeed);

            this.rawKey = rawKey;
            this.logger.LogEvent("KdbxReader.GotRawKey", EventVerbosity.Verbose);

            // Transform the key (this can take a while)
            IBuffer transformedKey;

            try
            {
                IKdfEngine kdf = HeaderData.KdfParameters.CreateEngine();

                LoggingFields fields = new LoggingFields();
                fields.AddString("KdfEngine", kdf.GetType().Name);
                this.logger.LogEvent("KdbxReader.StartingKeyTransform", fields, EventVerbosity.Info);

                transformedKey = await HeaderData.KdfParameters.CreateEngine().TransformKeyAsync(rawKey, token)
                                 .ConfigureAwait(false);

                if (transformedKey == null)
                {
                    throw new OperationCanceledException();
                }

                this.logger.LogEvent("KdbxReader.KeyTransformSucceeded", EventVerbosity.Info);
            }
            catch (OperationCanceledException)
            {
                return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.OperationCancelled)));
            }

            // In KDBX4, after the header is an HMAC-SHA-256 value computed over the header
            // allowing validation of header integrity.
            IBuffer          hmacKey     = HmacBlockHandler.DeriveHmacKey(transformedKey, HeaderData.MasterSeed);
            HmacBlockHandler hmacHandler = new HmacBlockHandler(hmacKey);

            IBuffer expectedMac = null;

            if (this.parameters.UseInlineHeaderAuthentication)
            {
                var algorithm = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
                CryptographicHash hmacHash = algorithm.CreateHash(hmacHandler.GetKeyForBlock(UInt64.MaxValue));

                DebugHelper.Assert(HeaderData.FullHeader != null);
                hmacHash.Append(HeaderData.FullHeader);

                expectedMac = hmacHash.GetValueAndReset();
            }

            // Hash transformed k (with the master seed) to get final cipher k
            hash.Append(transformedKey);
            IBuffer cipherKey = hash.GetValueAndReset();

            this.logger.LogEvent("KdbxReader.GotFinalCipherKey", EventVerbosity.Info);

            // Decrypt the document starting from the end of the header
            ulong headerLength = HeaderData.FullHeader.Length;

            if (this.parameters.UseInlineHeaderAuthentication)
            {
                // KDBX4 has a hash at the end of the header
                headerLength += 32;
            }

            stream.Seek(headerLength);
            if (expectedMac != null)
            {
                using (DataReader macReader = GetReaderForStream(stream))
                {
                    await macReader.LoadAsync(expectedMac.Length);

                    IBuffer actualMac = macReader.ReadBuffer(expectedMac.Length);

                    for (uint i = 0; i < expectedMac.Length; i++)
                    {
                        if (expectedMac.GetByte(i) != actualMac.GetByte(i))
                        {
                            this.logger.LogEvent("KdbxReader.HmacFailure", EventVerbosity.Critical);
                            return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.CouldNotDecrypt)));
                        }
                    }

                    macReader.DetachStream();
                }
            }

            IBuffer cipherText;

            try
            {
                cipherText = await GetCipherText(stream, hmacHandler);
            }
            catch (FormatException ex)
            {
                this.logger.LogEvent("KdbxReader.DataIntegrityFailure", ex.ToLoggingFields(), EventVerbosity.Critical);
                return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.DataIntegrityProblem, ex)));
            }

            IBuffer decryptedFile = DecryptDatabaseData(cipherText, cipherKey);

            if (decryptedFile == null)
            {
                this.logger.LogEvent("KdbxReader.DecryptionFailure", EventVerbosity.Critical);
                return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.CouldNotDecrypt)));
            }

            this.logger.LogEvent("KdbxReader.DecryptionSucceeded", EventVerbosity.Info);

            // Verify first 32 bytes of the clear data; if StreamStartBytes wasn't set
            // (e.g. due to KDBX4), nothing happens here.
            for (uint i = 0; i < (HeaderData.StreamStartBytes?.Length ?? 0); i++)
            {
                byte actualByte   = decryptedFile.GetByte(i);
                byte expectedByte = HeaderData.StreamStartBytes.GetByte(i);

                if (actualByte != expectedByte)
                {
                    this.logger.LogEvent("KdbxReader.PlaintextValidationFailure", EventVerbosity.Critical);
                    return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.FirstBytesMismatch)));
                }
            }

            this.logger.LogEvent("KdbxReader.PlaintextValidationSucceeded", EventVerbosity.Verbose);

            IBuffer plainText = await UnhashAndInflate(decryptedFile);

            if (plainText == null)
            {
                return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.CouldNotInflate)));
            }

            // Update HeaderData with info from the inner header, if relevant
            if (this.parameters.UseInnerHeader)
            {
                using (IRandomAccessStream plainTextStream = plainText.AsStream().AsRandomAccessStream())
                {
                    using (DataReader reader = GetReaderForStream(plainTextStream))
                    {
                        ReaderResult innerHeaderResult = await ReadInnerHeader(reader, HeaderData);

                        if (innerHeaderResult != ReaderResult.Success)
                        {
                            LoggingFields fields = new LoggingFields();
                            fields.AddInt32("Code", (int)innerHeaderResult.Code);
                            this.logger.LogEvent("KdbxReader.InnerHeaderReadFailure", fields, EventVerbosity.Critical);
                            return(new KdbxDecryptionResult(innerHeaderResult));
                        }

                        // Update plainText to point to the remainder of the buffer
                        uint bytesRemaining = plainText.Length - (uint)plainTextStream.Position;
                        await reader.LoadAsync(bytesRemaining);

                        plainText = reader.ReadBuffer(bytesRemaining);
                    }
                }
            }

            XDocument finalTree = null;

            try
            {
                finalTree = XDocument.Load(plainText.AsStream());
            }
            catch (XmlException)
            {
                return(null);
            }

            if (finalTree == null)
            {
                return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.MalformedXml)));
            }

            try
            {
                KdbxDocument parsedDocument = await Task.Run(() => new KdbxDocument(finalTree.Root, HeaderData.ProtectedBinaries, HeaderData.GenerateRng(), this.parameters));

                // Validate the final parsed header hash before returning
                if (this.parameters.UseXmlHeaderAuthentication &&
                    !String.IsNullOrEmpty(parsedDocument.Metadata.HeaderHash) &&
                    parsedDocument.Metadata.HeaderHash != HeaderData.HeaderHash)
                {
                    return(new KdbxDecryptionResult(new ReaderResult(KdbxParserCode.BadHeaderHash)));
                }

                return(new KdbxDecryptionResult(this.parameters, parsedDocument, this.rawKey));
            }
            catch (KdbxParseException e)
            {
                return(new KdbxDecryptionResult(e.Error));
            }
        }
Ejemplo n.º 17
0
        private async void InterruptGpioPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args)
        {
            DateTime currentTime = DateTime.UtcNow;

            Debug.WriteLine($"Digital Input Interrupt {sender.PinNumber} triggered {args.Edge}");

            if (args.Edge != this.interruptTriggerOn)
            {
                return;
            }

            // Check that enough time has passed for picture to be taken
            if ((currentTime - this.imageLastCapturedAtUtc) < this.debounceTimeout)
            {
                this.displayGpioPin.Write(GpioPinValue.High);
                this.displayOffTimer.Change(this.timerPeriodDetectIlluminated, this.timerPeriodInfinite);
                return;
            }

            this.imageLastCapturedAtUtc = currentTime;

            // Just incase - stop code being called while photo already in progress
            if (this.cameraBusy)
            {
                this.displayGpioPin.Write(GpioPinValue.High);
                this.displayOffTimer.Change(this.timerPeriodDetectIlluminated, this.timerPeriodInfinite);
                return;
            }

            this.cameraBusy = true;

            try
            {
                using (Windows.Storage.Streams.InMemoryRandomAccessStream captureStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
                {
                    this.mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), captureStream).AsTask().Wait();
                    captureStream.FlushAsync().AsTask().Wait();
                    captureStream.Seek(0);

                    IStorageFile photoFile = await KnownFolders.PicturesLibrary.CreateFileAsync(ImageFilename, CreationCollisionOption.ReplaceExisting);

                    ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
                    await this.mediaCapture.CapturePhotoToStorageFileAsync(imageProperties, photoFile);

                    ImagePrediction imagePrediction = await this.customVisionClient.ClassifyImageAsync(this.projectId, this.publishedName, captureStream.AsStreamForRead());

                    Debug.WriteLine($"Prediction count {imagePrediction.Predictions.Count}");

                    LoggingFields imageInformation = new LoggingFields();

                    imageInformation.AddDateTime("TakenAtUTC", currentTime);
                    imageInformation.AddInt32("Pin", sender.PinNumber);
                    imageInformation.AddInt32("Predictions", imagePrediction.Predictions.Count);

                    foreach (var prediction in imagePrediction.Predictions)
                    {
                        Debug.WriteLine($" Tag:{prediction.TagName} {prediction.Probability}");
                        imageInformation.AddDouble($"Tag:{prediction.TagName}", prediction.Probability);
                    }

                    this.logging.LogEvent("Captured image processed by Cognitive Services", imageInformation);
                }
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera photo or save failed " + ex.Message, LoggingLevel.Error);
            }
            finally
            {
                this.cameraBusy = false;
            }
        }
Ejemplo n.º 18
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            this.logging.LogEvent("Application starting");

            // Log the Application build, OS version information etc.
            LoggingFields startupInformation = new LoggingFields();

            startupInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            startupInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            startupInformation.AddString("MachineName", Environment.MachineName);

            // This is from the application manifest
            Package        package   = Package.Current;
            PackageId      packageId = package.Id;
            PackageVersion version   = packageId.Version;

            startupInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));

            try
            {
                // see if the configuration file is present if not copy minimal sample one from application directory
                if (localFolder.TryGetItemAsync(ConfigurationFilename).AsTask().Result == null)
                {
                    StorageFile templateConfigurationfile = Package.Current.InstalledLocation.GetFileAsync(ConfigurationFilename).AsTask().Result;
                    templateConfigurationfile.CopyAsync(localFolder, ConfigurationFilename).AsTask();
                }

                IConfiguration configuration = new ConfigurationBuilder().AddJsonFile(Path.Combine(localFolder.Path, ConfigurationFilename), false, true).Build();

                this.azureCognitiveServicesEndpoint = configuration.GetSection("AzureCognitiveServicesEndpoint").Value;
                startupInformation.AddString("AzureCognitiveServicesEndpoint", this.azureCognitiveServicesEndpoint);

                this.azureCognitiveServicesSubscriptionKey = configuration.GetSection("AzureCognitiveServicesSubscriptionKey").Value;
                startupInformation.AddString("AzureCognitiveServicesSubscriptionKey", this.azureCognitiveServicesSubscriptionKey);

                this.interruptPinNumber = int.Parse(configuration.GetSection("InterruptPinNumber").Value);
                startupInformation.AddInt32("Interrupt pin", this.interruptPinNumber);

                this.interruptTriggerOn = (GpioPinEdge)Enum.Parse(typeof(GpioPinEdge), configuration.GetSection("interruptTriggerOn").Value);
                startupInformation.AddString("Interrupt Trigger on", this.interruptTriggerOn.ToString());

                this.displayPinNumber = int.Parse(configuration.GetSection("DisplayPinNumber").Value);
                startupInformation.AddInt32("Display pin", this.interruptPinNumber);

                this.debounceTimeout = TimeSpan.Parse(configuration.GetSection("debounceTimeout").Value);
                startupInformation.AddTimeSpan("Debounce timeout", this.debounceTimeout);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load or settings retrieval failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                this.faceClient = new FaceClient(
                    new Microsoft.Azure.CognitiveServices.Vision.Face.ApiKeyServiceClientCredentials(this.azureCognitiveServicesSubscriptionKey),
                    new System.Net.Http.DelegatingHandler[] { })
                {
                    Endpoint = this.azureCognitiveServicesEndpoint,
                };
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure Cognitive Services Face Client configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                this.mediaCapture = new MediaCapture();
                this.mediaCapture.InitializeAsync().AsTask().Wait();
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            this.displayOffTimer = new Timer(this.TimerCallback, null, Timeout.Infinite, Timeout.Infinite);

            try
            {
                GpioController gpioController = GpioController.GetDefault();
                this.interruptGpioPin = gpioController.OpenPin(this.interruptPinNumber);
                this.interruptGpioPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
                this.interruptGpioPin.ValueChanged += this.InterruptGpioPin_ValueChanged;

                this.displayGpioPin = gpioController.OpenPin(this.displayPinNumber);
                this.displayGpioPin.SetDriveMode(GpioPinDriveMode.Output);
                this.displayGpioPin.Write(GpioPinValue.Low);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Digital input configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            this.logging.LogEvent("Application started", startupInformation);

            // enable task to continue running in background
            this.backgroundTaskDeferral = taskInstance.GetDeferral();
        }
Ejemplo n.º 19
0
        private async void InterruptGpioPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args)
        {
            DateTime currentTime = DateTime.UtcNow;

            Debug.WriteLine($"Digital Input Interrupt {sender.PinNumber} triggered {args.Edge}");

            if (args.Edge != this.interruptTriggerOn)
            {
                return;
            }

            // Check that enough time has passed for picture to be taken
            if ((currentTime - this.imageLastCapturedAtUtc) < this.debounceTimeout)
            {
                this.displayGpioPin.Write(GpioPinValue.High);
                this.displayOffTimer.Change(this.timerPeriodDetectIlluminated, this.timerPeriodInfinite);
                return;
            }

            this.imageLastCapturedAtUtc = currentTime;

            // Just incase - stop code being called while photo already in progress
            if (this.cameraBusy)
            {
                this.displayGpioPin.Write(GpioPinValue.High);
                this.displayOffTimer.Change(this.timerPeriodDetectIlluminated, this.timerPeriodInfinite);
                return;
            }

            this.cameraBusy = true;

            try
            {
                using (Windows.Storage.Streams.InMemoryRandomAccessStream captureStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
                {
                    this.mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), captureStream).AsTask().Wait();
                    captureStream.FlushAsync().AsTask().Wait();
                    captureStream.Seek(0);

                    IStorageFile photoFile = await KnownFolders.PicturesLibrary.CreateFileAsync(ImageFilename, CreationCollisionOption.ReplaceExisting);

                    ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
                    await this.mediaCapture.CapturePhotoToStorageFileAsync(imageProperties, photoFile);

                    IList <FaceAttributeType> returnfaceAttributes = new List <FaceAttributeType>();

                    returnfaceAttributes.Add(FaceAttributeType.Gender);
                    returnfaceAttributes.Add(FaceAttributeType.Age);

                    IList <DetectedFace> detectedFaces = await this.faceClient.Face.DetectWithStreamAsync(captureStream.AsStreamForRead(), returnFaceAttributes : returnfaceAttributes);

                    Debug.WriteLine($"Count {detectedFaces.Count}");

                    if (detectedFaces.Count > 0)
                    {
                        this.displayGpioPin.Write(GpioPinValue.High);

                        // Start the timer to turn the LED off
                        this.displayOffTimer.Change(this.timerPeriodFaceIlluminated, this.timerPeriodInfinite);
                    }

                    LoggingFields imageInformation = new LoggingFields();

                    imageInformation.AddDateTime("TakenAtUTC", currentTime);
                    imageInformation.AddInt32("Pin", sender.PinNumber);
                    imageInformation.AddInt32("Faces", detectedFaces.Count);
                    foreach (DetectedFace detectedFace in detectedFaces)
                    {
                        Debug.WriteLine("Face");
                        if (detectedFace.FaceId.HasValue)
                        {
                            imageInformation.AddGuid("FaceId", detectedFace.FaceId.Value);
                            Debug.WriteLine($" Id:{detectedFace.FaceId.Value}");
                        }

                        imageInformation.AddInt32("Left", detectedFace.FaceRectangle.Left);
                        imageInformation.AddInt32("Width", detectedFace.FaceRectangle.Width);
                        imageInformation.AddInt32("Top", detectedFace.FaceRectangle.Top);
                        imageInformation.AddInt32("Height", detectedFace.FaceRectangle.Height);
                        Debug.WriteLine($" L:{detectedFace.FaceRectangle.Left} W:{detectedFace.FaceRectangle.Width} T:{detectedFace.FaceRectangle.Top} H:{detectedFace.FaceRectangle.Height}");
                        if (detectedFace.FaceAttributes != null)
                        {
                            if (detectedFace.FaceAttributes.Gender.HasValue)
                            {
                                imageInformation.AddString("Gender", detectedFace.FaceAttributes.Gender.Value.ToString());
                                Debug.WriteLine($" Gender:{detectedFace.FaceAttributes.Gender.ToString()}");
                            }

                            if (detectedFace.FaceAttributes.Age.HasValue)
                            {
                                imageInformation.AddDouble("Age", detectedFace.FaceAttributes.Age.Value);
                                Debug.WriteLine($" Age:{detectedFace.FaceAttributes.Age.Value.ToString("F1")}");
                            }
                        }
                    }

                    this.logging.LogEvent("Captured image processed by Cognitive Services", imageInformation);
                }
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera photo or save failed " + ex.Message, LoggingLevel.Error);
            }
            finally
            {
                this.cameraBusy = false;
            }
        }
Ejemplo n.º 20
0
        private async Task PayloadCommaSeparatedValues(DeviceClient azureIoTHubClient, Rfm9XDevice.OnDataReceivedEventArgs e)
        {
            JObject       telemetryDataPoint   = new JObject();
            LoggingFields processLoggingFields = new LoggingFields();

            char[] sensorReadingSeparators    = { ',' };
            char[] sensorIdAndValueSeparators = { ' ' };

            processLoggingFields.AddString("PacketSNR", e.PacketSnr.ToString("F1"));
            telemetryDataPoint.Add("PacketSNR", e.PacketSnr.ToString("F1"));
            processLoggingFields.AddInt32("PacketRSSI", e.PacketRssi);
            telemetryDataPoint.Add("PacketRSSI", e.PacketRssi);
            processLoggingFields.AddInt32("RSSI", e.Rssi);
            telemetryDataPoint.Add("RSSI", e.Rssi);

            string addressBcdText = BitConverter.ToString(e.Address);

            processLoggingFields.AddInt32("DeviceAddressLength", e.Address.Length);
            processLoggingFields.AddString("DeviceAddressBCD", addressBcdText);
            telemetryDataPoint.Add("DeviceAddressBCD", addressBcdText);

            string messageText;

            try
            {
                messageText = UTF8Encoding.UTF8.GetString(e.Data);
                processLoggingFields.AddString("MessageText", messageText);
            }
            catch (Exception)
            {
                this.logging.LogEvent("PayloadProcess failure converting payload to text", processLoggingFields, LoggingLevel.Warning);
                return;
            }

            // Chop up the CSV text
            string[] sensorReadings = messageText.Split(sensorReadingSeparators, StringSplitOptions.RemoveEmptyEntries);
            if (sensorReadings.Length < 1)
            {
                this.logging.LogEvent("PayloadProcess payload contains no sensor readings", processLoggingFields, LoggingLevel.Warning);
                return;
            }

            // Chop up each sensor read into an ID & value
            foreach (string sensorReading in sensorReadings)
            {
                string[] sensorIdAndValue = sensorReading.Split(sensorIdAndValueSeparators, StringSplitOptions.RemoveEmptyEntries);

                // Check that there is an id & value
                if (sensorIdAndValue.Length != 2)
                {
                    this.logging.LogEvent("PayloadProcess payload invalid format", processLoggingFields, LoggingLevel.Warning);
                    return;
                }

                string sensorId = sensorIdAndValue[0].ToLower();
                string value    = sensorIdAndValue[1];

                // Construct the sensor ID from SensordeviceID & Value, mainly intended for Azure IOT Central support
                if (this.applicationSettings.SensorIDIsDeviceIDSensorID)
                {
                    sensorId = string.Concat(addressBcdText, sensorId);
                }

                try
                {
                    telemetryDataPoint.Add(sensorId, value);
                    processLoggingFields.AddString(sensorId, value);
                    Debug.WriteLine($" SensorID {sensorId} Value {value}");
                }
                catch (Exception ex)
                {
                    processLoggingFields.AddString("Exception", ex.ToString());
                    this.logging.LogEvent("PayloadProcess sensor reading invalid JSON format", processLoggingFields, LoggingLevel.Warning);
                    return;
                }
            }

            try
            {
                using (Message message = new Message(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(telemetryDataPoint))))
                {
                    Debug.WriteLine(" {0:HH:mm:ss} AzureIoTHubClient SendEventAsync start", DateTime.UtcNow);
                    await this.azureIoTHubClient.SendEventAsync(message);

                    Debug.WriteLine(" {0:HH:mm:ss} AzureIoTHubClient SendEventAsync finish", DateTime.UtcNow);
                }
                this.logging.LogEvent("SendEventAsync JSON payload", processLoggingFields, LoggingLevel.Information);
            }
            catch (Exception ex)
            {
                processLoggingFields.AddString("Exception", ex.ToString());
                this.logging.LogEvent("SendEventAsync JSON payload", processLoggingFields, LoggingLevel.Error);
            }
        }
Ejemplo n.º 21
0
        async void IMessageHandler.Rfm9XOnReceive(Rfm9XDevice.OnDataReceivedEventArgs e)
        {
            LoggingFields processReceiveLoggingFields = new LoggingFields();

            char[] sensorReadingSeparators    = { ',' };
            char[] sensorIdAndValueSeparators = { ' ' };

            processReceiveLoggingFields.AddString("PacketSNR", e.PacketSnr.ToString("F1"));
            processReceiveLoggingFields.AddInt32("PacketRSSI", e.PacketRssi);
            processReceiveLoggingFields.AddInt32("RSSI", e.Rssi);

            string addressBcdText = BitConverter.ToString(e.Address);

            processReceiveLoggingFields.AddInt32("DeviceAddressLength", e.Address.Length);
            processReceiveLoggingFields.AddString("DeviceAddressBCD", addressBcdText);

            string messageText;

            try
            {
                messageText = UTF8Encoding.UTF8.GetString(e.Data);
                processReceiveLoggingFields.AddString("MessageText", messageText);
            }
            catch (Exception ex)
            {
                processReceiveLoggingFields.AddString("Exception", ex.ToString());
                this.Logging.LogEvent("PayloadProcess failure converting payload to text", processReceiveLoggingFields, LoggingLevel.Warning);
                return;
            }

            // Chop up the CSV text
            string[] sensorReadings = messageText.Split(sensorReadingSeparators, StringSplitOptions.RemoveEmptyEntries);
            if (sensorReadings.Length < 1)
            {
                this.Logging.LogEvent("PayloadProcess payload contains no sensor readings", processReceiveLoggingFields, LoggingLevel.Warning);
                return;
            }

            JObject payloadJObject = new JObject();

            JObject feeds = new JObject();

            // Chop up each sensor read into an ID & value
            foreach (string sensorReading in sensorReadings)
            {
                string[] sensorIdAndValue = sensorReading.Split(sensorIdAndValueSeparators, StringSplitOptions.RemoveEmptyEntries);

                // Check that there is an id & value
                if (sensorIdAndValue.Length != 2)
                {
                    this.Logging.LogEvent("PayloadProcess payload invalid format", processReceiveLoggingFields, LoggingLevel.Warning);
                    return;
                }

                string sensorId = string.Concat(addressBcdText, sensorIdAndValue[0]);
                string value    = sensorIdAndValue[1];

                feeds.Add(sensorId.ToLower(), value);
            }
            payloadJObject.Add("feeds", feeds);

            string topic = $"{MqttClient.Options.Credentials.Username}/groups/{PlatformSpecificConfiguration}";

            try
            {
                var message = new MqttApplicationMessageBuilder()
                              .WithTopic(topic)
                              .WithPayload(JsonConvert.SerializeObject(payloadJObject))
                              .WithAtLeastOnceQoS()
                              .Build();
                Debug.WriteLine(" {0:HH:mm:ss} MQTT Client PublishAsync start", DateTime.UtcNow);
                await MqttClient.PublishAsync(message);

                Debug.WriteLine(" {0:HH:mm:ss} MQTT Client PublishAsync finish", DateTime.UtcNow);

                this.Logging.LogEvent("PublishAsync Adafruit payload", processReceiveLoggingFields, LoggingLevel.Information);
            }
            catch (Exception ex)
            {
                processReceiveLoggingFields.AddString("Exception", ex.ToString());
                this.Logging.LogEvent("PublishAsync Adafruit payload", processReceiveLoggingFields, LoggingLevel.Error);
            }
        }
Ejemplo n.º 22
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            this.logging.LogEvent("Application starting");

            // Log the Application build, OS version information etc.
            LoggingFields startupInformation = new LoggingFields();

            startupInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            startupInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            startupInformation.AddString("MachineName", Environment.MachineName);

            // This is from the application manifest
            Package        package   = Package.Current;
            PackageId      packageId = package.Id;
            PackageVersion version   = packageId.Version;

            startupInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));

            // ethernet mac address
            this.deviceMacAddress = NetworkInterface.GetAllNetworkInterfaces()
                                    .Where(i => i.NetworkInterfaceType.ToString().ToLower().Contains("ethernet"))
                                    .FirstOrDefault()
                                    ?.GetPhysicalAddress().ToString();

            // remove unsupported charachers from MacAddress
            this.deviceMacAddress = this.deviceMacAddress.Replace("-", string.Empty).Replace(" ", string.Empty).Replace(":", string.Empty);
            startupInformation.AddString("MacAddress", this.deviceMacAddress);

            try
            {
                // see if the configuration file is present if not copy minimal sample one from application directory
                if (localFolder.TryGetItemAsync(ConfigurationFilename).AsTask().Result == null)
                {
                    StorageFile templateConfigurationfile = Package.Current.InstalledLocation.GetFileAsync(ConfigurationFilename).AsTask().Result;
                    templateConfigurationfile.CopyAsync(localFolder, ConfigurationFilename).AsTask();

                    this.logging.LogMessage("JSON configuration file missing, templated created", LoggingLevel.Warning);
                    return;
                }

                IConfiguration configuration = new ConfigurationBuilder().AddJsonFile(Path.Combine(localFolder.Path, ConfigurationFilename), false, true).Build();

                this.azureStorageConnectionString = configuration.GetSection("AzureStorageConnectionString").Value;
                startupInformation.AddString("AzureStorageConnectionString", this.azureStorageConnectionString);

                this.azureStorageContainerNameLatestFormat = configuration.GetSection("AzureContainerNameFormatLatest").Value;
                startupInformation.AddString("ContainerNameLatestFormat", this.azureStorageContainerNameLatestFormat);

                this.azureStorageimageFilenameLatestFormat = configuration.GetSection("AzureImageFilenameFormatLatest").Value;
                startupInformation.AddString("ImageFilenameLatestFormat", this.azureStorageimageFilenameLatestFormat);

                this.azureStorageContainerNameHistoryFormat = configuration.GetSection("AzureContainerNameFormatHistory").Value;
                startupInformation.AddString("ContainerNameHistoryFormat", this.azureStorageContainerNameHistoryFormat);

                this.azureStorageImageFilenameHistoryFormat = configuration.GetSection("AzureImageFilenameFormatHistory").Value;
                startupInformation.AddString("ImageFilenameHistoryFormat", this.azureStorageImageFilenameHistoryFormat);

                this.interruptPinNumber = int.Parse(configuration.GetSection("InterruptPinNumber").Value);
                startupInformation.AddInt32("Interrupt pin", this.interruptPinNumber);

                this.interruptTriggerOn = (GpioPinEdge)Enum.Parse(typeof(GpioPinEdge), configuration.GetSection("interruptTriggerOn").Value);
                startupInformation.AddString("Interrupt Trigger on", this.interruptTriggerOn.ToString());

                this.debounceTimeout = TimeSpan.Parse(configuration.GetSection("debounceTimeout").Value);
                startupInformation.AddTimeSpan("Debounce timeout", this.debounceTimeout);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load or settings retrieval failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                this.mediaCapture = new MediaCapture();
                this.mediaCapture.InitializeAsync().AsTask().Wait();
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Camera configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                GpioController gpioController = GpioController.GetDefault();
                this.interruptGpioPin = gpioController.OpenPin(this.interruptPinNumber);
                this.interruptGpioPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
                this.interruptGpioPin.ValueChanged += this.InterruptGpioPin_ValueChanged;
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Digital input configuration failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            this.logging.LogEvent("Application started", startupInformation);

            // enable task to continue running in background
            this.backgroundTaskDeferral = taskInstance.GetDeferral();
        }
        private async Task <MethodResponse> DevicePushAsync(MethodRequest methodRequest, object userContext)
        {
            LoggingFields pushLoggingInfo = new LoggingFields();

            this.logging.LogEvent("Push BCD initiated");

            try
            {
                // Initially use a dynamac maybe use a decorated class in future +flexibility -performance
                dynamic json = JValue.Parse(methodRequest.DataAsJson);

                // Prepare the server address bytes for the message header and validate length
                byte[] serverAddressBytes = Encoding.UTF8.GetBytes(this.applicationSettings.RF24Address);
                pushLoggingInfo.AddInt32("serverAddressBytes Length", serverAddressBytes.Length);

                if (serverAddressBytes.Length > MessageAddressLengthMaximum)
                {
                    this.logging.LogEvent("DevicePushBcdAsync failed server address bytes Length", pushLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(400));
                }

                // Convert the device address from the JSON payload to bytes and validate length
                string deviceAddressBcd = json.DeviceAddress;
                pushLoggingInfo.AddString("DeviceAddressBCD", deviceAddressBcd);

                byte[] deviceAddressBytes = deviceAddressBcd.Split('-').Select(x => byte.Parse(x, NumberStyles.HexNumber)).ToArray();
                pushLoggingInfo.AddInt32("DeviceAddressBytes Length", deviceAddressBytes.Length);

                if ((deviceAddressBytes.Length <) || (deviceAddressBytes.Length >))
                {
                    this.logging.LogEvent("DevicePushAsync failed device address bytes length", pushLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(414));
                }

                string messagedBcd = json.DevicePayload;
                pushLoggingInfo.AddString("MessageBCD", messagedBcd);

                byte[] messageBytes = messagedBcd.Split('-').Select(x => byte.Parse(x, NumberStyles.HexNumber)).ToArray();
                pushLoggingInfo.AddInt32("MessageBytesLength", messageBytes.Length);

                Debug.WriteLine($"BondDeviceAsync DeviceAddress:{deviceAddressBcd} Payload:{messagedBcd} ServerAddress:{serverAddressBytes}");

                int payloadLength = MessageHeaderLength + deviceAddressBytes.Length + messageBytes.Length;
                pushLoggingInfo.AddInt32("PayloadLength", payloadLength);

                if (payloadLength < MessagePayloadLengthMinimum || (payloadLength > MessagePayloadLengthMaximum))
                {
                    this.logging.LogEvent("DevicePushBcdAsync failed payload Length", pushLoggingInfo, LoggingLevel.Error);
                    return(new MethodResponse(400));
                }

                // Assemble payload to send to device
                byte[] payloadBytes = new byte[payloadLength];

                payloadBytes[0] = (byte)(((byte)MessagePayloadType.DeviceIdPlusBinaryPayload << 4) | deviceAddressBytes.Length);
                Array.Copy(serverAddressBytes, 0, payloadBytes, MessageHeaderLength, serverAddressBytes.Length);
                Array.Copy(messageBytes, 0, payloadBytes, MessageHeaderLength + serverAddressBytes.Length, messageBytes.Length);

                this.rf24.SendTo(deviceAddressBytes, payloadBytes);

                this.logging.LogEvent("Device Push BCD data", pushLoggingInfo, LoggingLevel.Information);
            }
            catch (Exception ex)
            {
                pushLoggingInfo.AddString("Exception", ex.ToString());
                this.logging.LogEvent("DevicePushAsync failed exception", pushLoggingInfo, LoggingLevel.Error);

                return(new MethodResponse(400));
            }

            return(new MethodResponse(200));
        }