Skip to content

Commit

Permalink
Implement JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
williamdes committed May 5, 2024
1 parent 532d286 commit da450a0
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 9 deletions.
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,5 @@ clap = { version = "4.3", features = [ "derive" ]}
log = "0.4"
binary-layout = "4.0.2"
chrono = "0.4.38"
serde = { version = "1.0.200", default-features = false, features = ["derive"] }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,40 @@ The original C code can be found here: [ipmitool 1.8.19](https://github.com/ipmi

Special thanks to the library [ipmi-rs](https://github.com/datdenkikniet/ipmi-rs) that made this possible.

## Use

```text
A tool to fetch the power reading with ipmi dcmi
Usage: ipmitool-dcmi-power-reading [OPTIONS]
Options:
-c, --connection-uri <CONNECTION_URI>
The connection URI to use [default: file:///dev/ipmi0]
--timeout-ms <TIMEOUT_MS>
How many milliseconds to wait before timing out while waiting for a response [default: 2000]
--format <FORMAT>
The format to output [default: text] [possible values: text, json]
-h, --help
Print help
-V, --version
Print version
```

## Example (text)

```text
Instantaneous power reading : 214 Watts
Instantaneous power reading : 212 Watts
Minimum during sampling period : 2 Watts
Maximum during sampling period : 468 Watts
Average power reading over sample period : 184 Watts
IPMI timestamp : 2024-05-05 13:06:44 UTC
IPMI timestamp : 2024-05-05 14:17:17 UTC
Sampling period : 1000 Milliseconds
Power reading state is : activated
```

## TODO
## Example (json)

- [ ] Document options on the README
- [ ] Add JSON support
```json
{"grp_id":220,"curr_pwr":209,"min_sample":2,"max_sample":468,"avg_pwr":184,"time_stamp":1714918638,"sample":1000,"state":64}
```
16 changes: 14 additions & 2 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clap::{Args, Parser};
use clap::{Args, Parser, ValueEnum};
use ipmi_rs::{
connection::{
rmcp::{Active, Rmcp},
Expand All @@ -18,11 +18,17 @@ pub enum IpmiConnectionEnum {
}

#[derive(Parser)]
pub struct CliOpts {
struct CliOpts {
#[clap(flatten)]
pub common: CommonOpts,
}

#[derive(ValueEnum, Clone, Copy)]
pub enum OutputFormats {
Text,
Json,
}

#[derive(Args)]
pub struct CommonOpts {
/// The connection URI to use
Expand All @@ -31,6 +37,9 @@ pub struct CommonOpts {
/// How many milliseconds to wait before timing out while waiting for a response
#[clap(default_value = "2000", long)]
timeout_ms: u64,
/// The format to output
#[clap(default_value = "text", value_enum, long)]
format: OutputFormats,
}

fn error<T>(val: T) -> std::io::Error
Expand All @@ -41,6 +50,9 @@ where
}

impl CommonOpts {
pub fn get_format(&self) -> OutputFormats {
self.format
}
pub fn get_connection(&self) -> std::io::Result<IpmiConnectionEnum> {
let timeout = Duration::from_millis(self.timeout_ms);

Expand Down
18 changes: 16 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ use std::io::Error;
use binary_layout::binary_layout;
use chrono::{TimeZone, Utc};
use clap::Parser;
use common::{CommonOpts, IpmiConnectionEnum};
use common::{CommonOpts, IpmiConnectionEnum, OutputFormats};
use ipmi_rs::connection::{IpmiConnection, LogicalUnit, Message, NetFn, Request};
use serde::{Deserialize, Serialize};

mod common;

#[derive(Parser)]
#[clap(name = "ipmitool-dcmi-power-reading")]
#[clap(about = "A tool to fetch the power reading with ipmi dcmi")]
#[clap(author = "William Desportes <[email protected]>")]
#[clap(version = "1.0.0")]
struct Command {
#[clap(flatten)]
common: CommonOpts,
Expand All @@ -34,7 +39,9 @@ fn get_message() -> std::io::Result<Message> {
))
}

#[derive(Serialize, Deserialize)]
pub struct PowerConsumption {
#[allow(dead_code)]
grp_id: u8, /* first byte: Group Extension ID */
curr_pwr: u16,
min_sample: u16,
Expand Down Expand Up @@ -134,6 +141,10 @@ pub fn ipmi_dcmi_pwr_format_text(pwr: PowerConsumption) {
println!("");
}

pub fn ipmi_dcmi_pwr_format_json(pwr: PowerConsumption) {
print!("{}", serde_json::to_string(&pwr).unwrap());
}

fn main() -> std::io::Result<()> {
pretty_env_logger::formatted_builder()
.parse_filters(&std::env::var("RUST_LOG").unwrap_or("info".to_string()))
Expand All @@ -142,7 +153,10 @@ fn main() -> std::io::Result<()> {
let command = Command::parse();
let ipmi = command.common.get_connection()?;
match ipmi_dcmi_pwr_rd(ipmi) {
Ok(data) => Ok(ipmi_dcmi_pwr_format_text(data)),
Ok(data) => match command.common.get_format() {
OutputFormats::Json => Ok(ipmi_dcmi_pwr_format_json(data)),
OutputFormats::Text => Ok(ipmi_dcmi_pwr_format_text(data)),
},
Err(err) => Err(err),
}
}

0 comments on commit da450a0

Please sign in to comment.