first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 22:29:38 +03:00
commit 427856cd3a
176 changed files with 27613 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
use crate::frame::{ZclFrame, ZclFrameDirection};
#[must_use]
pub fn describe(frame: &ZclFrame, _data: &[u8]) -> Option<String> {
if frame.manufacturer_specific() {
return None;
}
if frame.flags.direction != ZclFrameDirection::ClientToServer {
return None;
}
match frame.cmd {
0x00 => Some("MoveToHue".to_string()),
0x01 => Some("MoveHue".to_string()),
0x02 => Some("StepHue".to_string()),
0x03 => Some("MoveToSaturation".to_string()),
0x04 => Some("MoveSaturation".to_string()),
0x05 => Some("StepSaturation".to_string()),
0x06 => Some("MoveToHueAndSaturation".to_string()),
0x07 => Some("MoveToColor".to_string()),
0x08 => Some("MoveColor".to_string()),
0x09 => Some("StepColor".to_string()),
0x0a => Some("MoveToColorTemp".to_string()),
0x40 => Some("EnhancedMoveToHue".to_string()),
0x41 => Some("EnhancedMoveHue".to_string()),
0x42 => Some("EnhancedStepHue".to_string()),
0x43 => Some("EnhancedMoveToHueAndSaturation".to_string()),
0x44 => Some("ColorLoopSet".to_string()),
0x47 => Some("StopMoveStep".to_string()),
0x4b => Some("MoveColorTemp".to_string()),
0x4c => Some("StepColorTemp".to_string()),
_ => None,
}
}

View File

@@ -0,0 +1,20 @@
use crate::error::ZclResult;
use crate::frame::ZclFrame;
use hue::zigbee::HueEntFrame;
pub fn describe(frame: &ZclFrame, data: &[u8]) -> ZclResult<Option<String>> {
if !frame.cluster_specific() {
return Ok(None);
}
match frame.cmd {
0x00 => Ok(Some("ScanRequest".to_string())),
0x02 => {
let (data, csum) = data.split_at(data.len() - 4);
let csum = u32::from_be_bytes([csum[0], csum[1], csum[2], csum[3]]);
let hes = HueEntFrame::parse(data)?;
Ok(Some(format!("{hes:x?} [PROXY, {csum:08x}]")))
}
_ => Ok(None),
}
}

View File

@@ -0,0 +1,13 @@
use crate::frame::{ZclFrame, ZclFrameDirection};
#[must_use]
pub fn describe(frame: &ZclFrame, _data: &[u8]) -> Option<String> {
if frame.flags.direction == ZclFrameDirection::ClientToServer {
match frame.cmd {
0x40 => Some("Trigger".to_string()),
_ => None,
}
} else {
None
}
}

View File

@@ -0,0 +1,18 @@
use crate::frame::{ZclFrame, ZclFrameDirection};
#[must_use]
pub fn describe(frame: &ZclFrame, _data: &[u8]) -> Option<String> {
if frame.flags.direction == ZclFrameDirection::ClientToServer {
match frame.cmd {
0x00 => Some("Add".to_string()),
0x02 => Some("GetMembership".to_string()),
_ => None,
}
} else {
match frame.cmd {
0x00 => Some("AddResp".to_string()),
0x02 => Some("GetMembershipResp".to_string()),
_ => None,
}
}
}

View File

@@ -0,0 +1,26 @@
use packed_struct::PackedStructSlice;
use crate::error::ZclResult;
use crate::frame::ZclFrame;
use hue::zigbee::{HueEntFrame, HueEntSegmentConfig, HueEntSegmentLayout, HueEntStop};
pub fn describe(frame: &ZclFrame, data: &[u8]) -> ZclResult<Option<String>> {
if !frame.cluster_specific() {
return Ok(None);
}
match frame.cmd {
1 => Ok(Some(format!("{:x?}", HueEntFrame::parse(data)?))),
3 => Ok(Some(format!("{:x?}", HueEntStop::unpack_from_slice(data)?))),
4 => {
let res = if frame.c2s() && data.len() == 1 {
"HueEntSegmentLayoutReq".to_string()
} else {
format!("{:x?}", HueEntSegmentLayout::parse(data)?)
};
Ok(Some(res))
}
7 => Ok(Some(format!("{:x?}", HueEntSegmentConfig::parse(data)?))),
_ => Ok(None),
}
}

View File

@@ -0,0 +1,18 @@
use hue::zigbee::Flags;
use crate::error::ZclResult;
use crate::frame::ZclFrame;
pub fn describe(frame: &ZclFrame, data: &[u8]) -> ZclResult<Option<String>> {
if !frame.cluster_specific() {
return Ok(None);
}
match frame.cmd {
0x00 => {
let zflags = Flags::from_bits(u16::from(data[0]) | (u16::from(data[1]) << 8)).unwrap();
Ok(Some(format!("{:?} {}", zflags, hex::encode(&data[2..]))))
}
_ => Ok(None),
}
}

View File

@@ -0,0 +1,24 @@
use crate::frame::{ZclFrame, ZclFrameDirection};
#[must_use]
pub fn describe(frame: &ZclFrame, _data: &[u8]) -> Option<String> {
if frame.manufacturer_specific() {
return None;
}
if frame.flags.direction != ZclFrameDirection::ClientToServer {
return None;
}
match frame.cmd {
0x00 => Some("MoveToLevel".to_string()),
0x01 => Some("Move".to_string()),
0x02 => Some("Step".to_string()),
0x03 => Some("Stop".to_string()),
0x04 => Some("MoveToLevelWithOnOff".to_string()),
0x05 => Some("MoveWithOnOff".to_string()),
0x06 => Some("StepWithOnOff".to_string()),
0x07 => Some("StopWithOnOff".to_string()),
_ => None,
}
}

View File

@@ -0,0 +1,10 @@
pub mod colorctrl;
pub mod commissioning;
pub mod effects;
pub mod groups;
pub mod hue_fc01;
pub mod hue_fc03;
pub mod levelctrl;
pub mod onoff;
pub mod scenes;
pub mod standard;

View File

@@ -0,0 +1,19 @@
use crate::frame::{ZclFrame, ZclFrameDirection};
#[must_use]
pub fn describe(frame: &ZclFrame, _data: &[u8]) -> Option<String> {
if frame.manufacturer_specific() {
return None;
}
if frame.flags.direction != ZclFrameDirection::ClientToServer {
return None;
}
match frame.cmd {
0x00 => Some("Off".to_string()),
0x01 => Some("On".to_string()),
0x40 => Some("OffWithEffect".to_string()),
_ => None,
}
}

View File

@@ -0,0 +1,39 @@
#![allow(clippy::collapsible_else_if)]
use hue::zigbee::Flags;
use crate::frame::{ZclFrame, ZclFrameDirection};
#[must_use]
pub fn describe(frame: &ZclFrame, data: &[u8]) -> Option<String> {
if frame.manufacturer_specific() {
if frame.flags.direction == ZclFrameDirection::ClientToServer {
match frame.cmd {
0x02 => Some(format!(
"SetComposite {:?}",
Flags::from_bits(u16::from(data[3]) | (u16::from(data[4]) << 8)).unwrap()
)),
_ => None,
}
} else {
match frame.cmd {
0x02 => Some("SetCompositeOk".to_string()),
_ => None,
}
}
} else {
if frame.flags.direction == ZclFrameDirection::ClientToServer {
match frame.cmd {
0x02 => Some("Remove".to_string()),
0x05 => Some("Recall".to_string()),
0x06 => Some("GetMembership".to_string()),
_ => None,
}
} else {
match frame.cmd {
0x06 => Some("GetMembershipResp".to_string()),
_ => None,
}
}
}
}

View File

@@ -0,0 +1,41 @@
use packed_struct::PrimitiveEnum;
use crate::attr::{
ZclCommand, ZclReadAttr, ZclReadAttrResp, ZclReportAttr, ZclWriteAttr, ZclWriteAttrResp,
};
use crate::error::ZclResult;
use crate::frame::ZclFrame;
pub fn describe(frame: &ZclFrame, data: &[u8]) -> ZclResult<Option<String>> {
let cmd = ZclCommand::from_primitive(frame.cmd);
let desc = match cmd {
Some(ZclCommand::ReadAttrib) => {
let req = ZclReadAttr::parse(data)?;
Some(format!("Attr rd -> {:04x?}", req.attr))
}
Some(ZclCommand::ReadAttribResp) => {
let req = ZclReadAttrResp::parse(data)?;
Some(format!("Attr rd <- {:?}", req.attr))
}
Some(ZclCommand::WriteAttrib) => {
let req = ZclWriteAttr::parse(data)?;
Some(format!("Attr wr -> {:?}", req.attr))
}
Some(ZclCommand::WriteAttribResp) => {
let req = ZclWriteAttrResp::parse(data)?;
Some(format!("Attr wr <- {:02x?}", req.attr))
}
Some(ZclCommand::ReportAttrib) => {
let req = ZclReportAttr::parse(data)?;
Some(format!("Attr rp <- {:02x?}", req.attr))
}
Some(ZclCommand::DefaultResp) => {
/* let req = ZclDefaultResp::parse(data)?; */
/* format!("Attr dr <- {:02x} {:02x}", req.cmd, req.stat) */
return Ok(Some(String::new()));
}
_ => None,
};
Ok(desc)
}