Files
rust-otus/smart-house/house/src/bin/thermometer_mock.rs
2026-04-11 10:47:12 +03:00

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, &params.addr).await?;
}
})
}