private void UpdateNodes()

in src/Azure.IIoT.OpcUa.Publisher.Testing/src/Plc/PluginNodes/SlowFastCommon.cs [145:295]


        private void UpdateNodes(BaseDataVariableState[] nodes, NodeType type, StatusCode status, bool addBadValue)
        {
            if (nodes == null || nodes.Length == 0)
            {
                _logger.LogWarning("Invalid argument {Argument} provided.", nodes);
                return;
            }

            for (var nodeIndex = 0; nodeIndex < nodes.Length; nodeIndex++)
            {
                var extendedNode = (BaseDataVariableStateExtended)nodes[nodeIndex];

                object value = null;
                if (StatusCode.IsNotBad(status) || addBadValue)
                {
                    switch (type)
                    {
                        case NodeType.DoubleScalar:
                            var minDoubleValue = (double)extendedNode.MinValue;
                            var maxDoubleValue = (double)extendedNode.MaxValue;
                            var extendedDoubleNodeValue = (double)(extendedNode.Value ?? minDoubleValue);

                            if (extendedNode.Randomize)
                            {
                                if (minDoubleValue != maxDoubleValue)
                                {
                                    // Hybrid range case (e.g. -5.0 to 5.0).
                                    if (minDoubleValue < 0 && maxDoubleValue > 0)
                                    {
                                        // If new random value is same as previous one, generate a new one until it is not.
                                        while (value == null || extendedDoubleNodeValue == (double)value)
                                        {
                                            // Split the range from 0 on both sides.
#pragma warning disable CA5394 // Do not use insecure randomness
                                            var value1 = _random.NextDouble() * maxDoubleValue;
#pragma warning restore CA5394 // Do not use insecure randomness
#pragma warning disable CA5394 // Do not use insecure randomness
                                            var value2 = _random.NextDouble() * minDoubleValue;
#pragma warning restore CA5394 // Do not use insecure randomness

                                            // Return random value from postive or negative range, randomly.
#pragma warning disable CA5394 // Do not use insecure randomness
                                            value = _random.Next(10) % 2 == 0 ? value1 : value2;
#pragma warning restore CA5394 // Do not use insecure randomness
                                        }
                                    }
                                    else // Negative and positive only range cases (e.g. -5.0 to -8.0 or 0 to 9.5).
                                    {
                                        // If new random value is same as previous one, generate a new one until it is not.
                                        while (value == null || extendedDoubleNodeValue == (double)value)
                                        {
#pragma warning disable CA5394 // Do not use insecure randomness
                                            value = minDoubleValue + (_random.NextDouble() * (maxDoubleValue - minDoubleValue));
#pragma warning restore CA5394 // Do not use insecure randomness
                                        }
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException($"Range {minDoubleValue} to {maxDoubleValue}does not have provision for randomness.");
                                }
                            }
                            else
                            {
                                // Positive only range cases (e.g. 0 to 9.5).
                                if (minDoubleValue >= 0 && maxDoubleValue > 0)
                                {
                                    value = (extendedDoubleNodeValue % maxDoubleValue) < minDoubleValue
                                         ? minDoubleValue
                                             : ((extendedDoubleNodeValue % maxDoubleValue) + (double)extendedNode.StepSize) > maxDoubleValue
                                                 ? minDoubleValue
                                                     : ((extendedDoubleNodeValue % maxDoubleValue) + (double)extendedNode.StepSize);
                                }
                                else if (maxDoubleValue <= 0 && minDoubleValue < 0) // Negative only range cases (e.g. 0 to -9.5).
                                {
                                    value = (extendedDoubleNodeValue % minDoubleValue) > maxDoubleValue
                                    ? maxDoubleValue
                                     : ((extendedDoubleNodeValue % minDoubleValue) - (double)extendedNode.StepSize) < minDoubleValue
                                                 ? maxDoubleValue
                                                 : (extendedDoubleNodeValue % minDoubleValue) - (double)extendedNode.StepSize;
                                }
                                else
                                {
                                    // This is to prevent infinte loop while attempting to create a different random number than previous one if no range is provided.
                                    throw new ArgumentException($"Negative to positive range {minDoubleValue} to {maxDoubleValue} for sequential node values is not supported currently.");
                                }
                            }
                            break;

                        case NodeType.BoolScalar:
                            value = extendedNode.Value == null || !(bool)extendedNode.Value;
                            break;

                        case NodeType.UIntArray:
                            var arrayValue = (uint[])extendedNode.Value;
                            if (arrayValue != null)
                            {
                                for (var arrayIndex = 0; arrayIndex < arrayValue.Length; arrayIndex++)
                                {
                                    arrayValue[arrayIndex]++;
                                }
                            }
                            else
                            {
                                arrayValue = new uint[32];
                            }
                            value = arrayValue;
                            break;

                        case NodeType.UIntScalar:
                            var minUIntValue = (uint)extendedNode.MinValue;
                            var maxUIntValue = (uint)extendedNode.MaxValue;
                            var extendedUIntNodeValue = (uint)(extendedNode.Value ?? minUIntValue);

                            if (extendedNode.Randomize)
                            {
                                if (minUIntValue != maxUIntValue)
                                {
                                    // If new random value is same as previous one, generate a new one until it is not.
                                    while (value == null || extendedUIntNodeValue == (uint)value)
                                    {
                                        // uint.MaxValue + 1 cycles back to 0 which causes infinte loop here hence a check maxUIntValue == uint.MaxValue to prevent it.
#pragma warning disable CA5394 // Do not use insecure randomness
                                        value = (uint)(minUIntValue + (_random.NextDouble() * ((maxUIntValue == uint.MaxValue ? maxUIntValue : maxUIntValue + 1) - minUIntValue)));
#pragma warning restore CA5394 // Do not use insecure randomness
                                    }
                                }
                                else
                                {
                                    // This is to prevent infinte loop while attempting to create a different random number than previous one if no range is provided.
                                    throw new ArgumentException($"Range {minUIntValue} to {maxUIntValue} does not have provision for randomness.");
                                }
                            }
                            else
                            {
                                value = (extendedUIntNodeValue % maxUIntValue) < minUIntValue
                                            ? minUIntValue
                                                : ((extendedUIntNodeValue % maxUIntValue) + (uint)extendedNode.StepSize) > maxUIntValue
                                                    ? minUIntValue
                                                        : ((extendedUIntNodeValue % maxUIntValue) + (uint)extendedNode.StepSize);
                            }
                            break;
                        default:
                            throw new NotSupportedException("Node type unknown");
                    }
                }

                extendedNode.StatusCode = status;
                SetValue(extendedNode, value);
            }
        }