Skip to main content

figments_render/
power.rs

1use figments::liber8tion::interpolate::Fract8;
2use rgb::{Grb, Rgb, Bgr};
3
4
5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
6pub struct Milliwatts(pub u32);
7
8pub trait AsMilliwatts {
9    fn as_milliwatts(&self) -> u32;
10}
11
12impl<T: Copy> AsMilliwatts for Bgr<T> where Rgb<T>: AsMilliwatts {
13    fn as_milliwatts(&self) -> u32 {
14        Rgb::new(self.r, self.g, self.b).as_milliwatts()
15    }
16}
17
18impl<T: Copy> AsMilliwatts for Grb<T> where Rgb<T>: AsMilliwatts {
19    fn as_milliwatts(&self) -> u32 {
20        Rgb::new(self.r, self.g, self.b).as_milliwatts()
21    }
22}
23
24// FIXME: Values are calculated based on the WS2812B chip; the AsMilliwatts trait could probably be parameterized to support other 
25impl<T: Into<u32> + Copy> AsMilliwatts for Rgb<T> {
26    fn as_milliwatts(&self) -> u32 {
27        const RED_MW : u32   = 16 * 5; //< 16mA @ 5v = 80mW
28        const GREEN_MW : u32 = 11 * 5; //< 11mA @ 5v = 55mW
29        const BLUE_MW : u32  = 15 * 5; //< 15mA @ 5v = 75mW
30        const DARK_MW : u32  =      5; //<  1mA @ 5v =  5mW
31
32        let red = (self.r.into() * RED_MW).wrapping_shr(8);
33        let green = (self.g.into() * GREEN_MW).wrapping_shr(8);
34        let blue = (self.b.into() * BLUE_MW).wrapping_shr(8);
35
36        red + green + blue + DARK_MW
37    }
38}
39
40impl<T> AsMilliwatts for [T] where T: AsMilliwatts {
41    fn as_milliwatts(&self) -> u32 {
42        self.iter().map(|p| { p.as_milliwatts() }).sum()
43    }
44}
45
46impl<T, const S: usize> AsMilliwatts for [T; S] where T: AsMilliwatts {
47    fn as_milliwatts(&self) -> u32 {
48        self.iter().map(|p| { p.as_milliwatts() }).sum()
49    }
50}
51
52pub fn brightness_for_mw(total_mw: u32, target: Fract8, max_power: Milliwatts) -> Fract8 {
53    let target32 = target.to_raw() as u32;
54    let requested_mw = (total_mw * target32) / 256;
55
56    if requested_mw > max_power.0 {
57        Fract8::from_raw(((target32 * max_power.0) / requested_mw) as u8)
58    } else {
59        target
60    }
61}