#![cfg(feature = "cli")]
use anyhow::Error;
use clap::{Parser, Subcommand};
use fennec_modbus::{
contrib::mq2200,
protocol::address,
tcp::{UnitId, tokio::Client},
};
use tracing::level_filters::LevelFilter;
use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt};
type Result<T = (), E = Error> = core::result::Result<T, E>;
#[tokio::main]
async fn main() -> Result {
let args = Args::parse();
let env_filter =
EnvFilter::builder().with_default_directive(LevelFilter::WARN.into()).from_env()?;
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer().without_time().compact().with_filter(env_filter))
.init();
let client = args.endpoint.client();
let unit_id = args.unit_id;
match args.command {
Command::Test(device) => match device {
Device::Mq2200 => {
println!(
"State-of-health: {:?}",
client.call::<mq2200::ReadStateOfHealth>(unit_id, address::Const).await?
);
println!(
"Design capacity: {:?}",
client.call::<mq2200::ReadDesignCapacity>(unit_id, address::Const).await?
);
println!(
"Total active power: {:?}",
client.call::<mq2200::ReadTotalActivePower>(unit_id, address::Const).await?
);
println!(
"Total EPS active power: {:?}",
client.call::<mq2200::ReadEpsActivePower>(unit_id, address::Const).await?
);
println!(
"State-of-charge: {:?}",
client.call::<mq2200::ReadStateOfCharge>(unit_id, address::Const).await?
);
println!(
"Minimum system SoC: {:?}",
client
.call::<mq2200::ReadMinimumSystemStateOfCharge>(unit_id, address::Const)
.await?
);
println!(
"Maximum SoC: {:?}",
client
.call::<mq2200::ReadMaximumStateOfCharge>(unit_id, address::Const)
.await?
);
println!(
"Minimum SoC on grid: {:?}",
client
.call::<mq2200::ReadMinimumStateOfChargeOnGrid>(unit_id, address::Const)
.await?
);
for i in 0..mq2200::schedule::BlockIndex::MAX {
println!(
"Schedule block #{i}: {:?}",
client
.call::<mq2200::ReadScheduleEntryBlock>(
unit_id,
mq2200::schedule::BlockIndex(i)
)
.await?
);
}
}
},
}
Ok(())
}
#[derive(Parser)]
struct Args {
#[clap(flatten)]
endpoint: Endpoint,
#[clap(long = "unit-id", alias = "slave-id", env = "UNIT_ID")]
unit_id: UnitId,
#[clap(subcommand)]
command: Command,
}
#[derive(Parser)]
struct Endpoint {
#[clap(name = "ENDPOINT", env = "ENDPOINT")]
inner: String,
}
impl Endpoint {
pub fn client(self) -> Client<String> {
Client::new(self.inner)
}
}
#[derive(Copy, Clone, Subcommand)]
enum Command {
#[clap(subcommand)]
Test(Device),
}
#[derive(Copy, Clone, Subcommand)]
enum Device {
#[clap(alias = "solakon-one", alias = "avocado-22-pro")]
Mq2200,
}