sdm72_lib/
tokio_async_safe_client.rs1use crate::{
32 protocol as proto,
33 tokio_async::SDM72,
34 tokio_common::{AllSettings, AllValues, Result},
35};
36use std::sync::Arc;
37use tokio::sync::Mutex;
38use tokio_modbus::{client::Context, prelude::SlaveContext};
39
40#[derive(Clone)]
42pub struct SafeClient {
43 ctx: Arc<Mutex<Context>>,
44}
45
46macro_rules! read_holding {
47 ($func_name:ident, $ty:ident) => {
48 paste::item! {
49 #[doc = "Reads the [`proto::" $ty "`] value from the Modbus holding register."]
50 pub async fn $func_name(&mut self) -> Result<proto::$ty> {
51 let mut ctx = self.ctx.lock().await;
52 SDM72::$func_name(&mut ctx).await
53 }
54 }
55 };
56}
57
58macro_rules! write_holding {
59 ($func_name:ident, $ty:ident) => {
60 paste::item! {
61 #[doc = "Writes the [`proto::" $ty "`] value to the Modbus holding register."]
62 pub async fn [< set_ $func_name >](&mut self, value: proto::$ty) -> Result<()> {
63 let mut ctx = self.ctx.lock().await;
64 SDM72::[< set_ $func_name >](&mut ctx, value).await
65 }
66 }
67 };
68}
69
70impl SafeClient {
71 pub fn new(ctx: Context) -> Self {
77 Self {
78 ctx: Arc::new(Mutex::new(ctx)),
79 }
80 }
81
82 pub fn from_shared(ctx: Arc<Mutex<Context>>) -> Self {
87 Self { ctx }
88 }
89
90 pub fn clone_shared(&self) -> Arc<Mutex<Context>> {
95 self.ctx.clone()
96 }
97
98 read_holding!(system_type, SystemType);
99 write_holding!(system_type, SystemType);
100 read_holding!(pulse_width, PulseWidth);
101 write_holding!(pulse_width, PulseWidth);
102 read_holding!(kppa, KPPA);
103
104 pub async fn set_kppa(&mut self, password: proto::Password) -> Result<()> {
108 let mut ctx = self.ctx.lock().await;
109 SDM72::set_kppa(&mut ctx, password).await
110 }
111
112 read_holding!(parity_and_stop_bit, ParityAndStopBit);
113 write_holding!(parity_and_stop_bit, ParityAndStopBit);
114 read_holding!(address, Address);
115
116 pub async fn set_address(&mut self, value: proto::Address) -> Result<()> {
117 let mut ctx = self.ctx.lock().await;
118 SDM72::set_address(&mut ctx, value).await?;
119 ctx.set_slave(tokio_modbus::Slave(*value));
120 Ok(())
121 }
122
123 read_holding!(pulse_constant, PulseConstant);
124 write_holding!(pulse_constant, PulseConstant);
125 read_holding!(password, Password);
126 write_holding!(password, Password);
127 read_holding!(baud_rate, BaudRate);
128 write_holding!(baud_rate, BaudRate);
129 read_holding!(auto_scroll_time, AutoScrollTime);
130 write_holding!(auto_scroll_time, AutoScrollTime);
131 read_holding!(backlight_time, BacklightTime);
132 write_holding!(backlight_time, BacklightTime);
133 read_holding!(pulse_energy_type, PulseEnergyType);
134 write_holding!(pulse_energy_type, PulseEnergyType);
135
136 pub async fn reset_historical_data(&mut self) -> Result<()> {
140 let mut ctx = self.ctx.lock().await;
141 SDM72::reset_historical_data(&mut ctx).await
142 }
143
144 read_holding!(serial_number, SerialNumber);
145 read_holding!(meter_code, MeterCode);
146 read_holding!(software_version, SoftwareVersion);
147
148 pub async fn read_all_settings(&mut self, delay: &std::time::Duration) -> Result<AllSettings> {
150 let mut ctx = self.ctx.lock().await;
151 SDM72::read_all_settings(&mut ctx, delay).await
152 }
153
154 pub async fn read_all(&mut self, delay: &std::time::Duration) -> Result<AllValues> {
156 let mut ctx = self.ctx.lock().await;
157 SDM72::read_all(&mut ctx, delay).await
158 }
159}