From 5585acbe384e67ed90176732f51c186b98de4b71 Mon Sep 17 00:00:00 2001 From: SusieeTheFemboy <96988330+SusieeTheLinuxUser@users.noreply.github.com> Date: Sat, 7 Nov 2026 07:40:41 +0100 Subject: [PATCH 1/2] fix(kraken): find Kraken Z sensors, fix bucket overlap check, decode GIFs lazily --- src/kraken.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/kraken.rs b/src/kraken.rs index 817a66d..e8ef51a 100644 --- a/src/kraken.rs +++ b/src/kraken.rs @@ -121,12 +121,14 @@ impl Kraken { use image::AnimationDecoder; use image::codecs::gif::{GifDecoder, GifEncoder, Repeat}; let file = std::io::BufReader::new(std::fs::File::open(path)?); - let frames = GifDecoder::new(file)?.into_frames().collect_frames()?; + // Decode one frame at a time so a huge GIF can't be pulled into RAM whole. + let frames = GifDecoder::new(file)?.into_frames(); let mut out = Vec::new(); { let mut enc = GifEncoder::new_with_speed(&mut out, 10); enc.set_repeat(Repeat::Infinite)?; for f in frames { + let f = f?; let delay = f.delay(); let img = self.prepare(f.into_buffer(), angle); enc.encode_frame(image::Frame::from_parts(img, 0, 0, delay))?; @@ -256,7 +258,7 @@ fn memory_offset(buckets: &[[u8; REPORT]], index: usize, pages: usize) -> Option max_used = max_used.max(end); min_used = min_used.min(start); if (start > cur_off && start < cur_off + pages) - || (start < cur_off && end > start) + || (start < cur_off && end > cur_off) || (start == cur_off && i != index) { overlap = true; @@ -277,7 +279,10 @@ fn memory_offset(buckets: &[[u8; REPORT]], index: usize, pages: usize) -> Option /// Liquid/pump/fan from the nzxt-kraken3 kernel driver (no USB traffic). #[cfg(target_os = "linux")] pub fn status() -> Result { - let dir = crate::hwmon("kraken").context("nzxt-kraken3 kernel driver not loaded")?; + let dir = crate::hwmon("kraken") + .or_else(|| crate::hwmon("z53")) + .or_else(|| crate::hwmon("x53")) + .context("nzxt-kraken3 kernel driver not loaded")?; let read = |f: &str| -> f32 { std::fs::read_to_string(dir.join(f)).ok().and_then(|s| s.trim().parse().ok()).unwrap_or(0.0) }; From 5c09f6af352f836ce6f4c3ffbeb4bf2cccd8b4d9 Mon Sep 17 00:00:00 2001 From: SusieeTheFemboy <96988330+SusieeTheLinuxUser@users.noreply.github.com> Date: Sat, 7 Nov 2026 07:46:21 +0100 Subject: [PATCH 2/2] fix(kraken): only reuse a slot when the upload fits in LCD memory Add tests for the overlap fix and the memory bound. Co-Authored-By: Claude Opus 5.5 --- src/kraken.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/kraken.rs b/src/kraken.rs index e8ef51a..a5a618c 100644 --- a/src/kraken.rs +++ b/src/kraken.rs @@ -264,7 +264,7 @@ fn memory_offset(buckets: &[[u8; REPORT]], index: usize, pages: usize) -> Option overlap = true; } } - if !overlap { + if !overlap && cur_off + pages <= LCD_TOTAL_MEMORY { return Some([cur[17], cur[18]]); } if max_used + pages < LCD_TOTAL_MEMORY { @@ -321,5 +321,13 @@ mod tests { // memory full: None (caller wipes all buckets) b[4] = bucket(7000, 17000); assert_eq!(memory_offset(&b, 2, 3000), None); + // a bucket below that ends before ours is not an overlap: reuse the slot + let mut c = empty.clone(); + c[0] = bucket(0, 1000); + c[2] = bucket(5000, 100); + assert_eq!(memory_offset(&c, 2, 1600), Some(5000u16.to_le_bytes())); + // ...unless the upload would run past the end of LCD memory + c[2] = bucket(24000, 100); + assert_eq!(memory_offset(&c, 2, 400), None); } }