feat: add support for the Stream Deck Mini Discord Edition (#53)

This commit is contained in:
Torben Schweren authored and GitHub committed 2025-11-29 18:06:12 +00:00
1 parent 3f7c78e91b
commit 18f5c46a8f
5 files changed
+23 -13

No files matched your search

+2
View File
@@ -7,6 +7,7 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="0660"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="008f", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b3", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00a5", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b8", MODE="0660", TAG+="uaccess"
@@ -22,6 +23,7 @@ KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="0660", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="008f", MODE="0660", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="0660", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b3", MODE="0660", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", MODE="0660", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00a5", MODE="0660", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b8", MODE="0660", TAG+="uaccess"
+1
View File
@@ -69,6 +69,7 @@ As it stands, this library should support the following devices.
- Stream Deck XL V2
- Stream Deck Mini
- Stream Deck Mini Mk2
- Stream Deck Mini Discord Edition
- Stream Deck Mk2
- Stream Deck Pedal
- Stream Deck Plus (thanks to [node-elgato-stream-deck](https://github.com/Julusian/node-elgato-stream-deck))
+12 -5
View File
@@ -20,6 +20,8 @@ pub const PID_STREAMDECK_MK2: u16 = 0x0080;
pub const PID_STREAMDECK_MK2_SCISSOR_KEYS: u16 = 0x00a5;
/// Product ID of Stream Deck Mini Mk2
pub const PID_STREAMDECK_MINI_MK2: u16 = 0x0090;
/// Product ID of Stream Deck Mini Discord Edition
pub const PID_STREAMDECK_MINI_DISCORD: u16 = 0x00b3;
/// Product ID of Stream Deck Neo
pub const PID_STREAMDECK_NEO: u16 = 0x009a;
/// Product ID of Stream Deck Pedal
@@ -60,6 +62,8 @@ pub enum Kind {
Mk2Scissor,
/// Stream Deck Mini Mk2
MiniMk2,
/// Stream Deck Mini Discord Edition
MiniDiscord,
/// Stream Deck Neo
Neo,
/// Stream Deck Pedal
@@ -87,6 +91,7 @@ impl Kind {
PID_STREAMDECK_MK2 => Some(Kind::Mk2),
PID_STREAMDECK_MK2_SCISSOR_KEYS => Some(Kind::Mk2Scissor),
PID_STREAMDECK_MINI_MK2 => Some(Kind::MiniMk2),
PID_STREAMDECK_MINI_DISCORD => Some(Kind::MiniDiscord),
PID_STREAMDECK_NEO => Some(Kind::Neo),
PID_STREAMDECK_PEDAL => Some(Kind::Pedal),
PID_STREAMDECK_PLUS => Some(Kind::Plus),
@@ -110,6 +115,7 @@ impl Kind {
Kind::Mk2 => PID_STREAMDECK_MK2,
Kind::Mk2Scissor => PID_STREAMDECK_MK2_SCISSOR_KEYS,
Kind::MiniMk2 => PID_STREAMDECK_MINI_MK2,
Kind::MiniDiscord => PID_STREAMDECK_MINI_DISCORD,
Kind::Neo => PID_STREAMDECK_NEO,
Kind::Pedal => PID_STREAMDECK_PEDAL,
Kind::Plus => PID_STREAMDECK_PLUS,
@@ -130,6 +136,7 @@ impl Kind {
Kind::Mk2 => ELGATO_VENDOR_ID,
Kind::Mk2Scissor => ELGATO_VENDOR_ID,
Kind::MiniMk2 => ELGATO_VENDOR_ID,
Kind::MiniDiscord => ELGATO_VENDOR_ID,
Kind::Neo => ELGATO_VENDOR_ID,
Kind::Pedal => ELGATO_VENDOR_ID,
Kind::Plus => ELGATO_VENDOR_ID,
@@ -143,7 +150,7 @@ impl Kind {
pub fn key_count(&self) -> u8 {
match self {
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 15,
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 6,
Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => 6,
Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 32,
Kind::Pedal => 3,
Kind::Neo | Kind::Plus => 8,
@@ -154,7 +161,7 @@ impl Kind {
pub fn row_count(&self) -> u8 {
match self {
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 3,
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 2,
Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => 2,
Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 4,
Kind::Pedal => 1,
Kind::Neo | Kind::Plus => 2,
@@ -165,7 +172,7 @@ impl Kind {
pub fn column_count(&self) -> u8 {
match self {
Kind::Original | Kind::OriginalV2 | Kind::Mk2 | Kind::Mk2Scissor | Kind::Mk2Module => 5,
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 3,
Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => 3,
Kind::Xl | Kind::XlV2 | Kind::XlV2Module => 8,
Kind::Pedal => 3,
Kind::Neo | Kind::Plus => 4,
@@ -224,7 +231,7 @@ impl Kind {
mirror: ImageMirroring::Both,
},
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => ImageFormat {
Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => ImageFormat {
mode: ImageMode::BMP,
size: (80, 80),
rotation: ImageRotation::Rot90,
@@ -271,7 +278,7 @@ impl Kind {
/// Returns blank image data appropriate for the Stream Deck kind
pub fn blank_image(&self) -> Vec<u8> {
match self {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => {
let mut data = vec![
0x42, 0x4d, 0xf6, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x3c, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+7 -7
View File
@@ -158,7 +158,7 @@ impl StreamDeck {
Ok(extract_str(&bytes[5..])?)
}
Kind::MiniMk2 | Kind::MiniMk2Module => {
Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => {
let bytes = get_feature_report(&self.device, 0x03, 32)?;
Ok(extract_str(&bytes[5..])?)
}
@@ -174,7 +174,7 @@ impl StreamDeck {
/// Returns firmware version of the StreamDeck
pub fn firmware_version(&self) -> Result<String, StreamDeckError> {
match self.kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 => {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord => {
let bytes = get_feature_report(&self.device, 0x04, 17)?;
Ok(extract_str(&bytes[5..])?)
}
@@ -214,7 +214,7 @@ impl StreamDeck {
_ => {
let data = match self.kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => read_data(&self.device, 1 + self.kind.key_count() as usize, timeout),
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => read_data(&self.device, 1 + self.kind.key_count() as usize, timeout),
_ => read_data(&self.device, 4 + self.kind.key_count() as usize + self.kind.touchpoint_count() as usize, timeout),
}?;
@@ -230,7 +230,7 @@ impl StreamDeck {
/// Resets the device
pub fn reset(&self) -> Result<(), StreamDeckError> {
match self.kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => {
let mut buf = vec![0x0B, 0x63];
buf.extend(vec![0u8; 15]);
@@ -253,7 +253,7 @@ impl StreamDeck {
let percent = percent.clamp(0, 100);
match self.kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => {
let mut buf = vec![0x05, 0x55, 0xaa, 0xd1, 0x01, percent];
buf.extend(vec![0u8; 11]);
@@ -288,7 +288,7 @@ impl StreamDeck {
|page_number, this_length, last_package| match self.kind {
Kind::Original => vec![0x02, 0x01, (page_number + 1) as u8, 0, if last_package { 1 } else { 0 }, key + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => vec![0x02, 0x01, page_number as u8, 0, if last_package { 1 } else { 0 }, key + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => vec![0x02, 0x01, page_number as u8, 0, if last_package { 1 } else { 0 }, key + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
_ => vec![
0x02,
@@ -529,7 +529,7 @@ impl WriteImageParameters {
};
let image_report_header_length = match kind {
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => 16,
Kind::Original | Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => 16,
_ => 8,
};
+1 -1
View File
@@ -70,7 +70,7 @@ pub fn read_button_states(kind: &Kind, states: &[u8]) -> Vec<bool> {
bools
}
Kind::Mini | Kind::MiniMk2 | Kind::MiniMk2Module => states[1..].iter().map(|s| *s != 0).collect(),
Kind::Mini | Kind::MiniMk2 | Kind::MiniDiscord | Kind::MiniMk2Module => states[1..].iter().map(|s| *s != 0).collect(),
_ => states[4..].iter().map(|s| *s != 0).collect(),
}