Help us shape the future of Go! Take the 2026 Go Developer Survey

streamdeck

package module
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 13 Imported by: 0

README

streamdeck

Latest Release Software License Build Status Go ReportCard Go Doc

A CLI application and Go library to control your Elgato Stream Deck on Linux.

If you're looking for a complete Linux service to control your StreamDeck, check out Deckmaster, which is based on this library.

Supported devices

Device Product ID Keys Other controls
Stream Deck Original, Original v2 0060, 006d 5×3
Stream Deck MK.2, MK.2 Scissor Keys 0080, 00a5 5×3
Stream Deck Mini, Mini MK.2, Mini Discord Edition 0063, 0090, 00b3 3×2
Stream Deck XL, XL v2 006c, 008f 8×4
Stream Deck Module 6, 15, 32 00b8, 00b9, 00e4, 00ba 3×2, 5×3, 8×4
Stream Deck Neo* 009a 4×2 2 touch keys with RGB LEDs, 248×58 info screen
Stream Deck Pedal* 0086 3 pedals no displays
Stream Deck+ 0084 4×2 4 dials, 800×100 touch screen
Stream Deck + XL* 00c6 9×4 6 dials, 1200×100 touch screen
Stream Deck Studio* 00aa 16×2, 144×112 pixels 2 dials with RGB LED rings

* Support for these models follows the reference implementations (python-elgato-streamdeck, node-elgato-stream-deck, elgato-streamdeck) and hasn't been tested on hardware yet. Reports are welcome!

Installation

Make sure you have a working Go environment (Go 1.26 or higher is required). See the install instructions.

To install the streamdeck-cli tool, run:

go install github.com/nix-er/streamdeck/cmd/streamdeck-cli@latest

To use streamdeck as a library in your Go module, run:

go get github.com/nix-er/streamdeck

Configuration

On Linux you need to set up some udev rules to be able to access the device as a regular user. Create /etc/udev/rules.d/70-streamdeck.rules with these lines:

# Elgato Stream Deck (vendor 0fd9), all models
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="008f", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="008f", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="009a", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00a5", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00a5", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00aa", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00aa", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b3", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b3", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b8", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b8", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b9", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00b9", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00ba", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00ba", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00c6", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00c6", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00e4", TAG+="uaccess"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="00e4", TAG+="uaccess"

TAG+="uaccess" gives the user logged in on the local seat access to the device, so no extra group membership is needed. The file name must sort before 73-seat-late.rules, or uaccess has no effect. Reload the rules with sudo udevadm control --reload-rules && sudo udevadm trigger. Unplug and replug the device and you should be good to go.

Usage

Control the brightness, in percent between 0 and 100:

streamdeck-cli brightness 50

Set an image on the first key (from the top-left):

streamdeck-cli image 0 image.png

Clear all images:

streamdeck-cli clear

Reset the device:

streamdeck-cli reset

Dials, touch screens and LEDs

Device.ReadInput() emits all input events of a device: Key, DialPress, DialTurn (with a signed step count, negative for counterclockwise turns) and Touch (tap, long press or swipe, with screen coordinates). ReadKeys() only emits key events.

events, err := dev.ReadInput()
if err != nil {
	return err
}
for e := range events {
	switch e := e.(type) {
	case streamdeck.Key:
		fmt.Println("key", e.Index, e.Pressed)
	case streamdeck.DialPress:
		fmt.Println("dial", e.Index, e.Pressed)
	case streamdeck.DialTurn:
		fmt.Println("dial", e.Index, "turned", e.Steps)
	case streamdeck.Touch:
		fmt.Println("touch", e.Type, e.X, e.Y)
	}
}

The touch screen (dev.ScreenWidth × dev.ScreenHeight pixels) is split into dev.ScreenSegments segments, one above each dial. Set an image on a segment with dev.SetScreenSegmentImage(index, img), or on any region with dev.SetScreenImage(x, y, img).

Key images must be dev.KeyWidth × dev.KeyHeight pixels, which isn't square on the Stream Deck Studio. The Stream Deck Pedal has no displays (KeyWidth is 0), so setting images and the brightness does nothing.

The Stream Deck Neo's touch keys report as keys dev.Keys to dev.Keys+dev.TouchKeys-1. Set their LED color with dev.SetKeyColor(index, color), and the info screen (dev.InfoScreenWidth × dev.InfoScreenHeight pixels) with dev.SetInfoScreenImage(img).

On devices with dev.DialRings (Stream Deck Studio), light a dial's LED ring with dev.SetDialRingColor(index, color) or partially with dev.SetDialRingPercentage(index, color, percent), and set its knob LED with dev.SetDialKnobColor(index, color).

Feedback

Got some feedback or suggestions? Please open an issue or drop me a note!

Documentation

Overview

Package streamdeck controls Elgato Stream Deck devices.

Index

Constants

View Source
const (
	VID_ELGATO                        = 0x0fd9
	PID_STREAMDECK                    = 0x0060
	PID_STREAMDECK_V2                 = 0x006d
	PID_STREAMDECK_MK2                = 0x0080
	PID_STREAMDECK_MK2_SCISSOR        = 0x00a5
	PID_STREAMDECK_MK2_MODULE         = 0x00b9
	PID_STREAMDECK_MK2_MODULE_SCISSOR = 0x00e4
	PID_STREAMDECK_MINI               = 0x0063
	PID_STREAMDECK_MINI_MK2           = 0x0090
	PID_STREAMDECK_MINI_DISCORD       = 0x00b3
	PID_STREAMDECK_MINI_MK2_MODULE    = 0x00b8
	PID_STREAMDECK_XL                 = 0x006c
	PID_STREAMDECK_XL_V2              = 0x008f
	PID_STREAMDECK_XL_V2_MODULE       = 0x00ba
	PID_STREAMDECK_NEO                = 0x009a
	PID_STREAMDECK_PEDAL              = 0x0086
	PID_STREAMDECK_PLUS               = 0x0084
	PID_STREAMDECK_PLUS_XL            = 0x00c6
	PID_STREAMDECK_STUDIO             = 0x00aa
)

Stream Deck Vendor & Product IDs.

Variables

This section is empty.

Functions

This section is empty.

Types

type Device

type Device struct {
	ID     string
	Serial string

	Columns uint8
	Rows    uint8
	Keys    uint8

	// KeyWidth and KeyHeight are the pixel dimensions of a key's display.
	// Both are zero if the keys have no displays (Stream Deck Pedal).
	KeyWidth  uint
	KeyHeight uint
	// Pixels is the smaller of KeyWidth and KeyHeight. It equals both on
	// devices with square keys, which are all but the Stream Deck Studio.
	Pixels  uint
	DPI     uint
	Padding uint

	// TouchKeys is the number of touch keys without a display (Stream Deck
	// Neo). They report as keys Keys to Keys+TouchKeys-1 and have an RGB
	// LED, set with SetKeyColor.
	TouchKeys uint8

	// Dials is the number of rotary dials (Stream Deck+, + XL and Studio).
	Dials uint8

	// DialRings is true if the dials have RGB LED rings and knob LEDs, set
	// with SetDialRingColor, SetDialRingPercentage and SetDialKnobColor
	// (Stream Deck Studio).
	DialRings bool

	// ScreenWidth and ScreenHeight are the pixel dimensions of the touch
	// screen strip (Stream Deck+ and + XL), which is split into
	// ScreenSegments equally sized segments, one above each dial. All zero
	// if the device has no touch screen.
	ScreenWidth    uint
	ScreenHeight   uint
	ScreenDPI      uint
	ScreenSegments uint8

	// InfoScreenWidth and InfoScreenHeight are the pixel dimensions of the
	// info screen (Stream Deck Neo), set with SetInfoScreenImage. Both are
	// zero if the device has no info screen.
	InfoScreenWidth  uint
	InfoScreenHeight uint
	// contains filtered or unexported fields
}

Device represents a single Stream Deck device.

func Devices

func Devices() ([]Device, error)

Devices returns all attached Stream Decks.

func (*Device) Asleep

func (d *Device) Asleep() bool

Asleep returns true if the device is asleep.

func (*Device) Clear

func (d *Device) Clear() error

Clear clears the Stream Deck, setting a black image on all buttons, the touch screen and the info screen.

func (*Device) Close

func (d *Device) Close() error

Close the connection with the device.

func (*Device) Fade

func (d *Device) Fade(start uint8, end uint8, duration time.Duration) error

Fade fades the brightness in or out.

func (*Device) FirmwareVersion

func (d *Device) FirmwareVersion() (string, error)

FirmwareVersion returns the firmware version of the device.

func (*Device) Open

func (d *Device) Open() error

Open the device for input/output. This must be called before trying to communicate with the device.

func (*Device) ReadInput added in v0.6.0

func (d *Device) ReadInput() (chan Event, error)

ReadInput returns a channel, which it will use to emit all input events: Key, DialPress, DialTurn and Touch. The channel gets closed when reading from the device fails.

func (*Device) ReadKeys

func (d *Device) ReadKeys() (chan Key, error)

ReadKeys returns a channel, which it will use to emit key presses/releases. Dial and touch screen input is ignored; use ReadInput to receive it.

func (*Device) Reopen added in v0.7.1

func (d *Device) Reopen() error

Reopen reconnects to the device after the connection was lost, e.g. because it was unplugged, finding it again by its serial number. The Device is updated in place, so references to it stay valid. It returns an error while the device isn't attached.

func (*Device) Reset

func (d *Device) Reset() error

Reset resets the Stream Deck, clears all button images and shows the standby image.

func (*Device) ScreenSegmentWidth added in v0.6.0

func (d *Device) ScreenSegmentWidth() uint

ScreenSegmentWidth returns the width of a touch screen segment in pixels, or 0 if the device has no touch screen.

func (*Device) SetBrightness

func (d *Device) SetBrightness(percent uint8) error

SetBrightness sets the background lighting brightness from 0 to 100 percent. While the device is asleep, it sets the brightness to restore on wake-up.

func (*Device) SetDialKnobColor added in v0.7.0

func (d *Device) SetDialKnobColor(index uint8, c color.Color) error

SetDialKnobColor sets the color of a dial's knob LED (Stream Deck Studio).

func (*Device) SetDialRingColor added in v0.7.0

func (d *Device) SetDialRingColor(index uint8, c color.Color) error

SetDialRingColor sets all LEDs of a dial's ring to a color (Stream Deck Studio).

func (*Device) SetDialRingPercentage added in v0.7.0

func (d *Device) SetDialRingPercentage(index uint8, c color.Color, percent uint8) error

SetDialRingPercentage lights the given percentage of a dial's ring LEDs in a color and turns the others off, e.g. to show a volume level (Stream Deck Studio).

func (*Device) SetImage

func (d *Device) SetImage(index uint8, img image.Image) error

SetImage sets the image of a button on the Stream Deck. The provided image needs to be in the correct resolution for the device. The index starts with 0 being the top-left button. On a device without key displays it does nothing.

func (*Device) SetInfoScreenImage added in v0.7.0

func (d *Device) SetInfoScreenImage(img image.Image) error

SetInfoScreenImage sets the image of the info screen (Stream Deck Neo). The image needs to be of the info screen's size.

func (*Device) SetKeyColor added in v0.7.0

func (d *Device) SetKeyColor(index uint8, c color.Color) error

SetKeyColor sets the color of a touch key's LED (Stream Deck Neo). Touch keys have the indexes Keys to Keys+TouchKeys-1.

func (*Device) SetScreenImage added in v0.6.0

func (d *Device) SetScreenImage(x, y int, img image.Image) error

SetScreenImage sets the image of a region of the touch screen, with its top-left corner at x, y. The image must fit within the screen.

func (*Device) SetScreenSegmentImage added in v0.6.0

func (d *Device) SetScreenSegmentImage(index uint8, img image.Image) error

SetScreenSegmentImage sets the image of a touch screen segment. The image needs to be of the segment's size. The index starts with 0 being the leftmost segment.

func (*Device) SetSleepFadeDuration

func (d *Device) SetSleepFadeDuration(t time.Duration)

SetSleepFadeDuration sets the duration of the fading animation when the device is put to sleep or wakes up.

func (*Device) SetSleepTimeout

func (d *Device) SetSleepTimeout(t time.Duration)

SetSleepTimeout sets the time after which the device will sleep if no key events are received.

func (*Device) Sleep

func (d *Device) Sleep() error

Sleep puts the device asleep, waiting for a key event to wake it up.

func (*Device) Wake

func (d *Device) Wake() error

Wake wakes the device from sleep.

type DialPress added in v0.6.0

type DialPress struct {
	Index   uint8
	Pressed bool
}

DialPress is emitted when a dial gets pressed or released.

type DialTurn added in v0.6.0

type DialTurn struct {
	Index uint8
	Steps int8
}

DialTurn is emitted when a dial gets turned. Steps is positive for clockwise and negative for counterclockwise turns.

type Event added in v0.6.0

type Event interface {
	// contains filtered or unexported methods
}

Event is an input event read from the device: Key, DialPress, DialTurn or Touch.

type Key

type Key struct {
	Index   uint8
	Pressed bool
}

Key holds the current status of a key on the device.

type Touch added in v0.6.0

type Touch struct {
	Type       TouchType
	X, Y       uint16
	EndX, EndY uint16
}

Touch is emitted when the touch screen gets tapped, long-pressed or swiped. X and Y are the screen coordinates of the touch, EndX and EndY the end point of a swipe.

type TouchType added in v0.6.0

type TouchType uint8

TouchType describes the kind of a Touch event.

const (
	TouchTap TouchType = iota + 1
	TouchLongPress
	TouchSwipe
)

Touch event types.

Directories

Path Synopsis
cmd
streamdeck-cli command
Command streamdeck-cli controls Elgato Stream Deck devices from the command line.
Command streamdeck-cli controls Elgato Stream Deck devices from the command line.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL