示例#1
0
        // Async method to send simulated telemetry.
        private static async void SendDeviceToCloudMessagesAsync(Random rand)
        {
            // Simulate the vibration telemetry of a conveyor belt.
            double vibration;

            while (true)
            {
                // Randomly adjust belt speed.
                switch (beltSpeed)
                {
                case SpeedEnum.fast:
                    if (rand.NextDouble() < 0.01)
                    {
                        beltSpeed = SpeedEnum.stopped;
                    }
                    if (rand.NextDouble() > 0.95)
                    {
                        beltSpeed = SpeedEnum.slow;
                    }
                    break;

                case SpeedEnum.slow:
                    if (rand.NextDouble() < 0.01)
                    {
                        beltSpeed = SpeedEnum.stopped;
                    }
                    if (rand.NextDouble() > 0.95)
                    {
                        beltSpeed = SpeedEnum.fast;
                    }
                    break;

                case SpeedEnum.stopped:
                    if (rand.NextDouble() > 0.75)
                    {
                        beltSpeed = SpeedEnum.slow;
                    }
                    break;
                }

                // Set vibration levels.
                if (beltSpeed == SpeedEnum.stopped)
                {
                    // If the belt is stopped, all vibration comes to a halt.
                    forcedConstant     = 0;
                    increasingConstant = 0;
                    vibration          = 0;

                    // Record how much time the belt is stopped, in case we need to send an alert.
                    beltStoppedSeconds += intervalInSeconds;
                }
                else
                {
                    // Conveyor belt is running.
                    beltStoppedSeconds = 0;

                    // Check for random starts in unwanted vibrations.

                    // Check forced vibration.
                    if (forcedConstant == 0)
                    {
                        if (rand.NextDouble() < 0.1)
                        {
                            // Forced vibration starts.
                            forcedConstant = 1 + 6 * rand.NextDouble();             // A number between 1 and 7.
                            if (beltSpeed == SpeedEnum.slow)
                            {
                                forcedConstant /= 2;                                // Lesser vibration if slower speeds.
                            }
                            forcedSeconds = 0;
                            redMessage($"Forced vibration starting with severity: {Math.Round(forcedConstant, 2)}");
                        }
                    }
                    else
                    {
                        if (rand.NextDouble() > 0.99)
                        {
                            forcedConstant = 0;
                            greenMessage("Forced vibration stopped");
                        }
                        else
                        {
                            redMessage($"Forced vibration: {Math.Round(forcedConstant, 1)} started at: {DateTime.Now.ToShortTimeString()}");
                        }
                    }

                    // Check increasing vibration.
                    if (increasingConstant == 0)
                    {
                        if (rand.NextDouble() < 0.05)
                        {
                            // Increasing vibration starts.
                            increasingConstant = 100 + 100 * rand.NextDouble();     // A number between 100 and 200.
                            if (beltSpeed == SpeedEnum.slow)
                            {
                                increasingConstant *= 2;                            // Longer period if slower speeds.
                            }
                            increasingSeconds = 0;
                            redMessage($"Increasing vibration starting with severity: {Math.Round(increasingConstant, 2)}");
                        }
                    }
                    else
                    {
                        if (rand.NextDouble() > 0.99)
                        {
                            increasingConstant = 0;
                            greenMessage("Increasing vibration stopped");
                        }
                        else
                        {
                            redMessage($"Increasing vibration: {Math.Round(increasingConstant, 1)} started at: {DateTime.Now.ToShortTimeString()}");
                        }
                    }

                    // Apply the vibrations, starting with natural vibration.
                    vibration = naturalConstant * Math.Sin(seconds);

                    if (forcedConstant > 0)
                    {
                        // Add forced vibration.
                        vibration     += forcedConstant * Math.Sin(0.75 * forcedSeconds) * Math.Sin(10 * forcedSeconds);
                        forcedSeconds += intervalInSeconds;
                    }

                    if (increasingConstant > 0)
                    {
                        // Add increasing vibration.
                        vibration         += (increasingSeconds / increasingConstant) * Math.Sin(increasingSeconds);
                        increasingSeconds += intervalInSeconds;
                    }
                }

                // Increment the time since the conveyor belt app started.
                seconds += intervalInSeconds;

                // Count the packages that have completed their journey.
                switch (beltSpeed)
                {
                case SpeedEnum.fast:
                    packageCount += (int)(fastPackagesPerSecond * intervalInSeconds);
                    break;

                case SpeedEnum.slow:
                    packageCount += (int)(slowPackagesPerSecond * intervalInSeconds);
                    break;

                case SpeedEnum.stopped:
                    // No packages!
                    break;
                }

                // Randomly vary ambient temperature.
                temperature += rand.NextDouble() - 0.5d;

                // Create two messages:
                // 1. Vibration telemetry only, that is routed to Azure Stream Analytics.
                // 2. Logging information, that is routed to an Azure storage account.

                // Create the telemetry JSON message.
                var telemetryDataPoint = new
                {
                    vibration = Math.Round(vibration, 2),
                };
                var telemetryMessageString = JsonConvert.SerializeObject(telemetryDataPoint);
                var telemetryMessage       = new Message(Encoding.ASCII.GetBytes(telemetryMessageString));

                // Add a custom application property to the message. This is used to route the message.
                telemetryMessage.Properties.Add("sensorID", "VSTel");

                // Send an alert if the belt has been stopped for more than five seconds.
                telemetryMessage.Properties.Add("beltAlert", (beltStoppedSeconds > 5) ? "true" : "false");

                Console.WriteLine($"Telemetry data: {telemetryMessageString}");

                // Send the telemetry message.
                await s_deviceClient.SendEventAsync(telemetryMessage);

                greenMessage($"Telemetry sent {DateTime.Now.ToShortTimeString()}");

                // Create the logging JSON message.
                var loggingDataPoint = new
                {
                    vibration = Math.Round(vibration, 2),
                    packages  = packageCount,
                    speed     = beltSpeed.ToString(),
                    temp      = Math.Round(temperature, 2),
                };
                var loggingMessageString = JsonConvert.SerializeObject(loggingDataPoint);
                var loggingMessage       = new Message(Encoding.ASCII.GetBytes(loggingMessageString));

                // Add a custom application property to the message. This is used to route the message.
                loggingMessage.Properties.Add("sensorID", "VSLog");

                // Send an alert if the belt has been stopped for more than five seconds.
                loggingMessage.Properties.Add("beltAlert", (beltStoppedSeconds > 5) ? "true" : "false");

                Console.WriteLine($"Log data: {loggingMessageString}");

                // Send the logging message.
                await s_deviceClient.SendEventAsync(loggingMessage);

                greenMessage("Log data sent\n");

                await Task.Delay(intervalInMilliseconds);
            }
        }