Files
rust_bifrost/examples/hz-parse.rs
Beyhan Oğur 427856cd3a first commit
2026-04-26 22:29:38 +03:00

114 lines
3.1 KiB
Rust

#![allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
use std::io::{BufRead, Cursor, stdin};
use itertools::Itertools;
use log::warn;
use packed_struct::PrimitiveEnumDynamicStr;
use hue::zigbee::{Flags, GradientColors, HueZigbeeUpdate};
use bifrost::error::ApiResult;
#[allow(clippy::format_push_string)]
#[must_use]
pub fn present_gradcolors(grad: &GradientColors) -> String {
let mut res = format!(
"{}-{}-{}-{:<9}",
grad.header.nlights,
grad.header.resv0,
grad.header.resv2,
grad.header.style.to_display_str(),
);
for p in &grad.points {
let x = (p.x * 1000.0) as u32;
let y = (p.y * 1000.0) as u32;
res += &format!(" {x:03}.{y:03}");
}
res
}
fn show(data: &[u8]) -> ApiResult<()> {
let flags = Flags::from_bits(u16::from(data[0]) | (u16::from(data[1]) << 8)).unwrap();
let mut cur = Cursor::new(data);
let hz = HueZigbeeUpdate::from_reader(&mut cur)?;
let desc = format!(
" {:04x} : {:2} : {:2} : {:4} : {:11} : {:<10} : {:2} : {:<55} : {:4} : {:4} ",
flags.bits(),
hz.onoff.map(|x| format!("{x:02x}")).unwrap_or_default(),
hz.brightness
.map(|x| format!("{x:02x}"))
.unwrap_or_default(),
hz.color_mirek
.map(|x| format!("{x:04x}"))
.unwrap_or_default(),
hz.color_xy
.map(|xy| { format!("{:.3},{:.3}", xy.x, xy.y) })
.unwrap_or_default(),
hz.effect_type
.map(|x| x.to_display_str())
.unwrap_or_default(),
hz.effect_speed
.map(|x| format!("{x:02x}"))
.unwrap_or_default(),
hz.gradient_colors
.as_ref()
.map(present_gradcolors)
.unwrap_or_default(),
hz.gradient_params
.map(|gt| format!("{:02x}{:02x}", gt.scale, gt.offset))
.unwrap_or_default(),
hz.fade_speed
.map(|x| format!("{x:04x}"))
.unwrap_or_default(),
);
println!(
"|{desc}| {} {}",
hex::encode(cur.fill_buf()?),
flags.iter_names().map(|(name, _)| name).join(" | ")
);
Ok(())
}
fn check(orig: &[u8]) -> ApiResult<()> {
let mut cur = Cursor::new(orig);
let hz = HueZigbeeUpdate::from_reader(&mut cur)?;
let mut dest = Cursor::new(vec![]);
hz.serialize(&mut dest)?;
let data = dest.into_inner();
if orig != data {
warn!("DIFF:");
warn!(" {} before", hex::encode(orig));
warn!(" {} after", hex::encode(&data));
}
Ok(())
}
fn main() -> ApiResult<()> {
pretty_env_logger::formatted_builder()
.filter_level(log::LevelFilter::Debug)
.parse_default_env()
.init();
eprintln!(
"| flag | on | br | mrek | (colx,coly) | effect ty. | es | gradient data | grad | fade |"
);
for line in stdin().lines() {
let line = line?;
let data = hex::decode(&line)?;
println!("==================== {line:<40}");
show(&data)?;
check(&data)?;
}
Ok(())
}