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.º 2
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();
        }
Ejemplo n.º 3
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();
        }
        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();
        }