use crate::dm::{ArrayAttributeRead, Cluster, Dataver, ReadContext};
use crate::error::{Error, ErrorCode};
use crate::im::EndptId;
use crate::tlv::{TLVBuilderParent, ToTLVArrayBuilder, ToTLVBuilder, Utf8StrBuilder};
use crate::with;
pub use crate::dm::clusters::decl::power_source::*;
pub const CLUSTER: Cluster<'static> = FULL_CLUSTER
.with_features(Feature::WIRED.bits())
.with_attrs(with!(required; AttributeId::WiredCurrentType))
.with_cmds(with!());
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PowerSourceConfig<'a> {
pub status: PowerSourceStatusEnum,
pub order: u8,
pub description: &'a str,
pub endpoint_list: &'a [EndptId],
pub wired_current_type: WiredCurrentTypeEnum,
}
impl PowerSourceConfig<'_> {
pub const MAINS: Self = Self {
status: PowerSourceStatusEnum::Active,
order: 0,
description: "Mains",
endpoint_list: &[],
wired_current_type: WiredCurrentTypeEnum::AC,
};
}
pub struct PowerSourceHandler<'a> {
dataver: Dataver,
config: &'a PowerSourceConfig<'a>,
}
impl<'a> PowerSourceHandler<'a> {
pub const fn new(dataver: Dataver, config: &'a PowerSourceConfig<'a>) -> Self {
Self { dataver, config }
}
pub const fn adapt(self) -> HandlerAdaptor<Self> {
HandlerAdaptor(self)
}
}
impl ClusterHandler for PowerSourceHandler<'_> {
const CLUSTER: Cluster<'static> = CLUSTER;
fn dataver(&self) -> u32 {
self.dataver.get()
}
fn dataver_changed(&self) {
self.dataver.changed();
}
fn status(&self, _ctx: impl ReadContext) -> Result<PowerSourceStatusEnum, Error> {
Ok(self.config.status)
}
fn order(&self, _ctx: impl ReadContext) -> Result<u8, Error> {
Ok(self.config.order)
}
fn description<P: TLVBuilderParent>(
&self,
_ctx: impl ReadContext,
out: Utf8StrBuilder<P>,
) -> Result<P, Error> {
out.set(self.config.description)
}
fn wired_current_type(&self, _ctx: impl ReadContext) -> Result<WiredCurrentTypeEnum, Error> {
Ok(self.config.wired_current_type)
}
fn endpoint_list<P: TLVBuilderParent>(
&self,
_ctx: impl ReadContext,
builder: ArrayAttributeRead<ToTLVArrayBuilder<P, EndptId>, ToTLVBuilder<P, EndptId>>,
) -> Result<P, Error> {
match builder {
ArrayAttributeRead::ReadAll(mut builder) => {
for endpoint in self.config.endpoint_list {
builder = builder.push(endpoint)?;
}
builder.end()
}
ArrayAttributeRead::ReadOne(index, builder) => {
let Some(endpoint) = self.config.endpoint_list.get(index as usize) else {
return Err(ErrorCode::ConstraintError.into());
};
builder.set(endpoint)
}
ArrayAttributeRead::ReadNone(builder) => builder.end(),
}
}
}