Skip to content
Knut Ahlers edited this page Nov 15, 2023 · 39 revisions

Installation

System requirements

  • Linux with installed hidapi library
    • Archlinux: pacman -S hidapi
    • Ubuntu: apt-get install libhidapi-dev
  • Access to /dev/hidraw* for StreamDeck control
  • Access to /dev/uinput for key_press action

udev configuration

In order to be able to access the StreamDeck as a user and use the key_press action you need to have access to above mentioned devices. This can for example be achieved with this configuration placed into /etc/udev/rules.d/99-streamdeck.rules:

ACTION=="add", ATTRS{idVendor}=="0fd9", MODE="0666"
KERNEL=="uinput", MODE="0666"

Building

To build the tool you will need to have a working Go development environment.

  • Most easy way is just to go get -u github.com/Luzifer/streamdeck/cmd/streamdeck the application.
  • Alternatively you can download the source and execute a go build inside the cmd/streamdeck directory. This will provide you with a streamdeck binary in said directory.

Configuration

The tool expects to get a configuration file in YAML format.

The config consists of a general part you need to supply:

# Automatically reload on config changes
auto_reload: true

# Optional: int, how much border to give captions in px
caption_border: 5
# Optional: array of int, RGBA color values (4 values, each 0-255)
caption_color: [0xff, 0xff, 0xff, 0xff]
# Font to use when rendering captions on buttons (must be a local path to a TTF file!)
caption_font: /usr/share/fonts/TTF/Roboto-Bold.ttf
# Optional: float, font size to use on captions
caption_font_size: 10.0
# Optional: string, where to place captions (bottom / top)
caption_position: bottom

# Brightness to set on start (0-100)
default_brightness: 20
# Page to display on start
default_page: default
# Optional: Time to display off (0s or leave out for no timeout)
display_off_time: 5m
# Font to use when rendering buttons with text (must be a local path to a TTF file!)
render_font: /usr/share/fonts/TTF/Roboto-Regular.ttf

And a part configuring the different pages and keys on the pages:

pages:

  default:
    overlay: otherpage # Optional: string, put defined keys over current page
    underlay: otherpage # Optional: string, put defined keys under current page
    keys:
      0: # Number of the key (0 = first, 31 = last on a XL, 14 = last on an Original)
        display:
          type: image
          attributes:
            path: /home/myuser/.config/streamdeck/images/lock.png
        actions:
          - type: exec
            attributes:
              command: ["/home/myuser/.config/streamdeck/scripts/lock.sh"]
  • Each page consists of a name (default in the example above) and key definitions.
  • Each key consists of a display and one or more action configs.
  • Each display or action config consists of a type and attributes.

Action modules

Currently these types of actions are supported:

exec

This action will call any command on the system specified and detach from it (the command will continue to run in the background even when streamdeck exits).

actions:
  - type: exec
    attributes:
      # Optional: bool, attach to STDERR of process
      attach_stderr: true
      # Optional: bool, attach to STDOUT of process
      attach_stdout: true
      # Required: array of strings, command to execute
      command: ["/usr/bin/bash", "-c", "echo 'Hi there!'"]
      # Optional: map string to string, environment variables to set
      env:
        MYVAR: "myvalue"
      # Optional: bool, wait for command to finish (default: false)
      wait: true

key_press

This action will emulate key-presses through the uinput kernel API.

actions:
  - type: key_press
    attributes:
      # Optional: string, time to wait between key presses
      delay: 1s
      # Required: array of int, key codes to press in order
      key_codes: [35, 18, 38, 38, 24]
      # DEPRECATED: array of strings, keys to press in order
      keys: ["c"]
      # Optional: boolean, whether to activate `alt` during key presses
      mod_alt: false
      # Optional: boolean, whether to activate `ctrl` during key presses
      mod_ctrl: false
      # Optional: boolean, whether to activate `shift` during key presses
      mod_shift: false
      # Optional: boolean, whether to activate `meta` (also known as `mod4` or `win`) during key presses
      mod_meta: false

You can get the key codes using the tool evtest, selecting your keyboard and pressing the corresponding keys or looking them up in the kernel key list (all defines starting with KEY_).

As an example when your keyboard is event8 to get the codes for typing "hello":

# sudo evtest /dev/input/event8 | grep 'EV_KEY.*value 1'
Event: time 1591456231.768213, type 1 (EV_KEY), code 35 (KEY_H), value 1
hEvent: time 1591456231.832260, type 1 (EV_KEY), code 18 (KEY_E), value 1
eEvent: time 1591456231.984229, type 1 (EV_KEY), code 38 (KEY_L), value 1
lEvent: time 1591456232.120230, type 1 (EV_KEY), code 38 (KEY_L), value 1
lEvent: time 1591456232.273392, type 1 (EV_KEY), code 24 (KEY_O), value 1
oEvent: time 1591456233.792516, type 1 (EV_KEY), code 29 (KEY_LEFTCTRL), value 1
Event: time 1591456234.096658, type 1 (EV_KEY), code 46 (KEY_C), value 1

page

This action will switch to another page using its name.

actions:
  - type: page
    attributes:
      # Optional: string, name of the target page as defined in config
      name: second
      # Optional: int, move back in the page-history for N steps
      relative: 1

pulsevolume (Linux only)

This action supports volume and mute control for PulseAudio setups.

actions:
  - type: pulsevolume
    attributes:
      # Required: string, type of the device to control (input / sink / source)
      device: input
      # Required: string, regular expression to match the name of the device
      match: '^Spotify'
      # Optional: string, state of mute to set (toggle / true / false)
      mute: toggle
      # Optional: float, adjustment of the volume to current volume (percent 0-150)
      change_volume: -5
      # Optional: float, adjustment of the volume in absolute percentage (0-150)
      set_volume: 22

reload_config

This action will reload the config and switch back to the default page.

actions:
  - type: reload_config

toggle_display

This action will toggle the display brightness between 0 and the previous value.

actions:
  - type: toggle_display

Display modules

Currently these types of displays are supported:

color

This display will show a uniform color on the icon.

display:
  type: color
  attributes:
    # Optional: string, name of a pre-defined color
    color: blue
    # Optional: array of int, RGBA color values (4 values, each 0-255)
    rgba: [0xff, 0x0, 0x0, 0xff]

exec

This display will execute a command and display the result on the icon.

display:
  type: exec
  attributes:
    # Optional: array of int, RGBA color values (4 values, each 0-255)
    background_color: [0xff, 0x0, 0x0, 0xff] # You can use an alpha < 0xff but that might lead to text distortion
    # Optional: int, number of pixels to leave as a border
    border: 5
    # Optional: string, caption to render onto the button (see global options)
    caption: My Button
    # Optional: array of int, RGBA color values (4 values, each 0-255)
    rgba: [0xff, 0x0, 0x0, 0xff]
    # Required: array of strings, command to execute
    command: ["/usr/bin/date", "+%H:%M:%S"]
    # Optional: map string to string, environment variables to set
    env:
      MYVAR: "myvalue"
    # Optional: float, maximum size of the font (font-size is automatically adjusted to fit the text)
    font-size: 20.0
    # Optional: string, path to a background image
    image: /home/myuser/.config/streamdeck/images/date_bg.png
    # Optional: int, number of seconds to refresh the icon after
    interval: 5 # if set to 0 or left out, refresh is disabled

The command may return JSON on its stdout and overwrite the attributes mentioned above (except command and interval):
{"text":"28%", "color":[0, 255, 0, 255]}

image

This display will load and display an image.

display:
  type: image
  attributes:
    # Optional: string, caption to render onto the button (see global options)
    caption: My Button
    # Required: string, path to a background image
    path: /home/myuser/.config/streamdeck/images/date_bg.png
    # Optional: string, URL to fetch the image from (will only be fetched if path is unset)
    url: "https://example.com/myimage.png"

pulsevolume (Linux only)

This action supports displaying device state / volume for PulseAudio devices.

display:
  type: pulsevolume
  attributes:
    # Optional: int, number of pixels to leave as a border
    border: 5
    # Optional: string, caption to render onto the button (see global options)
    caption: Spotify
    # Optional: array of int, RGBA color values (4 values, each 0-255)
    color: [0xff, 0x0, 0x0, 0xff]
    # Required: string, type of the device to control (input / sink / source)
    device: input
    # Required: string, regular expression to match the name of the device
    match: '^Spotify'
    # Optional: float, maximum size of the font (font-size is automatically adjusted to fit the text)
    font-size: 20.0
    # Optional: int, number of seconds to refresh the icon after
    interval: 5 # if left out, refresh is set to 1s

text

This display will display a simple text styable through attributes

display:
  type: text
  attributes:
    # Optional: array of int, RGBA color values (4 values, each 0-255)
    background_color: [0xff, 0x0, 0x0, 0xff] # You can use an alpha < 0xff but that might lead to text distortion
    # Optional: int, number of pixels to leave as a border
    border: 5
    # Optional: string, caption to render onto the button (see global options)
    caption: My Button
    # Optional: array of int, RGBA color values (4 values, each 0-255)
    rgba: [0xff, 0x0, 0x0, 0xff]
    # Optional: float, maximum size of the font (font-size is automatically adjusted to fit the text)
    font-size: 20.0
    # Optional: string, path to a background image
    image: /home/myuser/.config/streamdeck/images/date_bg.png
    # Optional: int, number of seconds to refresh the icon after
    interval: 5 # if set to 0 or left out, refresh is disabled
    # Required: string
    text: 'text'
Clone this wiki locally