Beispiel #1
0
        static async Task OnDesiredPropertiesUpdated(TwinCollection desiredPropertiesPatch, object userContext)
        {
            // At this point just update the configure configuration.
            if (desiredPropertiesPatch.Contains(SendIntervalConfigKey))
            {
                messageDelay = TimeSpan.FromSeconds((int)desiredPropertiesPatch[SendIntervalConfigKey]);
            }

            if (desiredPropertiesPatch.Contains(SendDataConfigKey))
            {
                bool desiredSendDataValue = (bool)desiredPropertiesPatch[SendDataConfigKey];
                if (desiredSendDataValue != sendData && !desiredSendDataValue)
                {
                    Console.WriteLine("Sending data disabled. Change twin configuration to start sending again.");
                }

                sendData = desiredSendDataValue;
            }

            var moduleClient = (ModuleClient)userContext;
            var patch        = new TwinCollection($"{{ \"SendData\":{sendData.ToString().ToLower()}, \"SendInterval\": {messageDelay.TotalSeconds}}}");
            await moduleClient.UpdateReportedPropertiesAsync(patch); // Just report back last desired property.
        }
Beispiel #2
0
        private static Task onDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext)
        {
            var moduleClient = userContext as ModuleClient;

            if (moduleClient == null)
            {
                throw new InvalidOperationException("UserContext doesn't contain " + "expected values");
            }

            if (desiredProperties.Contains("IMAGE_POLLING_INTERVAL"))
            {
                //update the Polling Interval (if possible)
                var updated = TimeSpan.TryParse(desiredProperties["IMAGE_POLLING_INTERVAL"], out IMAGE_POLLING_INTERVAL);

                if (updated)
                {
                    Console.WriteLine("IMAGE_POLLING_INTERVAL Updated.");

                    moduleClient.UpdateReportedPropertiesAsync(desiredProperties);
                }
            }

            if (desiredProperties.Contains("MODE"))
            {
                //update the MODE
                var updated = Enum.TryParse <OperatingMode>(desiredProperties["MODE"], out MODE);

                if (updated)
                {
                    Console.WriteLine("MODE Updated.");

                    moduleClient.UpdateReportedPropertiesAsync(desiredProperties);
                }
            }

            return(Task.CompletedTask);
        }
Beispiel #3
0
        private static async Task OnDesiredPropertyChange(TwinCollection desiredproperties, object usercontext)
        {
            if (desiredproperties.Contains("deviceTwinConfig"))
            {
                Message message;

                var deviceTwinConfig =
                    JsonConvert.DeserializeObject <DesiredDeviceTwinConfiguration>(
                        desiredproperties["deviceTwinConfig"].ToString());

                // ignore delay for now. Just want to see if it can be parsed.
                int delay;

                if (int.TryParse(deviceTwinConfig.MessageSendDelay, out delay))
                {
                    lock (Locker)
                    {
                        _twinDesiredProperties = deviceTwinConfig;
                        _propertyChangeStatus  = Status.Pending;
                    }
                    message = new Message(
                        Encoding.ASCII.GetBytes(
                            $"Device accepted messageSendDelay value: `{deviceTwinConfig.MessageSendDelay}`.  Property change is pending call to 'acceptDesiredProperties'.")
                        );

                    message.Properties.Add(MessageProperty.Type.ToString("G"), Type.ConfigChage.ToString("G"));
                    message.Properties.Add(MessageProperty.Status.ToString("G"), Status.Pending.ToString("G"));
                    message.Properties.Add(MessageProperty.Severity.ToString("G"), Severity.Critical.ToString("G"));
                }
                else
                {
                    _propertyChangeStatus = Status.Rejected;

                    ($"Device Twin Property `messageSendDelay` is set to an illegal value: `{deviceTwinConfig.MessageSendDelay}`, " +
                     $"change status is 'rejected'. Sending Critical Notification.").LogMessage(ConsoleColor.Red);

                    message = new Message(
                        Encoding.ASCII.GetBytes(
                            $"Parameter messageSendDelay value: `{deviceTwinConfig.MessageSendDelay}`, could not be converted to an Int."));

                    message.Properties.Add(MessageProperty.Type.ToString("G"), Type.ConfigChage.ToString("G"));
                    message.Properties.Add(MessageProperty.Status.ToString("G"), Status.Rejected.ToString("G"));
                    message.Properties.Add(MessageProperty.Severity.ToString("G"), Severity.Critical.ToString("G"));
                }


                await _deviceClient.SendEventAsync(message);
            }
        }
        static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext)
        {
            if (desiredProperties.Contains("POLLINGfrequency"))
            {
                POLLINGfrequency = (int)desiredProperties["POLLINGfrequency"];
            }

            if (desiredProperties.Contains("POLLINGHost"))
            {
                POLLINGHost = (string)desiredProperties["POLLINGHost"];
            }

            // also reporting our Reported properties
            JObject twinResponse = new JObject();

            twinResponse["POLLINGfrequency"] = POLLINGfrequency;
            twinResponse["POLLINGHost"]      = POLLINGHost;
            Console.WriteLine("Sending TWIN: " + twinResponse.ToString());
            TwinCollection patch = new TwinCollection(twinResponse.ToString());

            ioTHubModuleClient.UpdateReportedPropertiesAsync(patch);

            return(Task.CompletedTask);
        }
Beispiel #5
0
        protected override async Task OnDesiredModulePropertyChanged(TwinCollection newDesiredProperties)
        {
            Log.WriteLine("derived desired properties contains {0} properties", newDesiredProperties.Count);
            await base.OnDesiredModulePropertyChanged(newDesiredProperties);

            DesiredPropertiesType <ConfigurationType> dp;

            if (!newDesiredProperties.Contains(Keys.Configuration))
            {
                Log.WriteLine("derived desired properties contains no configuration.  skipping...");
                return;
            }

            dp.Configuration = ((JObject)newDesiredProperties[Keys.Configuration]).ToObject <ConfigurationType>();
            Log.WriteLine("checking for update current desiredProperties {0} new dp {1}", _desiredProperties.ToString(), dp.ToString());
            var changed = _desiredProperties.Update(dp);

            if (changed)
            {
                Log.WriteLine("desired properties {0} different then current properties, notifying...", _desiredProperties.ToString());
                ConfigurationChanged?.Invoke(this, dp.Configuration);
                Log.WriteLine("local notification complete. updating reported properties to cloud twin");
                await UpdateReportedPropertiesAsync(new KeyValuePair <string, Object>(Keys.Configuration, JsonConvert.SerializeObject(_desiredProperties.Configuration)));
            }
            if (newDesiredProperties.Contains(Keys.FruitTest))
            {
                var fruit = (string)((JValue)newDesiredProperties[Keys.FruitTest]).Value;
                Log.WriteLine("fruittest {0}", fruit != null ? fruit : "(null)");
                if (fruit != null)
                {
                    Log.WriteLine("setting fruit {0}", fruit);
                    FruitChanged?.Invoke(this, fruit);
                }
            }
            Log.WriteLine("update complete -- current properties {0}", _desiredProperties.ToString());
        }
        async Task <Dictionary <string, string> > ValidatePropertiesFromTwinAsync(Twin receivedTwin)
        {
            TwinCollection propertyUpdatesFromTwin = receivedTwin.Properties.Desired;
            Dictionary <string, DateTime> desiredPropertiesUpdated = await this.storage.GetAllDesiredPropertiesUpdatedAsync();

            Dictionary <string, DateTime> desiredPropertiesReceived = await this.storage.GetAllDesiredPropertiesReceivedAsync();

            Dictionary <string, string> propertiesToRemoveFromTwin = new Dictionary <string, string>();

            foreach (KeyValuePair <string, DateTime> desiredPropertyUpdate in desiredPropertiesUpdated)
            {
                bool   hasTwinUpdate             = propertyUpdatesFromTwin.Contains(desiredPropertyUpdate.Key);
                bool   hasModuleReceivedCallback = desiredPropertiesReceived.ContainsKey(desiredPropertyUpdate.Key);
                string status;
                if (hasTwinUpdate && hasModuleReceivedCallback)
                {
                    status = $"{(int)StatusCode.ValidationSuccess}: Successfully validated desired property update";
                    Logger.LogInformation(status + $" {desiredPropertyUpdate.Key}");
                }
                else if (this.ExceedFailureThreshold(this.twinState, desiredPropertyUpdate.Value))
                {
                    if (hasTwinUpdate && !hasModuleReceivedCallback)
                    {
                        status = $"{(int)StatusCode.DesiredPropertyUpdateNoCallbackReceived}: Failure receiving desired property update in callback";
                    }
                    else if (!hasTwinUpdate && hasModuleReceivedCallback)
                    {
                        status = $"{(int)StatusCode.DesiredPropertyUpdateNotInEdgeTwin}: Failure receiving desired property update in twin";
                    }
                    else
                    {
                        status = $"{(int)StatusCode.DesiredPropertyUpdateTotalFailure}: Failure receiving desired property update in both twin and callback";
                    }

                    Logger.LogError($"{status} for update #{desiredPropertyUpdate.Key}");
                }
                else
                {
                    continue;
                }

                await this.HandleReportStatusAsync(Settings.Current.ModuleId, status);

                propertiesToRemoveFromTwin.Add(desiredPropertyUpdate.Key, null); // will later be serialized as a twin update
            }

            return(propertiesToRemoveFromTwin);
        }
        // The OnDesiredPropertyChanged event handler accepts a desiredProperties
        // parameter of type TwinCollection.
        private static async Task OnDesiredPropertyChanged(
            TwinCollection desiredProperties,
            object userContext)
        {
            Console.WriteLine("Desired Twin Property Changed:");
            Console.WriteLine($"{desiredProperties.ToJson()}");

            // Read the desired Twin Properties
            if (desiredProperties.Contains("telemetryDelay"))
            {
                // Notice that if the value of the desiredProperties parameter
                // contains telemetryDelay (a device twin desired property), the
                // code will assign the value of the device twin property to the
                // telemetryDelay variable. You may recall that the
                // SendDeviceToCloudMessagesAsync method includes a Task.Delay
                // call that uses the telemetryDelay variable to set the delay
                // time between messages sent to IoT hub.
                string desiredTelemetryDelay = desiredProperties["telemetryDelay"];
                if (desiredTelemetryDelay != null)
                {
                    telemetryDelay = int.Parse(desiredTelemetryDelay);
                }
                // if desired telemetryDelay is null or unspecified, don't change it
            }

            // The next block of code is used to report the current state of the
            // device back up to Azure IoT Hub. This code calls the DeviceClient.
            // UpdateReportedPropertiesAsync method and passes it a
            // TwinCollection that contains the current state of the device
            // properties.
            // This is how the device reports back to IoT Hub that it received
            // the device twin desired properties changed event, and has now
            // updated its configuration accordingly.
            // Note that it  reports what the properties are now set to, not an
            // echo of the desired properties. In the case where the reported
            // properties sent from the device are different than the desired
            // state that the device received, IoT Hub will maintain an accurate
            // Device Twin that reflects the state of the device.
            var reportedProperties = new TwinCollection();

            reportedProperties["telemetryDelay"] = telemetryDelay.ToString();
            await deviceClient
            .UpdateReportedPropertiesAsync(reportedProperties)
            .ConfigureAwait(false);

            Console.WriteLine("Reported Twin Properties:");
            Console.WriteLine($"{reportedProperties.ToJson()}");
        }
Beispiel #8
0
        async Task <TwinCollection> ValidatePropertiesFromTwinAsync(Twin receivedTwin)
        {
            TwinCollection propertyUpdatesFromTwin = receivedTwin.Properties.Reported;
            Dictionary <string, DateTime> reportedPropertiesUpdated = await this.storage.GetAllReportedPropertiesUpdatedAsync();

            TwinCollection propertiesToRemove = new TwinCollection();

            foreach (KeyValuePair <string, DateTime> reportedPropertyUpdate in reportedPropertiesUpdated)
            {
                string status;
                if (propertyUpdatesFromTwin.Contains(reportedPropertyUpdate.Key))
                {
                    if (this.reportedPropertyKeysFailedToReceiveWithinThreshold.Contains(reportedPropertyUpdate.Key))
                    {
                        this.reportedPropertyKeysFailedToReceiveWithinThreshold.Remove(reportedPropertyUpdate.Key);
                        status = $"{(int)StatusCode.ReportedPropertyReceivedAfterThreshold}: Successfully validated reported property update (exceeded failure threshold)";
                    }
                    else
                    {
                        status = $"{(int)StatusCode.ValidationSuccess}: Successfully validated reported property update";
                    }

                    await this.HandleReportStatusAsync(status);

                    Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}");
                    propertiesToRemove[reportedPropertyUpdate.Key] = null; // will later be serialized as a twin update
                }
                else if (!this.reportedPropertyKeysFailedToReceiveWithinThreshold.Contains(reportedPropertyUpdate.Key) &&
                         this.DoesExceedFailureThreshold(this.twinTestState, reportedPropertyUpdate.Key, reportedPropertyUpdate.Value))
                {
                    this.reportedPropertyKeysFailedToReceiveWithinThreshold.Add(reportedPropertyUpdate.Key);
                    status = $"{(int)StatusCode.ReportedPropertyUpdateNotInCloudTwin}: Failure receiving reported property update";
                    await this.HandleReportStatusAsync(status);

                    Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}");
                }
                else if (this.DoesExceedCleanupThreshold(this.twinTestState, reportedPropertyUpdate.Key, reportedPropertyUpdate.Value))
                {
                    status = $"{(int)StatusCode.ReportedPropertyUpdateNotInCloudTwinAfterCleanUpThreshold}: Failure receiving reported property update after cleanup threshold";
                    await this.HandleReportStatusAsync(status);

                    Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}");
                    propertiesToRemove[reportedPropertyUpdate.Key] = null; // will later be serialized as a twin update
                }
            }

            return(propertiesToRemove);
        }
Beispiel #9
0
        public static JObject GetOrCreateComponent(this TwinCollection collection, string componentName)
        {
            if (collection.Contains(componentName))
            {
                var component = collection[componentName] as JObject;
                CheckComponentFlag(component, componentName);
            }
            else
            {
                JToken flag = JToken.Parse("{\"__t\" : \"c\"}");
                collection[componentName] = flag;
            }
            JObject componentJson = collection[componentName] as JObject;

            return(componentJson);
        }
Beispiel #10
0
        private static async Task UpdateDeviceProperties(TwinCollection desiredProperties)
        {
            // Set properties based on Desired Properties (from Device Twin stored in cloud)
            if (desiredProperties.Contains("sensorDataReportIntervalMinutes"))
            {
                sensorDataReportIntervalMinutes = desiredProperties["sensorDataReportIntervalMinutes"];
            }

            // Set Reported Propeeties based on actual device settings
            TwinCollection reportedProperties = new TwinCollection();

            reportedProperties["sensorDataReportIntervalMinutes"] = sensorDataReportIntervalMinutes;

            // Update Device Twin stored in the cloud
            await deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
        }
Beispiel #11
0
        static double?TryGetDesiredPropertyDouble(TwinCollection desiredProperties, string propertyName)
        {
            if (desiredProperties.Contains(propertyName))
            {
                var raw = desiredProperties[propertyName]?.ToString() ?? string.Empty;
                if (!string.IsNullOrEmpty(raw))
                {
                    if (double.TryParse(raw, out double value))
                    {
                        return(value);
                    }
                }
            }

            return(null);
        }
Beispiel #12
0
        private async Task HandleDeviceEnablement(TwinCollection desiredProperties, object userContext)
        {
            if (desiredProperties.Contains("status"))
            {
                DeviceStatus desiredStatus = (DeviceStatus)Enum.Parse(typeof(DeviceStatus), desiredProperties["status"].ToString());
                if (desiredStatus == DeviceStatus.enabled)
                {
                    // reset stock count
                    this.TicketStockCount = deviceConfig.InitialStockCount;
                    Console.WriteLine("Resetting Stock levels.");
                }
            }

            // hides compiler warning for async with no await
            await Task.Run(() => { });
        }
Beispiel #13
0
        private bool LightBulbFromTwins(TwinCollection twins)
        {
            if (twins == null || !twins.Contains(LightProperty))
            {
                return(false);
            }

            var light = twins[LightProperty];

            if (Enum.TryParse(light.Value, out TrafficLightState lightEnum))
            {
                LightBulb(lightEnum);
                return(true);
            }

            return(false);
        }
Beispiel #14
0
        /// <summary>
        /// Update Start from module Twin.
        /// </summary>
        static async Task  DoTwinUpdate(TwinCollection desiredProperties, ModuleClient ioTHubModuleClient)
        {
            string serializedStr = JsonConvert.SerializeObject(desiredProperties);

            Console.WriteLine("Updating desired properties:");
            Console.WriteLine(serializedStr);

            if (string.IsNullOrEmpty(serializedStr))
            {
                Console.WriteLine("No configuration provided for the module Twin.");
            }
            else if (!desiredProperties.Contains(DriveProfileConfig.DriveProfileConfigSection))
            {
                Console.WriteLine("No driverProfile configuration defined in Twin desired properties or local settings");
                Console.WriteLine("Configuration must contain required section " + DriveProfileConfig.DriveProfileConfigSection);
            }
            else
            {
                Console.WriteLine("Attempt to parse configuration");
                DriveProfileConfig config = JsonConvert.DeserializeObject <DriveProfileConfig>(serializedStr);


                ModuleMessageHandler moduleHandle = ModuleMessageHandler.CreateFromConfig(config);

                if (moduleHandle != null)
                {
                    var userContext = new Tuple <ModuleClient, ModuleMessageHandler>(ioTHubModuleClient, moduleHandle);
                    // Register callback to be called when a message is received by the module
                    await ioTHubModuleClient.SetInputMessageHandlerAsync(
                        "driveProfileInput",
                        PipeMessage,
                        userContext);

                    Console.WriteLine("DriverProfile module was loaded sucessfully and listining for modbus messages.");
                }
                else
                {
                    Console.WriteLine("Error creating modbus message handler. Message processing stopped.");
                }

                // Report current module config via moduleTwin
                serializedStr = JsonConvert.SerializeObject(config);
                TwinCollection reported = JsonConvert.DeserializeObject <TwinCollection>(serializedStr);
                await ioTHubModuleClient.UpdateReportedPropertiesAsync(reported);
            }
        }
        // Callback for responding to desired property changes
        static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, object userContext)
        {
            LogToConsole("Desired property changed:");
            LogToConsole($"{desiredProperties.ToJson()}");

            // Execute firmware update
            if (desiredProperties.Contains("firmware") && (desiredProperties["firmware"] != null))
            {
                // In the desired properties, we will find the following information:
                // fwVersion: the version number of the new firmware to flash
                // fwPackageURI: URI from where to download the new firmware binary
                // fwPackageCheckValue: Hash for validating the integrity of the binary  downloaded
                // We will assume the version of the firmware is a new one
                TwinCollection fwProperties = new TwinCollection(desiredProperties["firmware"].ToString());
                await UpdateFirmware((DeviceClient)userContext, fwProperties["fwVersion"].ToString(), fwProperties["fwPackageURI"].ToString(), fwProperties["fwPackageCheckValue"].ToString());
            }
        }
        // check for module twin updates. Below is a sample value check
        private async Task UpdateDesiredProperties(TwinCollection desiredproperties, object usercontext, ModuleConfig moduleConfig)
        {
            if (desiredproperties.Contains(OpcUASampleValueKey))
            {
                string value = desiredproperties[OpcUASampleValueKey].ToString();
                if (!string.IsNullOrEmpty(value))
                {
                    moduleConfig.OpcUASampleValue = value;
                }
                Console.WriteLine($"{nameof(ModuleConfig.OpcUASampleValue)}: { moduleConfig.OpcUASampleValue}");
            }

            if (usercontext is DeviceClient deviceClient)
            {
                await deviceClient.UpdateReportedPropertiesAsync(CreateTwinCollectionFromModuleConfig(moduleConfig));
            }
        }
        public void AddComponentPropAddsTheFlagIfNeeded()
        {
            TwinCollection collection = new TwinCollection();

            collection.AddComponentProperty("myComp", "myProp", 12.3);
            Assert.True(collection.Contains("myComp"));
            var comp = collection["myComp"] as JObject;

            Assert.True(comp.ContainsKey("__t"));
            Assert.True(comp.ContainsKey("myProp"));
            var prop = comp["myProp"];

            Assert.NotNull(prop);
            var propValue = prop["value"];

            Assert.Equal(12.3, propValue.Value <double>());
        }
        T GetPropertyValue <T>(TwinCollection collection, string propertyName)
        {
            T result = default(T);

            if (collection.Contains(propertyName))
            {
                var propertyJson = collection[propertyName] as JObject;
                if (propertyJson != null)
                {
                    result = propertyJson.ToObject <T>();
                }
                else
                {
                    this.logger.LogError($"Property {propertyName} not found");
                }
            }
            return(result);
        }
Beispiel #19
0
        /// <summary>
        /// Process a collection of desired device twin properties
        /// Sends back the reported properties
        /// </summary>
        /// <param name="desiredProperties"></param>
        /// <returns></returns>
        private static async Task ProcessDesiredPropertiesUpdate(TwinCollection desiredProperties, ModuleClient moduleClient)
        {
            if (desiredProperties.Contains("samplingrate") &&
                desiredProperties["samplingrate"].Type == JTokenType.Integer)
            {
                int desiredSamplingRate = desiredProperties["samplingrate"];
                // only allow values between 1ms and 60000ms (1min)
                if (desiredSamplingRate >= 1 && desiredSamplingRate <= 60000)
                {
                    Log.Information($"Setting samplingRate to {desiredSamplingRate}ms");
                    _samplingRateMs = desiredSamplingRate;
                }
            }

            _reportedProperties["samplingrate"] = _samplingRateMs;

            // Report properties back to IoT hub
            await moduleClient.UpdateReportedPropertiesAsync(_reportedProperties);
        }
Beispiel #20
0
        private void UpdateOccupantStateReportedProperties(TwinCollection desiredProperties,
            TwinCollection reportedProperties)
        {
            const string occupantState = nameof(Config.Occupant);
            try
            {
                if (desiredProperties.Contains(occupantState))
                {
                    OccupantState newOccupantState = JsonConvert.DeserializeObject<OccupantState>(desiredProperties[occupantState].ToString());
                    _alarmState.OccupantStateChanged(Config.Occupant, newOccupantState);

                    Config.Occupant = newOccupantState;
                    reportedProperties[occupantState] = Config.Occupant;
                }
            }
            catch (Exception ex)
            {
                Log.Error($"Error on UpdateState '{occupantState}'", ex);
            }
        }
Beispiel #21
0
        async Task <TwinCollection> ValidatePropertiesFromTwinAsync(Twin receivedTwin)
        {
            TwinCollection propertyUpdatesFromTwin = receivedTwin.Properties.Reported;
            Dictionary <string, DateTime> reportedPropertiesUpdated = await this.storage.GetAllReportedPropertiesUpdatedAsync();

            TwinCollection propertiesToRemoveFromTwin = new TwinCollection();

            foreach (KeyValuePair <string, DateTime> reportedPropertyUpdate in reportedPropertiesUpdated)
            {
                string status;
                if (propertyUpdatesFromTwin.Contains(reportedPropertyUpdate.Key))
                {
                    try
                    {
                        await this.storage.RemoveReportedPropertyUpdateAsync(reportedPropertyUpdate.Key);
                    }
                    catch (Exception e)
                    {
                        Logger.LogError(e, $"Failed to remove validated reported property id {reportedPropertyUpdate.Key} from storage.");
                        continue;
                    }

                    status = $"{(int)StatusCode.ValidationSuccess}: Successfully validated reported property update";
                    Logger.LogInformation(status + $" {reportedPropertyUpdate.Key}");
                }
                else if (this.ExceedFailureThreshold(this.twinState, reportedPropertyUpdate.Value))
                {
                    status = $"{(int)StatusCode.ReportedPropertyUpdateNotInCloudTwin}: Failure receiving reported property update";
                    Logger.LogInformation($"{status} for reported property update {reportedPropertyUpdate.Key}");
                }
                else
                {
                    continue;
                }

                propertiesToRemoveFromTwin[reportedPropertyUpdate.Key] = null; // will later be serialized as a twin update
                await this.HandleReportStatusAsync(status);
            }

            return(propertiesToRemoveFromTwin);
        }
        private bool checkIsAValidSFDesiredProperty(TwinCollection desiredProperties)
        {
            try
            {
                if (desiredProperties.Contains(SfTwinProperties.SF_LASTUPDATED_TIMESTAMP))
                {
                    int lastUpdatedTS = desiredProperties[SfTwinProperties.SF_LASTUPDATED_TIMESTAMP];
                    Logger.showDebug(TAG, "lastUpdatedTS: {0}".FormatInvariant(lastUpdatedTS));
                    if (lastUpdatedTS != 0)
                    {
                        return(true);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.showError(TAG, "checkIsAValidSFDesiredProperty Exception: {0}".FormatInvariant(ex.Message.ToString()));
            }

            return(false);
        }
Beispiel #23
0
        static private void Set(this TwinCollection collection, IEnumerable <string> names, dynamic value)
        {
            var name = names.First();

            if (names.Count() == 1)
            {
                // Current node is the target node, set the value
                collection[name] = value;
            }
            else if (!collection.Contains(name))
            {
                // Current node is container, go to next level
                // The target collection is not exist, create and add it
                // Reminder: the 'add' operation perform 'copy' rather than 'link'
                var newCollection = new TwinCollection();
                Set(newCollection, names.Skip(1), value);
                collection[name] = newCollection;
            }
            else
            {
                var child = collection[name];
                if (child is TwinCollection)
                {
                    // The target collection is there. Go to next level
                    Set(child as TwinCollection, names.Skip(1), value);
                }
                else if (child is JContainer)
                {
                    // The target collection is there. Go to next level
                    Set(child as JContainer, names.Skip(1), value);
                }
                else
                {
                    // Currently, the container could only be TwinCollection or JContainer
#if DEBUG
                    throw new ApplicationException(FormattableString.Invariant($"Unexpected TwinCollection item type: {child.GetType().FullName} @ ...{name}"));
#endif
                }
            }
        }
        public static T GetPropertyValue <T>(this TwinCollection collection, string propertyName)
        {
            T result = default(T);

            if (collection.Contains(propertyName))
            {
                var propertyJson = collection[propertyName] as JObject;
                if (propertyJson != null)
                {
                    if (propertyJson.ContainsKey("value"))
                    {
                        var propertyValue = propertyJson["value"];
                        result = propertyValue.Value <T>();
                    }
                }
                else
                {
                    result = collection[propertyName].Value;
                }
            }
            return(result);
        }
    private async Task DesiredPropUpdated(TwinCollection desiredProperties, object userContext)
    {
        if (DesiredPropertiesUpdated != null)
        {
            DesiredPropertiesUpdated(deviceClient, new DesiredPropertiesUpdatedEventArgs()
            {
                DesiredProperties = desiredProperties
            });
        }

        if (desiredProperties.Contains(updateIntervalCommand))
        {
            lock (this) {
                TelemetryCycleMSec = desiredProperties[updateIntervalCommand];
            }
        }
        var reportedProperties = new TwinCollection();

        reportedProperties["DateTimeLastDisredPropertyChangeReceived"] = DateTime.Now;

        await deviceClient.UpdateReportedPropertiesAsync(reportedProperties);
    }
        public static void CreateSupportedMethodReport(TwinCollection patch, IEnumerable <Command> commands, TwinCollection reported)
        {
            var existingMethods = new HashSet <string>();

            if (reported != null && reported.Contains("SupportedMethods"))
            {
                existingMethods.UnionWith(reported.AsEnumerableFlatten()
                                          .Select(pair => pair.Key)
                                          .Where(key => key.StartsWith("SupportedMethods."))
                                          .Select(key => key.Split('.')[1]));
            }

            var supportedMethods = new TwinCollection();

            foreach (var method in commands.Where(c => c.DeliveryType == DeliveryType.Method))
            {
                if (string.IsNullOrWhiteSpace(method.Name))
                {
                    continue;
                }

                if (method.Parameters.Any(p => string.IsNullOrWhiteSpace(p.Name) || string.IsNullOrWhiteSpace(p.Type)))
                {
                    continue;
                }

                var pair = method.Serialize();
                supportedMethods[pair.Key] = pair.Value;

                existingMethods.Remove(pair.Key);
            }

            foreach (var method in existingMethods)
            {
                supportedMethods[method] = null;
            }

            patch["SupportedMethods"] = supportedMethods;
        }
Beispiel #27
0
        private async Task PropertyHandler(TwinCollection desiredProperties, object userContext)
        {
            Logger.LogInformation("PropertyHandler called");

            if (!(userContext is Dictionary <string, SubscriptionCallback> callbacks))
            {
                throw new InvalidOperationException("UserContext doesn't contain a valid SubscriptionCallback");
            }

            Logger.LogInformation("Desired property change:");
            Logger.LogInformation(JsonConvert.SerializeObject(desiredProperties));

            foreach (var callback in callbacks)
            {
                if (desiredProperties.Contains($"___{callback.Key}"))
                {
                    var input = TypeTwin.CreateTwin(callback.Value.Type, callback.Key, desiredProperties);

                    var invocationResult = callback.Value.Handler.DynamicInvoke(input);
                    await(Task <TwinResult>) invocationResult;
                }
            }
        }
Beispiel #28
0
        private async Task OnDesiredPropertyChangedAsync(TwinCollection desiredProperties, object userContext)
        {
            // callback when Desired Property (settings) is changed/updated by Cloud/Backend
            Console.WriteLine("\r\nDesired property (Settings) changed:");
            Console.WriteLine($"{desiredProperties.ToJson(Newtonsoft.Json.Formatting.Indented)}");

            // IoT Central expects the following payloads in Reported Property (as a response and communicate synchronization status)
            if (desiredProperties.Contains("isCelsius") && desiredProperties["isCelsius"]["value"] != null)
            {
                _bCelsius = desiredProperties["isCelsius"]["value"];

                // update reported properties to keep UI and device state in synch
                TwinCollection twinValue = new TwinCollection();
                twinValue["value"]          = _bCelsius;
                twinValue["desiredVersion"] = desiredProperties["$version"];
                twinValue["statusCode"]     = 200;

                TwinCollection reportedProperties = new TwinCollection();
                reportedProperties["isCelsius"] = twinValue;

                await _client.UpdateReportedPropertiesAsync(reportedProperties).ConfigureAwait(false);
            }
        }
Beispiel #29
0
        public static T GetPropertyValue <T>(this TwinCollection collection, string componentName, string propertyName)
        {
            T result = default(T);

            if (collection.Contains(componentName))
            {
                var componentJson = collection[componentName] as JObject;
                CheckComponentFlag(componentJson, componentName);
                if (componentJson.ContainsKey(propertyName))
                {
                    var propertyJson = componentJson[propertyName] as JObject;
                    if (propertyJson != null)
                    {
                        if (propertyJson.ContainsKey("value"))
                        {
                            var propertyValue = propertyJson["value"];
                            result = propertyValue.Value <T>();
                        }
                    }
                }
            }
            return(result);
        }
Beispiel #30
0
        private static async Task HandleSettingChanged(TwinCollection desiredProperties, object userContext)
        {
            try
            {
                Console.WriteLine("Received settings change...");
                Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));

                string setting = "ANT";
                if (desiredProperties.Contains(setting))
                {
                    // Act on setting change, then
                    AcknowledgeSettingChange(desiredProperties, setting);
                }

                await Client.UpdateReportedPropertiesAsync(reportedProperties);
            }

            catch (Exception ex)
            {
                Console.WriteLine();
                Console.WriteLine("Error in sample: {0}", ex.Message);
            }
        }