use crate::schema::power_supply::PowerSupply as PowerSupplySchema;
use crate::schema::power_supply_metrics::PowerSupplyMetrics;
use crate::Error;
use crate::NvBmc;
use crate::Resource;
use crate::ResourceSchema;
use nv_redfish_core::Bmc;
use nv_redfish_core::NavProperty;
use std::sync::Arc;
#[cfg(feature = "sensors")]
use crate::extract_sensor_uris;
#[cfg(feature = "sensors")]
use crate::sensor::SensorLink;
pub struct PowerSupply<B: Bmc> {
bmc: NvBmc<B>,
data: Arc<PowerSupplySchema>,
}
impl<B: Bmc> PowerSupply<B> {
pub(crate) async fn new(
bmc: &NvBmc<B>,
nav: &NavProperty<PowerSupplySchema>,
) -> Result<Self, Error<B>> {
nav.get(bmc.as_ref())
.await
.map_err(Error::Bmc)
.map(|data| Self {
bmc: bmc.clone(),
data,
})
}
#[must_use]
pub fn raw(&self) -> Arc<PowerSupplySchema> {
self.data.clone()
}
pub async fn metrics(&self) -> Result<Option<Arc<PowerSupplyMetrics>>, Error<B>> {
if let Some(metrics_ref) = &self.data.metrics {
metrics_ref
.get(self.bmc.as_ref())
.await
.map_err(Error::Bmc)
.map(Some)
} else {
Ok(None)
}
}
#[cfg(feature = "sensors")]
pub async fn metrics_sensor_links(&self) -> Result<Vec<SensorLink<B>>, Error<B>> {
let sensor_refs = if let Some(metrics_ref) = &self.data.metrics {
metrics_ref
.get(self.bmc.as_ref())
.await
.map_err(Error::Bmc)
.map(|m| {
extract_sensor_uris!(m,
single: input_voltage,
single: input_current_amps,
single: input_power_watts,
single: energyk_wh,
single: frequency_hz,
single: output_power_watts,
single: temperature_celsius,
single: fan_speed_percent,
vec: rail_voltage,
vec: rail_current_amps,
vec: rail_power_watts,
vec: fan_speeds_percent
)
})?
} else {
Vec::new()
};
Ok(sensor_refs
.into_iter()
.map(|r| SensorLink::new(&self.bmc, r))
.collect())
}
}
impl<B: Bmc> Resource for PowerSupply<B> {
fn resource_ref(&self) -> &ResourceSchema {
&self.data.as_ref().base
}
}