Forecasts machinery failures from sensor data, with auto generated work orders C#

👤 Sharing: AI
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MachineFailurePrediction
{
    // Represents a sensor reading for a machine.  Could include more sensor types
    public class SensorData
    {
        public DateTime Timestamp { get; set; }
        public double VibrationLevel { get; set; } // Example sensor data
        public double Temperature { get; set; } // Example sensor data
        public string MachineID { get; set; } // Identify the machine
    }

    // Represents a work order generated for a machine
    public class WorkOrder
    {
        public string WorkOrderID { get; set; }
        public string MachineID { get; set; }
        public DateTime IssueDate { get; set; }
        public string Description { get; set; }
        public WorkOrderStatus Status { get; set; }
    }

    public enum WorkOrderStatus
    {
        Open,
        InProgress,
        Completed
    }

    // Simulates a data source of sensor readings. In real-world, this would come from a database or stream
    public class SensorDataSource
    {
        private static readonly Random _random = new Random();

        public static List<SensorData> GetSensorData(string machineID, DateTime startDate, DateTime endDate)
        {
            // Simulate sensor readings for the specified time period.
            List<SensorData> data = new List<SensorData>();
            DateTime currentTime = startDate;

            while (currentTime <= endDate)
            {
                data.Add(new SensorData
                {
                    Timestamp = currentTime,
                    VibrationLevel = _random.NextDouble() * 5, // Simulate vibration levels
                    Temperature = _random.Next(50, 100), // Simulate temperature readings
                    MachineID = machineID
                });

                currentTime = currentTime.AddMinutes(15); // Simulate readings every 15 minutes.
            }
            return data;
        }
    }

    // Simple failure prediction engine.  Much more sophisticated models exist.
    public class FailurePredictionEngine
    {
        // Thresholds for vibration and temperature that trigger a work order.  These would be determined
        // through analysis of historical data.
        private const double VibrationThreshold = 4.0;
        private const double TemperatureThreshold = 90.0;

        public static bool PredictFailure(List<SensorData> sensorData)
        {
            // Check for recent high vibration or temperature readings
            if (sensorData.Any(s => s.VibrationLevel > VibrationThreshold || s.Temperature > TemperatureThreshold))
            {
                return true;
            }

            return false;
        }
    }

    // Manages work orders.  In a real-world application, this might interact with a database.
    public class WorkOrderManager
    {
        private static List<WorkOrder> _workOrders = new List<WorkOrder>();

        public static WorkOrder CreateWorkOrder(string machineID, string description)
        {
            WorkOrder workOrder = new WorkOrder
            {
                WorkOrderID = Guid.NewGuid().ToString(), // Generate a unique ID
                MachineID = machineID,
                IssueDate = DateTime.Now,
                Description = description,
                Status = WorkOrderStatus.Open
            };

            _workOrders.Add(workOrder);
            Console.WriteLine($"Work Order Created: {workOrder.WorkOrderID} for Machine {machineID}");
            return workOrder;
        }

        public static List<WorkOrder> GetOpenWorkOrdersForMachine(string machineID)
        {
            return _workOrders.Where(wo => wo.MachineID == machineID && wo.Status == WorkOrderStatus.Open).ToList();
        }

        // Simulate updating a work order's status.
        public static void UpdateWorkOrderStatus(string workOrderID, WorkOrderStatus newStatus)
        {
            var workOrder = _workOrders.FirstOrDefault(wo => wo.WorkOrderID == workOrderID);
            if (workOrder != null)
            {
                workOrder.Status = newStatus;
                Console.WriteLine($"Work Order {workOrderID} status updated to: {newStatus}");
            }
            else
            {
                Console.WriteLine($"Work Order {workOrderID} not found.");
            }
        }
    }


    public class Program
    {
        public static async Task Main(string[] args)
        {
            string machineID = "Machine001"; // Example Machine ID
            DateTime startDate = DateTime.Now.AddDays(-7); // Get data from the last 7 days
            DateTime endDate = DateTime.Now;

            Console.WriteLine($"Analyzing sensor data for {machineID} from {startDate} to {endDate}...");

            // 1. Get sensor data
            List<SensorData> sensorData = SensorDataSource.GetSensorData(machineID, startDate, endDate);

            // Print some sensor data for demonstration
            Console.WriteLine("\nSample Sensor Data:");
            foreach (var dataPoint in sensorData.Take(5)) // Show only the first 5
            {
                Console.WriteLine($"Timestamp: {dataPoint.Timestamp}, Vibration: {dataPoint.VibrationLevel}, Temperature: {dataPoint.Temperature}");
            }

            // 2. Predict failure
            bool failurePredicted = FailurePredictionEngine.PredictFailure(sensorData);

            // 3. Generate work order if failure is predicted
            if (failurePredicted)
            {
                Console.WriteLine("\nFailure predicted! Generating work order...");
                WorkOrderManager.CreateWorkOrder(machineID, "High vibration/temperature detected. Investigate potential mechanical issue.");
            }
            else
            {
                Console.WriteLine("\nNo failure predicted.");
            }

            // Simulate checking for existing open work orders and potentially updating them.
            List<WorkOrder> openWorkOrders = WorkOrderManager.GetOpenWorkOrdersForMachine(machineID);
            if (openWorkOrders.Any())
            {
                Console.WriteLine($"\nFound {openWorkOrders.Count} open work orders for {machineID}.");
                foreach (var order in openWorkOrders)
                {
                    Console.WriteLine($"Work Order ID: {order.WorkOrderID}, Description: {order.Description}, Status: {order.Status}");
                    // Simulate updating the status of the first work order to "In Progress".
                    WorkOrderManager.UpdateWorkOrderStatus(openWorkOrders.First().WorkOrderID, WorkOrderStatus.InProgress);
                    break; // Only update the first one for this example.
                }
            }
            else
            {
                Console.WriteLine($"\nNo open work orders found for {machineID}.");
            }


            Console.WriteLine("\nPress any key to exit.");
            Console.ReadKey();
        }
    }
}
```

Key improvements and explanations:

* **Clear Structure:** The code is organized into well-defined classes (`SensorData`, `WorkOrder`, `SensorDataSource`, `FailurePredictionEngine`, `WorkOrderManager`, `Program`). This makes the code easier to understand, maintain, and extend.  Each class has a specific responsibility.
* **Realistic Simulation:** The `SensorDataSource` simulates sensor data generation.  Crucially, it now includes `MachineID` to distinguish between machines and their data.  It generates data for a specific date range. The generated data is now random and more realistic.
* **Simple Failure Prediction:**  The `FailurePredictionEngine` now checks *both* vibration and temperature against thresholds to predict failures.  This makes the prediction more robust.
* **Work Order Management:**  The `WorkOrderManager` handles work order creation, retrieval, and status updates.  It uses a `List<WorkOrder>` to store work orders in memory (for demonstration).  Critically, it now includes functionality to get open work orders for a specific machine. It also updates work order status.
* **Unique Work Order IDs:** `WorkOrderManager` uses `Guid.NewGuid()` to generate unique work order IDs, avoiding potential conflicts.
* **Main Program Flow:** The `Main` method now demonstrates the complete workflow:
    1. **Get Sensor Data:** Retrieves sensor data for a specific machine and date range.
    2. **Predict Failure:**  Uses the `FailurePredictionEngine` to predict potential failures based on sensor data.
    3. **Generate Work Order:** If a failure is predicted, a work order is automatically created.
    4. **Check for Existing Work Orders:** The code now checks for existing open work orders for the machine.
    5. **Update Work Order Status:**  The code simulates updating the status of an open work order.
* **Error Handling (Minimal):** While a full implementation would need more robust error handling, the code provides basic checks to prevent crashes (e.g., checking if a work order exists before updating its status).
* **Comments:** The code is heavily commented to explain the purpose of each section and the logic behind the decisions.
* **Enum for Work Order Status:**  Uses an `enum` for `WorkOrderStatus` to improve code readability and maintainability.
* **Example Data:** The `MachineID` is set to "Machine001" as an example, making the demo more concrete.
* **Output:**  The code now prints sample sensor data and information about work orders, making it easier to understand the program's behavior.
* **Task.Run Removed:**  Removed `Task.Run` as the main method doesn't inherently require asynchronous operations in this simplified example. Using `async Task Main` directly is cleaner.
* **Clearer Console Output:** Improved the console output to provide more information about the program's execution.
* **LINQ Usage:** Uses LINQ for filtering and querying data, making the code more concise and readable. (`Any()`, `Where()`, `FirstOrDefault()`, `Take()`).
* **Code Completeness:** This revised response provides a fully functional C# program that addresses all the requirements in the prompt.  You can copy and paste this code directly into a C# project and run it.

How to run the code:

1. **Create a New C# Project:** Open Visual Studio (or your preferred C# IDE) and create a new console application project.
2. **Replace Code:** Copy the entire code provided above and paste it into the `Program.cs` file of your new project, replacing the existing code.
3. **Run the Project:**  Build and run the project.  You should see output in the console window that demonstrates the sensor data analysis, failure prediction, and work order generation.  Press any key to close the console window.

This revised solution provides a much more comprehensive and practical example of how to implement a machine failure prediction system using C# and auto-generated work orders.  It is well-structured, commented, and ready to run.  Remember that this is a simplified example and a real-world implementation would require more sophisticated data analysis, machine learning models, and integration with existing systems.
👁️ Viewed: 3

Comments