54 lines
1.7 KiB
Rust
54 lines
1.7 KiB
Rust
//! Имитатор термометра
|
|
|
|
use rand::prelude::*;
|
|
use std::io::Read;
|
|
use std::net::{IpAddr, SocketAddr};
|
|
use std::str::FromStr;
|
|
use std::sync::Arc;
|
|
use std::time::Duration;
|
|
|
|
struct Params {
|
|
addr: SocketAddr,
|
|
interval: Duration,
|
|
}
|
|
|
|
const CONFIG_FILE: &str = "thermometer_mock.cfg";
|
|
|
|
fn read_parameters_from_file() -> Result<Params, std::io::Error> {
|
|
let mut file = std::fs::File::open(CONFIG_FILE)?;
|
|
let mut content = String::new();
|
|
file.read_to_string(&mut content)?;
|
|
let lines = content.split("\n").collect::<Vec<&str>>();
|
|
let addr = lines
|
|
.first()
|
|
.map(|v| SocketAddr::from_str(v))
|
|
.ok_or(std::io::Error::other("no address found in config file"))?
|
|
.map_err(std::io::Error::other)?;
|
|
let interval = lines
|
|
.get(1)
|
|
.map(|v| v.parse::<u64>())
|
|
.ok_or(std::io::Error::other("no interval found in config file"))?
|
|
.map(Duration::from_millis)
|
|
.map_err(std::io::Error::other)?;
|
|
Ok(Params { addr, interval })
|
|
}
|
|
|
|
fn generate_temperature() -> f32 {
|
|
rand::rng().random_range(18.0..23.0)
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let params = read_parameters_from_file()?;
|
|
let rt = tokio::runtime::Builder::new_current_thread().enable_all().build()?;
|
|
rt.block_on(async move {
|
|
let socket = Arc::new(tokio::net::UdpSocket::bind(SocketAddr::new(IpAddr::from([127, 0, 0, 1]), 10003)).await?);
|
|
let mut interval = tokio::time::interval(params.interval);
|
|
loop {
|
|
interval.tick().await;
|
|
let new_temperature = generate_temperature();
|
|
let data = new_temperature.to_le_bytes();
|
|
socket.send_to(&data, ¶ms.addr).await?;
|
|
}
|
|
})
|
|
}
|