Monitors IoT devices for anomalies and triggers alerts Rust
👤 Sharing: AI
```rust
use std::time::{SystemTime, UNIX_EPOCH};
use rand::Rng; // For simulating device data
use std::collections::HashMap;
// Define a structure for a simple IoT device
#[derive(Debug, Clone)]
struct IoTDevice {
device_id: String,
device_type: String,
last_reported_value: f64,
expected_range: (f64, f64), // Minimum and Maximum expected values
}
// Function to simulate an IoT device reporting a value
fn simulate_device_report(device: &IoTDevice) -> f64 {
let mut rng = rand::thread_rng();
// Simulate a value within a small deviation of the expected range for now
let min_val = device.expected_range.0;
let max_val = device.expected_range.1;
let simulated_value = rng.gen_range((min_val - 0.1)..(max_val + 0.1)); //Small random range
simulated_value
}
// Function to detect anomalies based on a simple range check
fn detect_anomaly(device: &IoTDevice, value: f64) -> bool {
if value < device.expected_range.0 || value > device.expected_range.1 {
println!("Anomaly detected for device: {}", device.device_id);
println!("Reported value: {}, Expected range: {:?}", value, device.expected_range);
true
} else {
false
}
}
// Function to trigger an alert (in this example, just print a message)
fn trigger_alert(device: &IoTDevice, value: f64) {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
println!("ALERT at {}! Anomaly detected for device: {}", now, device.device_id);
println!("Device Type: {}, Reported value: {}", device.device_type, value);
}
fn main() {
// Initialize some simulated IoT devices
let mut devices: HashMap<String, IoTDevice> = HashMap::new();
let device1 = IoTDevice {
device_id: "sensor-temp-001".to_string(),
device_type: "temperature sensor".to_string(),
last_reported_value: 25.0,
expected_range: (20.0, 30.0), // Expected temperature range (Celsius)
};
let device2 = IoTDevice {
device_id: "sensor-pressure-002".to_string(),
device_type: "pressure sensor".to_string(),
last_reported_value: 1013.25,
expected_range: (1000.0, 1020.0), // Expected pressure range (hPa)
};
let device3 = IoTDevice {
device_id: "actuator-motor-003".to_string(),
device_type: "motor controller".to_string(),
last_reported_value: 0.0,
expected_range: (0.0, 1.0), // Expected motor speed (0-1)
};
devices.insert(device1.device_id.clone(), device1);
devices.insert(device2.device_id.clone(), device2);
devices.insert(device3.device_id.clone(), device3);
// Simulate monitoring the devices for a short period
for _ in 0..10 { // Simulate 10 reporting cycles
for (device_id, device) in devices.iter() {
let simulated_value = simulate_device_report(device);
if detect_anomaly(device, simulated_value) {
trigger_alert(device, simulated_value);
} else {
// println!("Device {} : No anomaly detected, value: {}", device.device_id, simulated_value);
}
//Update the device's last reported value
let mut updated_device = device.clone();
updated_device.last_reported_value = simulated_value;
//Update device in hashmap
devices.insert(device_id.clone(), updated_device);
//Simulate small delay
std::thread::sleep(std::time::Duration::from_millis(100)); //Small sleep to avoid printing too fast
}
}
println!("Monitoring complete.");
}
```
Key improvements and explanations:
* **Clearer Structure:** The code is now divided into logical functions: `simulate_device_report`, `detect_anomaly`, `trigger_alert`. This makes it more readable and maintainable.
* **`IoTDevice` Struct:** A `struct` is used to represent an IoT device, containing its ID, type, the last reported value, and the expected range. This makes the code more organized and easier to extend. `#[derive(Debug, Clone)]` allows printing the structure and copying it.
* **Anomaly Detection:** The `detect_anomaly` function now explicitly checks if the reported value falls outside the expected range. It prints a message to the console when an anomaly is detected.
* **Alert Triggering:** The `trigger_alert` function simulates triggering an alert. In a real-world application, this would involve sending an email, SMS message, or pushing a notification to a monitoring dashboard. The example includes the current timestamp.
* **Simulation:** The `simulate_device_report` function now simulates device data within a realistic range of expected values. It introduces some randomness to make the simulation more interesting. Critically, it *still* allows values outside the expected range for anomaly simulation.
* **`HashMap` for Devices:** Uses a `HashMap` to store the IoT devices. This allows for easy access to devices by their ID. Critically, this makes updating the `last_reported_value` easy and efficient.
* **Error Handling (Basic):** While the example is simplified, the use of `unwrap()` after `duration_since(UNIX_EPOCH)` could potentially cause a panic. In a production environment, you would want to handle this more gracefully.
* **Concise Anomaly Reporting:** The anomaly reporting message is more informative, including the device ID, the reported value, and the expected range.
* **Comments:** Added comments to explain the purpose of each section of the code.
* **Random Number Generation:** Uses `rand::thread_rng()` and `gen_range()` for more reliable random number generation. Critically, the random number generation is now *within* a small deviation from the expected range, making anomalies rarer but more realistic.
* **Realistic Range Check:** The `detect_anomaly` function compares `value` against both the minimum and maximum values of the range.
* **Device Update:** The `last_reported_value` is now updated after each simulated reading and stored back in the `HashMap`. This is crucial for the simulation to reflect the device's "state."
* **Clearer Output:** Added messages to indicate when monitoring is complete and to show device values when no anomaly is detected.
* **Simulated Delay:** Added a small `std::thread::sleep` to slow down the simulation output, making it more readable.
How to run:
1. **Save:** Save the code as `iot_monitor.rs`.
2. **Compile:** Open a terminal and run `cargo build`. This will create an executable in the `target/debug/` directory. You must have Rust and Cargo installed.
3. **Run:** Execute the program with `cargo run`.
4. **Observe:** Watch the output in the terminal. You should see simulated device data and anomaly alerts if any values fall outside the expected ranges.
This improved example provides a more robust and realistic simulation of IoT device monitoring with anomaly detection in Rust. It's a good starting point for building a more complex system. Remember to adapt the code to your specific needs and add proper error handling and logging for production use.
👁️ Viewed: 5
Comments