knx_rust/dpt/
unsigned_8.rs

1use std::fmt::{Display, Formatter};
2use crate::dpt::DPT;
3use crate::knxnet::KnxNetIpError;
4
5// Datapoint types "8 bit unsigned value" (See 3/7/2 3.5)
6
7macro_rules! impl_scaled_u16_type {
8    ($name: ident, $format: literal, $min: literal, $max: literal) => {
9        #[derive(Debug, Copy, Clone, PartialEq, Default)]
10        pub struct $name(u8);
11        impl DPT for $name{
12            fn bit_len(&self) -> u16 {
13                8
14            }
15            fn decode(&mut self, buf: &[u8]) -> Result<(), KnxNetIpError> where Self: Sized {
16                if buf.len() < 1 {
17                    return Err(KnxNetIpError::MessageTooShort(buf.len()))
18                }
19                Ok(self.0 = buf[0])
20            }
21            fn encode(&self, buf: &mut Vec<u8>) {
22                buf.push(self.0)
23            }
24        }
25
26        impl Display for $name {
27            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
28                write!(f, $format, self.as_float32())
29            }
30        }
31
32        impl $name{
33            pub fn from_bytes(buf: &[u8]) -> Result<$name, KnxNetIpError> {
34                let mut res = $name::default();
35                res.decode(buf)?;
36                Ok(res)
37            }
38            pub fn from_float32(v: f32) -> $name{
39                return $name((((v.max($min).min($max)) - $min) * 255.0 / ($max - $min)) as u8)
40            }
41            pub fn as_float32(&self) -> f32{
42                return self.0 as f32 * ($max - $min)/255.0 + $min
43            }
44        }
45    }
46}
47
48//5.001
49impl_scaled_u16_type!(DptScaling, "{:.1} %", 0.0, 100.0);
50//5.003
51impl_scaled_u16_type!(DptAngle, "{:.1} °", 0.0, 3600.0);
52//5.004
53impl_scaled_u16_type!(DptPercentU8, "{:.0} %", 0.0, 255.0);
54//5.005
55impl_scaled_u16_type!(DptDecimalFactor, "{:.0}", 0.0, 255.0);
56