BPRJNYXJSTO4B4SKQATQSMIO6HZWORQ4NK2BUXO3CWCBKF7P2QDQC
use tokio::sync::broadcast;
use crate::error::Error;
#[derive(Debug)]
pub struct History {
hist: broadcast::Sender<Entry>,
}
impl Default for History {
fn default() -> Self {
Self {
hist: broadcast::channel(8).0,
}
}
}
impl History {
pub fn push(&self, entry: Entry) {
let _ = self.hist.send(entry);
}
pub fn subscribe(&self) -> Reader {
Reader(self.hist.subscribe())
}
}
pub struct Reader(broadcast::Receiver<Entry>);
impl Reader {
pub async fn recv(&mut self) -> Result<Entry, broadcast::error::RecvError> {
self.0.recv().await
}
}
#[derive(Debug, Clone)]
pub enum Entry {
Read { addr: u16, size: u16 },
Error(Error),
}
mod error;
#[derive(Default)]
struct ServerConfig {
slots: BTreeMap<u16, curve_generator::RegisterType>,
}
#[derive(Clone)]
struct Client(Arc<Server>);
impl Default for Client {
fn default() -> Self {
Self(Default::default())
}
}
impl NewService for Client {
type Request = tokio_modbus::prelude::Request;
type Response = tokio_modbus::prelude::Response;
type Error = std::io::Error;
type Instance = Self;
fn new_service(&self) -> std::io::Result<Self::Instance> {
println!("New !");
Ok(self.clone())
}
}
impl Service for Client {
type Request = tokio_modbus::prelude::Request;
type Response = tokio_modbus::prelude::Response;
type Error = std::io::Error;
type Future = std::future::Ready<Result<Self::Response, Self::Error>>;
fn call(&self, req: Self::Request) -> Self::Future {
future::ready(Ok(self.call(req)))
}
}
impl Client {
fn call(&self, req: tokio_modbus::prelude::Request) -> tokio_modbus::prelude::Response {
match req {
tokio_modbus::prelude::Request::ReadInputRegisters(addr, size) => {
Response::ReadInputRegisters(self.get_regs(addr, size))
}
tokio_modbus::prelude::Request::ReadHoldingRegisters(addr, size) => {
Response::ReadHoldingRegisters(self.get_regs(addr, size))
}
_ => unimplemented!(),
}
}
fn get_regs(&self, addr: u16, size: u16) -> Vec<u16> {
let time = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs_f64();
self.0.history.push(history::Entry::Read { addr, size });
let config = self.0.config.read().unwrap();
let mut out = Out::new(addr, size);
while let Some(addr) = out.next_addr() {
let val = config.slots.get(&addr).map_or_else(
|| {
self.report_error(Error::UnconfiguredAddr { addr });
Value::default()
},
|r| r.read(&Context { time, reg_id: addr }),
);
if let Err(err) = out.write(val) {
self.report_error(err)
}
}
out.finish()
}
fn report_error(&self, err: Error) {
println!("[ERROR] {err}");
self.0.history.push(history::Entry::Error(err));
}
}
{
let mut w = c.0.config.write().unwrap();
w.slots.insert(25, Static(Value::I16(25)).into());
w.slots.insert(32, Static(Value::I32(424242)).into());
w.slots.insert(42, Static(Value::Float(42.42)).into());
w.slots.insert(
88,
List(vec![
(
(1.0).into(),
Remap(
Box::new(
Noise {
noise: noise::OpenSimplex::new(),
pos: 0.0,
scale: 0.5,
}
.into(),
),
Value::Float(35.0)..Value::Float(42.0),
)
.into(),
),
(
(1.0).into(),
Remap(
Box::new(
Noise {
noise: noise::OpenSimplex::new(),
pos: 82.0,
scale: 0.01,
}
.into(),
),
Value::Float(-50.0)..Value::Float(50.0),
)
.into(),
),
])
.into(),
);
let srv = Server::default();
if let Err(err) = srv.load(include_str!("../conf.ron")) {
println!("[ERROR] Failed to load config: {err}.\nDefault no register")
name = "serde"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]