Ejemplo n.º 1
0
        void IMessageHandler.MqttApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            LoggingFields processReceiveLoggingFields = new LoggingFields();

            processReceiveLoggingFields.AddString("ClientId", e.ClientId);
#if DEBUG
            processReceiveLoggingFields.AddString("Payload", e.ApplicationMessage.ConvertPayloadToString());
#endif
            processReceiveLoggingFields.AddString("QualityOfServiceLevel", e.ApplicationMessage.QualityOfServiceLevel.ToString());
            processReceiveLoggingFields.AddBoolean("Retain", e.ApplicationMessage.Retain);
            processReceiveLoggingFields.AddString("Topic", e.ApplicationMessage.Topic);

            this.Logging.LogEvent("MqttApplicationMessageReceived topic not processed", processReceiveLoggingFields, LoggingLevel.Error);
        }
Ejemplo n.º 2
0
        void IMessageHandler.MqttApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            LoggingFields processReceiveLoggingFields = new LoggingFields();

            processReceiveLoggingFields.AddString("ClientId", e.ClientId);
#if DEBUG
            processReceiveLoggingFields.AddString("Payload", e.ApplicationMessage.ConvertPayloadToString());
#endif
            processReceiveLoggingFields.AddString("QualityOfServiceLevel", e.ApplicationMessage.QualityOfServiceLevel.ToString());
            processReceiveLoggingFields.AddBoolean("Retain", e.ApplicationMessage.Retain);
            processReceiveLoggingFields.AddString("Topic", e.ApplicationMessage.Topic);

            // Check to see if this is a rate limit notification
            string rateLimittopic = $"{MqttClient.Options.Credentials.Username}/throttle";
            if (string.Compare(e.ApplicationMessage.Topic, rateLimittopic, false) == 0)
            {
                this.Logging.LogEvent("MqttApplicationMessageReceived rate limiting occuring", processReceiveLoggingFields, LoggingLevel.Warning);
                return;
            }

            this.Logging.LogEvent("MqttApplicationMessageReceived topic not processed", processReceiveLoggingFields, LoggingLevel.Error);
        }
Ejemplo n.º 3
0
        public IAsyncOperation <NiconicoSignInStatus> SignIn(string mailOrTelephone, string password)
        {
            return(AsyncInfo.Run <NiconicoSignInStatus>(async(cancelToken) =>
            {
                if (!Util.InternetConnection.IsInternet())
                {
                    NiconicoContext?.Dispose();
                    NiconicoContext = new NiconicoContext();
                    return NiconicoSignInStatus.Failed;
                }

                if (NiconicoContext != null &&
                    NiconicoContext.AuthenticationToken?.MailOrTelephone == mailOrTelephone &&
                    NiconicoContext.AuthenticationToken?.Password == password)
                {
                    return NiconicoSignInStatus.Success;
                }

                await SignOut();

                try
                {
                    await _SigninLock.WaitAsync();



                    var context = new NiconicoContext(new NiconicoAuthenticationToken(mailOrTelephone, password));

                    context.AdditionalUserAgent = HohoemaUserAgent;

                    LoginErrorText = "";

                    Debug.WriteLine("try login");

                    NiconicoSignInStatus result = NiconicoSignInStatus.Failed;
                    try
                    {
                        result = await context.SignInAsync();
                    }
                    catch
                    {
                        LoginErrorText = "サインインに失敗、再起動をお試しください";
                    }

                    UpdateServiceStatus(result);

                    NiconicoContext = context;

                    if (result == NiconicoSignInStatus.Success)
                    {
                        Debug.WriteLine("login success");


                        using (var loginActivityLogger = LoggingChannel.StartActivity("login process"))
                        {
                            loginActivityLogger.LogEvent("begin login process.");

                            var fields = new LoggingFields();

                            await Task.Delay(500);
                            try
                            {
                                loginActivityLogger.LogEvent("getting UserInfo.");
                                var userInfo = await NiconicoContext.User.GetInfoAsync();

                                LoginUserId = userInfo.Id;
                                IsPremiumUser = userInfo.IsPremium;

                                {
                                    try
                                    {
                                        var user = await NiconicoContext.User.GetUserDetail(LoginUserId.ToString());
                                        LoginUserName = user.Nickname;
                                        UserIconUrl = user.ThumbnailUri;

                                        OnPropertyChanged(nameof(LoginUserName));
                                        OnPropertyChanged(nameof(UserIconUrl));
                                    }
                                    catch (Exception ex)
                                    {
                                        throw new Exception("ユーザー名取得のフォールバック処理に失敗 + " + LoginUserId, ex);
                                    }
                                }

                                fields.AddString("user id", LoginUserId.ToString());
                                fields.AddString("user name", LoginUserName);
                                fields.AddBoolean("is premium", IsPremiumUser);

                                loginActivityLogger.LogEvent("[Success]:get UserInfo.", fields, LoggingLevel.Information);
                            }
                            catch (Exception ex)
                            {
                                LoginErrorText = $"ユーザー情報の取得に失敗しました。再起動をお試しください。({ex.Message})";

                                fields.AddString("mail", mailOrTelephone);
                                loginActivityLogger.LogEvent(LoginErrorText, fields, LoggingLevel.Warning);

                                NiconicoContext.Dispose();
                                NiconicoContext = new NiconicoContext();

                                return NiconicoSignInStatus.Failed;
                            }

                            fields.Clear();



                            Debug.WriteLine("user id is : " + LoginUserId);


                            // 0.4.0以前のバージョンからのログインユーザー情報の移行処理
                            try
                            {
                                await MigrateLegacyUserSettings(LoginUserId.ToString());
                            }
                            catch
                            {
                                LoginErrorText = "ユーザー設定の過去バージョンとの統合処理に失敗しました。";

                                return NiconicoSignInStatus.Failed;
                            }


                            try
                            {
                                Debug.WriteLine("initilize: fav");
                                loginActivityLogger.LogEvent("initialize user favorite");
                                FollowManager = await FollowManager.Create(this, LoginUserId);
                            }
                            catch
                            {
                                LoginErrorText = "お気に入り情報の取得に失敗しました。再起動をお試しください。";
                                Debug.WriteLine(LoginErrorText);
                                loginActivityLogger.LogEvent(LoginErrorText, fields, LoggingLevel.Error);
                                NiconicoContext.Dispose();
                                NiconicoContext = new NiconicoContext();
                                return NiconicoSignInStatus.Failed;
                            }

                            FollowManagerUpdater = BackgroundUpdater.RegistrationBackgroundUpdateScheduleHandler(
                                FollowManager,
                                "FollowManager",
                                label: "フォロー"
                                );


                            Debug.WriteLine("Login done.");
                            loginActivityLogger.LogEvent("[Success]: Login done");
                        }

                        // BG更新をスケジュール
                        UpdateAllComponent();

                        // 動画のキャッシュフォルダの選択状態をチェック
                        await(App.Current as App).CheckVideoCacheFolderState();


                        // サインイン完了
                        OnSignin?.Invoke();

                        // TODO: 途中だった動画のダウンロードを再開
                        // await MediaManager.StartBackgroundDownload();



                        // ニコニコサービスの裏で取得させたいので強制的に待ちを挟む
                        await Task.Delay(1000);
                    }
                    else
                    {
                        Debug.WriteLine("login failed");
                        NiconicoContext?.Dispose();
                        NiconicoContext = null;
                    }

                    return result;
                }
                finally
                {
                    _SigninLock.Release();
                }
            }));
        }
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            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();
                }

                // Load the settings from configuration file exit application if missing or invalid
                StorageFile file = localFolder.GetFileAsync(ConfigurationFilename).AsTask().Result;

                applicationSettings = (JsonConvert.DeserializeObject <ApplicationSettings>(FileIO.ReadTextAsync(file).AsTask().Result));
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            // Log the Application build, shield information etc.
            LoggingFields appllicationBuildInformation = new LoggingFields();

#if DRAGINO
            appllicationBuildInformation.AddString("Shield", "DraginoLoRaGPSHat");
#endif
#if ELECROW
            appllicationBuildInformation.AddString("Shield", "ElecrowRFM95IoTBoard");
#endif
#if M2M
            appllicationBuildInformation.AddString("Shield", "M2M1ChannelLoRaWanGatewayShield");
#endif
#if ELECTRONIC_TRICKS
            appllicationBuildInformation.AddString("Shield", "ElectronicTricksLoRaLoRaWANShield");
#endif
#if UPUTRONICS_RPIZERO_CS0
            appllicationBuildInformation.AddString("Shield", "UputronicsPiZeroLoRaExpansionBoardCS0");
#endif
#if UPUTRONICS_RPIZERO_CS1
            appllicationBuildInformation.AddString("Shield", "UputronicsPiZeroLoRaExpansionBoardCS1");
#endif
#if UPUTRONICS_RPIPLUS_CS0
            appllicationBuildInformation.AddString("Shield", "UputronicsPiPlusLoRaExpansionBoardCS0");
#endif
#if UPUTRONICS_RPIPLUS_CS1
            appllicationBuildInformation.AddString("Shield", "UputronicsPiPlusLoRaExpansionBoardCS1");
#endif
#if ADAFRUIT_RADIO_BONNET
            appllicationBuildInformation.AddString("Shield", "AdafruitRadioBonnet");
#endif
            appllicationBuildInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            appllicationBuildInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            appllicationBuildInformation.AddString("MachineName", Environment.MachineName);

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

            appllicationBuildInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));
            this.logging.LogEvent("Application starting", appllicationBuildInformation, LoggingLevel.Information);

            // Configure the AdaFruit API client
            LoggingFields adaFruitIOSettings = new LoggingFields();
            if (!string.IsNullOrEmpty(this.applicationSettings.AdaFruitIOBaseUrl))
            {
                this.adaFruitIOClient.BaseUrl = this.applicationSettings.AdaFruitIOBaseUrl;
                adaFruitIOSettings.AddString("BaseURL", this.applicationSettings.AdaFruitIOBaseUrl);
            }

            this.adaFruitIOClient.ApiKey = this.applicationSettings.AdaFruitIOApiKey;

            adaFruitIOSettings.AddString("APIKey", this.applicationSettings.AdaFruitIOApiKey);
            adaFruitIOSettings.AddString("UserName", this.applicationSettings.AdaFruitIOUserName);
            adaFruitIOSettings.AddString("GroupName", this.applicationSettings.AdaFruitIOGroupName);
            this.logging.LogEvent("AdaFruit.IO configuration", adaFruitIOSettings, LoggingLevel.Information);

            rfm9XDevice.OnReceive  += Rfm9XDevice_OnReceive;
            rfm9XDevice.OnTransmit += Rfm9XDevice_OnTransmit;

            rfm9XDevice.Initialise(this.applicationSettings.Frequency,
                                   rxDoneignoreIfCrcMissing: true,
                                   rxDoneignoreIfCrcInvalid: true,
                                   paBoost: this.applicationSettings.PABoost, maxPower: this.applicationSettings.MaxPower, outputPower: this.applicationSettings.OutputPower,
                                   ocpOn: this.applicationSettings.OCPOn, ocpTrim: this.applicationSettings.OCPTrim,
                                   lnaGain: this.applicationSettings.LnaGain, lnaBoost: this.applicationSettings.LNABoost,
                                   bandwidth: this.applicationSettings.Bandwidth, codingRate: this.applicationSettings.CodingRate, implicitHeaderModeOn: this.applicationSettings.ImplicitHeaderModeOn,
                                   spreadingFactor: this.applicationSettings.SpreadingFactor,
                                   rxPayloadCrcOn: true,
                                   symbolTimeout: this.applicationSettings.SymbolTimeout,
                                   preambleLength: this.applicationSettings.PreambleLength,
                                   payloadLength: this.applicationSettings.PayloadLength,
                                   payloadMaxLength: this.applicationSettings.PayloadMaxLength,
                                   freqHoppingPeriod: this.applicationSettings.FreqHoppingPeriod,
                                   lowDataRateOptimize: this.applicationSettings.LowDataRateOptimize,
                                   ppmCorrection: this.applicationSettings.PpmCorrection,

                                   detectionOptimize: this.applicationSettings.DetectionOptimize,
                                   invertIQ: this.applicationSettings.InvertIQ,
                                   detectionThreshold: this.applicationSettings.DetectionThreshold,
                                   syncWord: this.applicationSettings.SyncWord
                                   );

                        #if DEBUG
            rfm9XDevice.RegisterDump();
                        #endif

            rfm9XDevice.Receive(Encoding.UTF8.GetBytes(this.applicationSettings.Address));

            LoggingFields loRaSettings = new LoggingFields();
            loRaSettings.AddString("Address", this.applicationSettings.Address);
            loRaSettings.AddDouble("Frequency", this.applicationSettings.Frequency);
            loRaSettings.AddBoolean("PABoost", this.applicationSettings.PABoost);

            loRaSettings.AddUInt8("MaxPower", this.applicationSettings.MaxPower);
            loRaSettings.AddUInt8("OutputPower", this.applicationSettings.OutputPower);
            loRaSettings.AddBoolean("OCPOn", this.applicationSettings.OCPOn);
            loRaSettings.AddUInt8("OCPTrim", this.applicationSettings.OCPTrim);

            loRaSettings.AddString("LnaGain", this.applicationSettings.LnaGain.ToString());
            loRaSettings.AddBoolean("lnaBoost", this.applicationSettings.LNABoost);

            loRaSettings.AddString("codingRate", this.applicationSettings.CodingRate.ToString());
            loRaSettings.AddString("implicitHeaderModeOn", applicationSettings.ImplicitHeaderModeOn.ToString());
            loRaSettings.AddString("spreadingFactor", this.applicationSettings.SpreadingFactor.ToString());
            loRaSettings.AddBoolean("rxPayloadCrcOn", true);

            loRaSettings.AddUInt8("symbolTimeout", this.applicationSettings.SymbolTimeout);
            loRaSettings.AddUInt8("preambleLength", this.applicationSettings.PreambleLength);
            loRaSettings.AddUInt8("payloadLength", this.applicationSettings.PayloadLength);

            loRaSettings.AddUInt8("payloadMaxLength", this.applicationSettings.PayloadMaxLength);
            loRaSettings.AddUInt8("freqHoppingPeriod", this.applicationSettings.FreqHoppingPeriod);
            loRaSettings.AddBoolean("lowDataRateOptimize", this.applicationSettings.LowDataRateOptimize);
            loRaSettings.AddUInt8("ppmCorrection", this.applicationSettings.PpmCorrection);

            loRaSettings.AddString("detectionOptimize", this.applicationSettings.DetectionOptimize.ToString());
            loRaSettings.AddBoolean("invertIQ", this.applicationSettings.InvertIQ);
            loRaSettings.AddString("detectionThreshold", this.applicationSettings.DetectionThreshold.ToString());
            loRaSettings.AddUInt8("SyncWord", this.applicationSettings.SyncWord);

            this.logging.LogEvent("LoRa configuration", loRaSettings, LoggingLevel.Information);

            this.deferral = taskInstance.GetDeferral();
        }
Ejemplo n.º 5
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            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();
                }

                // Load the settings from configuration file exit application if missing or invalid
                StorageFile file = localFolder.GetFileAsync(ConfigurationFilename).AsTask().Result;

                applicationSettings = (JsonConvert.DeserializeObject <ApplicationSettings>(FileIO.ReadTextAsync(file).AsTask().Result));
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            // Log the Application build, shield information etc.
            LoggingFields applicationBuildInformation = new LoggingFields();

#if DRAGINO
            applicationBuildInformation.AddString("Shield", "DraginoLoRaGPSHat");
#endif
#if ELECROW
            applicationBuildInformation.AddString("Shield", "ElecrowRFM95IoTBoard");
#endif
#if M2M
            applicationBuildInformation.AddString("Shield", "M2M1ChannelLoRaWanGatewayShield");
#endif
#if ELECTRONIC_TRICKS
            applicationBuildInformation.AddString("Shield", "ElectronicTricksLoRaLoRaWANShield");
#endif
#if UPUTRONICS_RPIZERO_CS0
            applicationBuildInformation.AddString("Shield", "UputronicsPiZeroLoRaExpansionBoardCS0");
#endif
#if UPUTRONICS_RPIZERO_CS1
            applicationBuildInformation.AddString("Shield", "UputronicsPiZeroLoRaExpansionBoardCS1");
#endif
#if UPUTRONICS_RPIPLUS_CS0
            applicationBuildInformation.AddString("Shield", "UputronicsPiPlusLoRaExpansionBoardCS0");
#endif
#if UPUTRONICS_RPIPLUS_CS1
            applicationBuildInformation.AddString("Shield", "UputronicsPiPlusLoRaExpansionBoardCS1");
#endif
#if ADAFRUIT_RADIO_BONNET
            applicationBuildInformation.AddString("Shield", "AdafruitRadioBonnet");
#endif
#if PAYLOAD_TEXT
            applicationBuildInformation.AddString("PayloadProcessor", "Text");
#endif
#if PAYLOAD_TEXT_COMA_SEPARATED_VALUES
            applicationBuildInformation.AddString("PayloadProcessor", "ComaSeperatedValues");
#endif
#if PAYLOAD_BINARY_BINARY_CODED_DECIMAL
            applicationBuildInformation.AddString("PayloadProcessor", "BinaryCodedDecimal");
#endif
#if PAYLOAD_BINARY_CAYENNE_LOW_POWER_PAYLOAD
            applicationBuildInformation.AddString("PayloadProcessor", "CayenneLowPowerPayload");
#endif
            applicationBuildInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            applicationBuildInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            applicationBuildInformation.AddString("MachineName", Environment.MachineName);

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

            applicationBuildInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));
            this.logging.LogEvent("Application starting", applicationBuildInformation, LoggingLevel.Information);

            // Log the MQTT connection string and associated settings
            LoggingFields mqttClientInformation = new LoggingFields();
            mqttClientInformation.AddString("UserName", this.applicationSettings.MqttUserName);
            mqttClientInformation.AddString("Password", this.applicationSettings.MqttPassword);
            mqttClientInformation.AddString("Server", this.applicationSettings.MqttServer);
            mqttClientInformation.AddString("ClientID", this.applicationSettings.MqttClientID);
            mqttClientInformation.AddString("PlatformSpecificConfiguration", this.applicationSettings.PlatformSpecificConfiguration);
            this.logging.LogEvent("MQTT client configuration", mqttClientInformation, LoggingLevel.Information);

            // Connect the MQTT broker so we are ready for messages
            var factory = new MqttFactory();
            this.mqttClient = factory.CreateMqttClient();

            // Wire up a handler for disconnect event for retry
            mqttClient.UseDisconnectedHandler(new MqttClientDisconnectedHandlerDelegate(e => MqttClient_Disconnected(e)));
            mqttClient.UseApplicationMessageReceivedHandler(new MqttApplicationMessageReceivedHandlerDelegate(e => MqttClient_ApplicationMessageReceived(e)));

            try
            {
                this.mqttOptions = new MqttClientOptionsBuilder()
                                   .WithClientId(applicationSettings.MqttClientID)
                                   .WithTcpServer(applicationSettings.MqttServer)
                                   .WithCredentials(applicationSettings.MqttUserName, applicationSettings.MqttPassword)
                                   .WithTls()
                                   .Build();

                this.mqttClient.ConnectAsync(this.mqttOptions).Wait();
            }
            catch (Exception ex)
            {
                mqttClientInformation.AddString("Exception", ex.ToString());
                this.logging.LogMessage("MQTT Connect Async failed" + ex.Message, LoggingLevel.Error);
                return;
            }

            // Load up the message handler assembly
            try
            {
                Assembly assembly = Assembly.Load(applicationSettings.MessageHandlerAssembly);

                messageHandler = (IMessageHandler)assembly.CreateInstance("devMobile.Mqtt.IoTCore.FieldGateway.MessageHandler");
                if (messageHandler == null)
                {
                    this.logging.LogMessage($"MessageHandler assembly {applicationSettings.MessageHandlerAssembly} load failed", LoggingLevel.Error);
                    return;
                }

                messageHandler.Initialise(logging, mqttClient, rfm9XDevice, applicationSettings.PlatformSpecificConfiguration);
            }
            catch (Exception ex)
            {
                mqttClientInformation.AddString("Exception", ex.ToString());
                this.logging.LogMessage("MessageHandler configuration failed" + ex.Message, LoggingLevel.Error);
                return;
            }

            // Configure the LoRa module
            rfm9XDevice.OnReceive  += Rfm9XDevice_OnReceive;
            rfm9XDevice.OnTransmit += Rfm9XDevice_OnTransmit;

            rfm9XDevice.Initialise(this.applicationSettings.Frequency,
                                   rxDoneignoreIfCrcMissing: true,
                                   rxDoneignoreIfCrcInvalid: true,
                                   paBoost: this.applicationSettings.PABoost, maxPower: this.applicationSettings.MaxPower, outputPower: this.applicationSettings.OutputPower,
                                   ocpOn: this.applicationSettings.OCPOn, ocpTrim: this.applicationSettings.OCPTrim,
                                   lnaGain: this.applicationSettings.LnaGain, lnaBoost: this.applicationSettings.LNABoost,
                                   bandwidth: this.applicationSettings.Bandwidth, codingRate: this.applicationSettings.CodingRate, implicitHeaderModeOn: this.applicationSettings.ImplicitHeaderModeOn,
                                   spreadingFactor: this.applicationSettings.SpreadingFactor,
                                   rxPayloadCrcOn: true,
                                   symbolTimeout: this.applicationSettings.SymbolTimeout,
                                   preambleLength: this.applicationSettings.PreambleLength,
                                   payloadLength: this.applicationSettings.PayloadLength,
                                   payloadMaxLength: this.applicationSettings.PayloadMaxLength,
                                   freqHoppingPeriod: this.applicationSettings.FreqHoppingPeriod,
                                   lowDataRateOptimize: this.applicationSettings.LowDataRateOptimize,
                                   ppmCorrection: this.applicationSettings.PpmCorrection,
                                   detectionOptimize: this.applicationSettings.DetectionOptimize,
                                   invertIQ: this.applicationSettings.InvertIQ,
                                   detectionThreshold: this.applicationSettings.DetectionThreshold,
                                   syncWord: this.applicationSettings.SyncWord
                                   );

#if DEBUG
            rfm9XDevice.RegisterDump();
#endif

            rfm9XDevice.Receive(Encoding.UTF8.GetBytes(this.applicationSettings.Address));

            LoggingFields loRaSettings = new LoggingFields();
            loRaSettings.AddString("Address", this.applicationSettings.Address);
            loRaSettings.AddDouble("Frequency", this.applicationSettings.Frequency);
            loRaSettings.AddBoolean("PABoost", this.applicationSettings.PABoost);

            loRaSettings.AddUInt8("MaxPower", this.applicationSettings.MaxPower);
            loRaSettings.AddUInt8("OutputPower", this.applicationSettings.OutputPower);
            loRaSettings.AddBoolean("OCPOn", this.applicationSettings.OCPOn);
            loRaSettings.AddUInt8("OCPTrim", this.applicationSettings.OCPTrim);

            loRaSettings.AddString("LnaGain", this.applicationSettings.LnaGain.ToString());
            loRaSettings.AddBoolean("lnaBoost", this.applicationSettings.LNABoost);

            loRaSettings.AddString("codingRate", this.applicationSettings.CodingRate.ToString());
            loRaSettings.AddString("implicitHeaderModeOn", applicationSettings.ImplicitHeaderModeOn.ToString());
            loRaSettings.AddString("spreadingFactor", this.applicationSettings.SpreadingFactor.ToString());
            loRaSettings.AddBoolean("rxPayloadCrcOn", true);

            loRaSettings.AddUInt8("symbolTimeout", this.applicationSettings.SymbolTimeout);
            loRaSettings.AddUInt8("preambleLength", this.applicationSettings.PreambleLength);
            loRaSettings.AddUInt8("payloadLength", this.applicationSettings.PayloadLength);

            loRaSettings.AddUInt8("payloadMaxLength", this.applicationSettings.PayloadMaxLength);
            loRaSettings.AddUInt8("freqHoppingPeriod", this.applicationSettings.FreqHoppingPeriod);
            loRaSettings.AddBoolean("lowDataRateOptimize", this.applicationSettings.LowDataRateOptimize);
            loRaSettings.AddUInt8("ppmCorrection", this.applicationSettings.PpmCorrection);

            loRaSettings.AddString("detectionOptimize", this.applicationSettings.DetectionOptimize.ToString());
            loRaSettings.AddBoolean("invertIQ", this.applicationSettings.InvertIQ);
            loRaSettings.AddString("detectionThreshold", this.applicationSettings.DetectionThreshold.ToString());
            loRaSettings.AddUInt8("SyncWord", this.applicationSettings.SyncWord);

            this.logging.LogEvent("LoRa configuration", loRaSettings, LoggingLevel.Information);

            this.deferral = taskInstance.GetDeferral();
        }
Ejemplo n.º 6
0
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            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();
                }

                // Load the settings from configuration file exit application if missing or invalid
                StorageFile file = localFolder.GetFileAsync(ConfigurationFilename).AsTask().Result;

                applicationSettings = (JsonConvert.DeserializeObject <ApplicationSettings>(FileIO.ReadTextAsync(file).AsTask().Result));
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            // Log the Application build, shield information etc.
            LoggingFields applicationBuildInformation = new LoggingFields();

#if DRAGINO
            applicationBuildInformation.AddString("Shield", "DraginoLoRaGPSHat");
#endif
#if ELECROW
            applicationBuildInformation.AddString("Shield", "ElecrowRFM95IoTBoard");
#endif
#if M2M
            applicationBuildInformation.AddString("Shield", "M2M1ChannelLoRaWanGatewayShield");
#endif
#if ELECTRONIC_TRICKS
            applicationBuildInformation.AddString("Shield", "ElectronicTricksLoRaLoRaWANShield");
#endif
#if UPUTRONICS_RPIZERO_CS0
            applicationBuildInformation.AddString("Shield", "UputronicsPiZeroLoRaExpansionBoardCS0");
#endif
#if UPUTRONICS_RPIZERO_CS1
            applicationBuildInformation.AddString("Shield", "UputronicsPiZeroLoRaExpansionBoardCS1");
#endif
#if UPUTRONICS_RPIPLUS_CS0
            applicationBuildInformation.AddString("Shield", "UputronicsPiPlusLoRaExpansionBoardCS0");
#endif
#if UPUTRONICS_RPIPLUS_CS1
            applicationBuildInformation.AddString("Shield", "UputronicsPiPlusLoRaExpansionBoardCS1");
#endif
#if ADAFRUIT_RADIO_BONNET
            applicationBuildInformation.AddString("Shield", "AdafruitRadioBonnet");
#endif
#if CLOUD_DEVICE_BOND
            applicationBuildInformation.AddString("Bond", "Supported");
#else
            applicationBuildInformation.AddString("Bond", "NotSupported");
#endif
#if CLOUD_DEVICE_PUSH
            applicationBuildInformation.AddString("Push", "Supported");
#else
            applicationBuildInformation.AddString("Push", "NotSupported");
#endif
#if CLOUD_DEVICE_SEND
            applicationBuildInformation.AddString("Send", "Supported");
#else
            applicationBuildInformation.AddString("Send", "NotSupported");
#endif
#if PAYLOAD_TEXT
            applicationBuildInformation.AddString("PayloadProcessor", "Text");
#endif
#if PAYLOAD_TEXT_COMA_SEPARATED_VALUES
            applicationBuildInformation.AddString("PayloadProcessor", "ComaSeperatedValues");
#endif
#if PAYLOAD_BINARY_BINARY_CODED_DECIMAL
            applicationBuildInformation.AddString("PayloadProcessor", "BinaryCodedDecimal");
#endif
#if PAYLOAD_BINARY_CAYENNE_LOW_POWER_PAYLOAD
            applicationBuildInformation.AddString("PayloadProcessor", "CayenneLowPowerPayload");
#endif

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

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

            applicationBuildInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));
            this.logging.LogEvent("Application starting", applicationBuildInformation, LoggingLevel.Information);

            try
            {
#if DRAGINO
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS0, ChipSelectLine, ResetLine, InterruptLine);
#endif
#if M2M
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS0, ChipSelectLine, ResetLine, InterruptLine);
#endif
#if ELECROW
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS1, ResetLine, InterruptLine);
#endif
#if ELECTRONIC_TRICKS
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS0, ResetLine, InterruptLine);
#endif
#if UPUTRONICS_RPIZERO_CS0
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS0, InterruptLine);
#endif
#if UPUTRONICS_RPIZERO_CS1
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS1, InterruptLine);
#endif
#if UPUTRONICS_RPIPLUS_CS0
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS0, InterruptLine);
#endif
#if UPUTRONICS_RPIPLUS_CS1
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS1, InterruptLine);
#endif
#if ADAFRUIT_RADIO_BONNET
                rfm9XDevice = new Rfm9XDevice(ChipSelectPin.CS1, ResetLine, InterruptLine);
#endif
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Hardware initialisation failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            // Log the Azure connection string and associated settings
            LoggingFields azureIoTHubSettings = new LoggingFields();
            azureIoTHubSettings.AddString("DeviceConnectionString", this.applicationSettings.AzureIoTHubDeviceConnectionString);
            azureIoTHubSettings.AddString("TransportType", this.applicationSettings.AzureIoTHubTransportType.ToString());
            azureIoTHubSettings.AddString("SensorIDIsDeviceIDSensorID", this.applicationSettings.SensorIDIsDeviceIDSensorID.ToString());
            this.logging.LogEvent("AzureIoTHub configuration", azureIoTHubSettings, LoggingLevel.Information);

            // Connect the IoT hub first so we are ready for any messages
            try
            {
                this.azureIoTHubClient = DeviceClient.CreateFromConnectionString(this.applicationSettings.AzureIoTHubDeviceConnectionString, this.applicationSettings.AzureIoTHubTransportType);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("IoT Hub connection failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            try
            {
                TwinCollection reportedProperties;
                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);
                }

                azureIoTHubClient.UpdateReportedPropertiesAsync(reportedProperties).Wait();
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("IoT Hub updating reported properties failed " + ex.Message, LoggingLevel.Error);
            }

            // Wire up the field gateway restart method handler
            try
            {
                azureIoTHubClient.SetMethodHandlerAsync("Restart", RestartAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub Restart method handler setup failed " + ex.Message, LoggingLevel.Error);
                return;
            }

#if CLOUD_DEVICE_BOND
            // Wire up the bond device method handler
            try
            {
                azureIoTHubClient.SetMethodHandlerAsync("DeviceBond", this.DeviceBondAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub Device Bond method handler setup failed " + ex.Message, LoggingLevel.Error);
                return;
            }
#endif

#if CLOUD_DEVICE_PUSH
            // Wire up the push message to device method handler
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("DevicePush", this.DevicePushAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub DevicePush method handler setup failed " + ex.Message, LoggingLevel.Error);
                return;
            }
#endif

#if CLOUD_DEVICE_SEND
            // Wire up the send message to device method handler
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("DeviceSend", this.DeviceSendAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client DeviceSend method handler setup failed " + ex.Message, LoggingLevel.Error);
                return;
            }
#endif

            // Configure the LoRa module
            rfm9XDevice.OnReceive  += Rfm9XDevice_OnReceive;
            rfm9XDevice.OnTransmit += Rfm9XDevice_OnTransmit;

            rfm9XDevice.Initialise(this.applicationSettings.Frequency,
                                   rxDoneignoreIfCrcMissing: true,
                                   rxDoneignoreIfCrcInvalid: true,
                                   paBoost: this.applicationSettings.PABoost, maxPower: this.applicationSettings.MaxPower, outputPower: this.applicationSettings.OutputPower,
                                   ocpOn: this.applicationSettings.OCPOn, ocpTrim: this.applicationSettings.OCPTrim,
                                   lnaGain: this.applicationSettings.LnaGain, lnaBoost: this.applicationSettings.LNABoost,
                                   bandwidth: this.applicationSettings.Bandwidth, codingRate: this.applicationSettings.CodingRate, implicitHeaderModeOn: this.applicationSettings.ImplicitHeaderModeOn,
                                   spreadingFactor: this.applicationSettings.SpreadingFactor,
                                   rxPayloadCrcOn: true,
                                   symbolTimeout: this.applicationSettings.SymbolTimeout,
                                   preambleLength: this.applicationSettings.PreambleLength,
                                   payloadLength: this.applicationSettings.PayloadLength,
                                   payloadMaxLength: this.applicationSettings.PayloadMaxLength,
                                   freqHoppingPeriod: this.applicationSettings.FreqHoppingPeriod,
                                   lowDataRateOptimize: this.applicationSettings.LowDataRateOptimize,
                                   ppmCorrection: this.applicationSettings.PpmCorrection,
                                   detectionOptimize: this.applicationSettings.DetectionOptimize,
                                   invertIQ: this.applicationSettings.InvertIQ,
                                   detectionThreshold: this.applicationSettings.DetectionThreshold,
                                   syncWord: this.applicationSettings.SyncWord
                                   );

#if DEBUG
            rfm9XDevice.RegisterDump();
#endif

            rfm9XDevice.Receive(Encoding.UTF8.GetBytes(this.applicationSettings.Address));

            LoggingFields loRaSettings = new LoggingFields();
            loRaSettings.AddString("Address", this.applicationSettings.Address);
            loRaSettings.AddDouble("Frequency", this.applicationSettings.Frequency);
            loRaSettings.AddBoolean("PABoost", this.applicationSettings.PABoost);

            loRaSettings.AddUInt8("MaxPower", this.applicationSettings.MaxPower);
            loRaSettings.AddUInt8("OutputPower", this.applicationSettings.OutputPower);
            loRaSettings.AddBoolean("OCPOn", this.applicationSettings.OCPOn);
            loRaSettings.AddUInt8("OCPTrim", this.applicationSettings.OCPTrim);

            loRaSettings.AddString("LnaGain", this.applicationSettings.LnaGain.ToString());
            loRaSettings.AddBoolean("lnaBoost", this.applicationSettings.LNABoost);

            loRaSettings.AddString("codingRate", this.applicationSettings.CodingRate.ToString());
            loRaSettings.AddString("implicitHeaderModeOn", applicationSettings.ImplicitHeaderModeOn.ToString());
            loRaSettings.AddString("spreadingFactor", this.applicationSettings.SpreadingFactor.ToString());
            loRaSettings.AddBoolean("rxPayloadCrcOn", true);

            loRaSettings.AddUInt8("symbolTimeout", this.applicationSettings.SymbolTimeout);
            loRaSettings.AddUInt8("preambleLength", this.applicationSettings.PreambleLength);
            loRaSettings.AddUInt8("payloadLength", this.applicationSettings.PayloadLength);

            loRaSettings.AddUInt8("payloadMaxLength", this.applicationSettings.PayloadMaxLength);
            loRaSettings.AddUInt8("freqHoppingPeriod", this.applicationSettings.FreqHoppingPeriod);
            loRaSettings.AddBoolean("lowDataRateOptimize", this.applicationSettings.LowDataRateOptimize);
            loRaSettings.AddUInt8("ppmCorrection", this.applicationSettings.PpmCorrection);

            loRaSettings.AddString("detectionOptimize", this.applicationSettings.DetectionOptimize.ToString());
            loRaSettings.AddBoolean("invertIQ", this.applicationSettings.InvertIQ);
            loRaSettings.AddString("detectionThreshold", this.applicationSettings.DetectionThreshold.ToString());
            loRaSettings.AddUInt8("SyncWord", this.applicationSettings.SyncWord);

            this.logging.LogEvent("LoRa configuration", loRaSettings, LoggingLevel.Information);

            this.deferral = taskInstance.GetDeferral();
        }
        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;
            }
        }
        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;

            try
            {
                using (Windows.Storage.Streams.InMemoryRandomAccessStream captureStream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
                {
                    await this.mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), captureStream);

                    await captureStream.FlushAsync();

#if DEBUG
                    IStorageFile photoFile = await KnownFolders.PicturesLibrary.CreateFileAsync(ImageFilenameLocal, CreationCollisionOption.ReplaceExisting);

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

                    string azureFilenameLatest  = string.Format(this.azureStorageimageFilenameLatestFormat, currentTime);
                    string azureFilenameHistory = string.Format(this.azureStorageImageFilenameHistoryFormat, currentTime);

                    LoggingFields imageInformation = new LoggingFields();
                    imageInformation.AddDateTime("TakenAtUTC", currentTime);
                    imageInformation.AddBoolean("IsCommand", isCommand);
#if DEBUG
                    imageInformation.AddString("LocalFilename", photoFile.Path);
#endif
                    imageInformation.AddString("AzureFilenameLatest", azureFilenameLatest);
                    imageInformation.AddString("AzureFilenameHistory", azureFilenameHistory);
                    this.logging.LogEvent("Saving image(s) to Azure storage", imageInformation);

                    // Update the latest image in storage
                    if (!string.IsNullOrWhiteSpace(azureFilenameLatest))
                    {
                        captureStream.Seek(0);
                        Debug.WriteLine("AzureIoT Hub latest image upload start");
                        await this.azureIoTHubClient.UploadToBlobAsync(azureFilenameLatest, captureStream.AsStreamForRead());

                        Debug.WriteLine("AzureIoT Hub latest image upload done");
                    }

                    // Upload the historic image to storage
                    if (!string.IsNullOrWhiteSpace(azureFilenameHistory))
                    {
                        captureStream.Seek(0);
                        Debug.WriteLine("AzureIoT Hub historic image upload start");
                        await this.azureIoTHubClient.UploadToBlobAsync(azureFilenameHistory, captureStream.AsStreamForRead());

                        Debug.WriteLine("AzureIoT Hub historic image upload done");
                    }
                }
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Image capture or AzureIoTHub storage upload failed " + ex.Message, LoggingLevel.Error);
            }
            finally
            {
                this.cameraBusy = false;
            }
        }
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;

            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();
                }

                // Load the settings from configuration file exit application if missing or invalid
                StorageFile file = localFolder.GetFileAsync(ConfigurationFilename).AsTask().Result;

                this.applicationSettings = JsonConvert.DeserializeObject <ApplicationSettings>(FileIO.ReadTextAsync(file).AsTask().Result);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("JSON configuration file load failed " + ex.Message, LoggingLevel.Error);
                return;
            }

#if CEECH_NRF24L01P_SHIELD
            // Disable the onboard beeper so it doesn't whine so much
            GpioController gpioController = GpioController.GetDefault();
            GpioPin        buzzer         = gpioController.OpenPin(4);
            buzzer.SetDriveMode(GpioPinDriveMode.Output);
            buzzer.Write(GpioPinValue.Low);
#endif

            // Log the Application build, shield information etc.
            LoggingFields applicationBuildInformation = new LoggingFields();
#if CEECH_NRF24L01P_SHIELD
            applicationBuildInformation.AddString("Shield", "CeechnRF24L01P");
#endif
#if BOROS_RF2_SHIELD_RADIO_0
            appllcationBuildInformation.AddString("Shield", "BorosRF2Port0");
#endif
#if BOROS_RF2_SHIELD_RADIO_1
            applicationBuildInformation.AddString("Shield", "BorosRF2Port1");
#endif
#if CLOUD_DEVICE_BOND
            applicationBuildInformation.AddString("Bond", "Supported");
#else
            applicationBuildInformation.AddString("Bond", "NotSupported");
#endif
#if CLOUD_DEVICE_PUSH
            applicationBuildInformation.AddString("Push", "Supported");
#else
            applicationBuildInformation.AddString("Push", "NotSupported");
#endif
#if CLOUD_DEVICE_SEND
            applicationBuildInformation.AddString("Send", "Supported");
#else
            applicationBuildInformation.AddString("Send", "NotSupported");
#endif
            applicationBuildInformation.AddString("Timezone", TimeZoneSettings.CurrentTimeZoneDisplayName);
            applicationBuildInformation.AddString("OSVersion", Environment.OSVersion.VersionString);
            applicationBuildInformation.AddString("MachineName", Environment.MachineName);

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

            applicationBuildInformation.AddString("ApplicationVersion", string.Format($"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"));
            this.logging.LogEvent("Application starting", applicationBuildInformation, LoggingLevel.Information);

            // Connect the IoT hub first so we are ready for any messages
            LoggingFields azureIoTHubSettings = new LoggingFields();
            azureIoTHubSettings.AddString("DeviceConnectionString", this.applicationSettings.AzureIoTHubDeviceConnectionString);
            azureIoTHubSettings.AddString("TransportType", this.applicationSettings.AzureIoTHubTransportType.ToString());
            azureIoTHubSettings.AddString("SensorIDIsDeviceIDSensorID", this.applicationSettings.SensorIDIsDeviceIDSensorID.ToString());
            this.logging.LogEvent("AzureIoTHub configuration", azureIoTHubSettings, LoggingLevel.Information);

            try
            {
                this.azureIoTHubClient = DeviceClient.CreateFromConnectionString(this.applicationSettings.AzureIoTHubDeviceConnectionString, this.applicationSettings.AzureIoTHubTransportType);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("IoT Hub connection failed " + ex.Message, LoggingLevel.Error);
                return;
            }

            // Wire up the field gateway restart method handler
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("Restart", this.RestartAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client Restart method handler setup failed " + ex.Message, LoggingLevel.Error);
                return;
            }

#if CLOUD_DEVICE_BOND
            // Wire up the bond device method handler
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("DeviceBond", this.DeviceBondAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub Device Bond method handler setup failed " + ex.Message, LoggingLevel.Error);
                return;
            }
#endif

#if CLOUD_DEVICE_PUSH
            // Wire up the push message to device method handler
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("DevicePush", this.DevicePushAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client DevicePush SetMethodHandlerAsync failed " + ex.Message, LoggingLevel.Error);
                return;
            }
#endif

#if CLOUD_DEVICE_SEND
            // Wire up the send message to device method handler
            try
            {
                this.azureIoTHubClient.SetMethodHandlerAsync("DeviceSend", this.DeviceSendAsync, null);
            }
            catch (Exception ex)
            {
                this.logging.LogMessage("Azure IoT Hub client DeviceSend SetMethodHandlerAsync failed " + ex.Message, LoggingLevel.Error);
                return;
            }
#endif

            // Configure the nRF24L01 module
            this.rf24.OnDataReceived    += this.Radio_OnDataReceived;
            this.rf24.OnTransmitFailed  += this.Radio_OnTransmitFailed;
            this.rf24.OnTransmitSuccess += this.Radio_OnTransmitSuccess;

            this.rf24.Initialize(RF24ModuleChipEnablePin, RF24ModuleChipSelectPin, RF24ModuleInterruptPin);
            this.rf24.Address = Encoding.UTF8.GetBytes(this.applicationSettings.RF24Address);
            this.rf24.Channel = this.applicationSettings.RF24Channel;

            // The order of setting the power level and Data rate appears to be important, most probably register masking issue in NRF24 library which needs some investigation
            this.rf24.PowerLevel           = this.applicationSettings.RF24PowerLevel;
            this.rf24.DataRate             = this.applicationSettings.RF24DataRate;
            this.rf24.IsAutoAcknowledge    = this.applicationSettings.IsRF24AutoAcknowledge;
            this.rf24.IsDyanmicAcknowledge = this.applicationSettings.IsRF24DynamicAcknowledge;
            this.rf24.IsDynamicPayload     = this.applicationSettings.IsRF24DynamicPayload;
            this.rf24.IsEnabled            = true;

            LoggingFields rf24Settings = new LoggingFields();
            rf24Settings.AddUInt8("Channel", this.applicationSettings.RF24Channel);
            rf24Settings.AddString("Address", this.applicationSettings.RF24Address);
            rf24Settings.AddString("DataRate", this.applicationSettings.RF24DataRate.ToString());
            rf24Settings.AddString("PowerLevel", this.applicationSettings.RF24PowerLevel.ToString());
            rf24Settings.AddBoolean("AutoAcknowledge", this.applicationSettings.IsRF24AutoAcknowledge);
            rf24Settings.AddBoolean("DynamicAcknowledge", this.applicationSettings.IsRF24DynamicAcknowledge);
            rf24Settings.AddBoolean("DynamicPayload", this.applicationSettings.IsRF24DynamicPayload);
            this.logging.LogEvent("nRF24L01 configuration", rf24Settings, LoggingLevel.Information);

            this.deferral = taskInstance.GetDeferral();
        }