use crate::{protocol as proto, tokio_common::Result};
use tokio_modbus::prelude::{SyncReader, SyncWriter};
pub struct R413D08 {}
impl R413D08 {
fn map_tokio_result<T>(result: tokio_modbus::Result<T>) -> Result<T> {
match result {
Ok(Ok(result)) => Ok(result),
Ok(Err(err)) => Err(err.into()), Err(err) => Err(err.into()), }
}
fn read_and_decode<T, F>(
ctx: &mut tokio_modbus::client::sync::Context,
address: u16,
quantity: u16,
decoder: F,
) -> Result<T>
where
F: FnOnce(&[u16]) -> Result<T>,
{
decoder(&Self::map_tokio_result(
ctx.read_holding_registers(address, quantity),
)?)
}
pub fn read_ports(ctx: &mut tokio_modbus::client::sync::Context) -> Result<proto::PortStates> {
Self::read_and_decode(
ctx,
proto::PortStates::ADDRESS,
proto::PortStates::QUANTITY,
|words| Ok(proto::PortStates::decode_from_holding_registers(words)),
)
}
pub fn set_port_open(
ctx: &mut tokio_modbus::client::sync::Context,
port: proto::Port,
) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
port.address_for_write_register(),
proto::Port::REG_DATA_SET_PORT_OPEN,
))
}
pub fn set_all_open(ctx: &mut tokio_modbus::client::sync::Context) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
proto::PortsAll::ADDRESS,
proto::PortsAll::REG_DATA_SET_ALL_OPEN,
))
}
pub fn set_port_close(
ctx: &mut tokio_modbus::client::sync::Context,
port: proto::Port,
) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
port.address_for_write_register(),
proto::Port::REG_DATA_SET_PORT_CLOSE,
))
}
pub fn set_all_close(ctx: &mut tokio_modbus::client::sync::Context) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
proto::PortsAll::ADDRESS,
proto::PortsAll::REG_DATA_SET_ALL_CLOSE,
))
}
pub fn set_port_toggle(
ctx: &mut tokio_modbus::client::sync::Context,
port: proto::Port,
) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
port.address_for_write_register(),
proto::Port::REG_DATA_SET_PORT_TOGGLE,
))
}
pub fn set_port_latch(
ctx: &mut tokio_modbus::client::sync::Context,
port: proto::Port,
) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
port.address_for_write_register(),
proto::Port::REG_DATA_SET_PORT_LATCH,
))
}
pub fn set_port_momentary(
ctx: &mut tokio_modbus::client::sync::Context,
port: proto::Port,
) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
port.address_for_write_register(),
proto::Port::REG_DATA_SET_PORT_MOMENTARY,
))
}
pub fn set_port_delay(
ctx: &mut tokio_modbus::client::sync::Context,
port: proto::Port,
delay: u8,
) -> Result<()> {
Self::map_tokio_result(ctx.write_single_register(
port.address_for_write_register(),
proto::Port::encode_delay_for_write_register(delay),
))
}
pub fn read_address(ctx: &mut tokio_modbus::client::sync::Context) -> Result<proto::Address> {
Self::read_and_decode(
ctx,
proto::Address::ADDRESS,
proto::Address::QUANTITY,
|words| Ok(proto::Address::decode_from_holding_registers(words)?),
)
}
pub fn set_address(
ctx: &mut tokio_modbus::client::sync::Context,
address: proto::Address,
) -> Result<()> {
Self::map_tokio_result(
ctx.write_single_register(proto::Address::ADDRESS, address.encode_for_write_register()),
)
}
}