Coder Social home page Coder Social logo

julusian / node-elgato-stream-deck Goto Github PK

View Code? Open in Web Editor NEW
155.0 10.0 20.0 7.79 MB

A Node.js library for interfacing with the Elgato Stream Deck. https://julusian.github.io/node-elgato-stream-deck/

Home Page: https://www.npmjs.com/org/elgato-stream-deck

License: MIT License

JavaScript 15.56% TypeScript 82.37% Dockerfile 0.03% HTML 0.94% CSS 1.06% Shell 0.05%
stream-deck elgato webhid

node-elgato-stream-deck's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-elgato-stream-deck's Issues

Add native .forget() event

Native HID event have a .forget event, that disconect the device complety, allowing the user to connect with a difference device. Here the docs:

https://developer.mozilla.org/en-US/docs/Web/API/HIDDevice/forget

We current have .close event, but this event still remember the device and only closes the connection.


Alternatively just expose the .device var and let users mess with it as so they please.

Hope that makes sense. I can help raise the PR.

`tslib` seems to still be required as dependency

Even though 3ebd04f seems to have removed the tslib dependency, installing the latest release from npm still complains about it being needed:

node:internal/modules/cjs/loader:928
  throw err;
  ^

Error: Cannot find module 'tslib'
Require stack:
- /some/path/node_modules/elgato-stream-deck/dist/models/index.js
- /some/path/node_modules/elgato-stream-deck/dist/index.js
- /some/path/index.js

Looking into it, this seems to be caused by export * in models/index.ts.

Replacing this line with export { KeyIndex, DeviceModelId, StreamDeckDeviceInfo } from './id' would fix this. However, I am no TypeScript expert and there may be a more elegant TS-specific alternative I'm not aware of.

Happy to submit a PR, let me know your preference.

Allow changing standby image

As of the v4.9.0 of the elgato software it is possible to change the 'screensaver'.
This needs proper reverse engineering and exposing in the api

function openStreamDeck - argument devicePath is no longer optional

In version 6.0.0 argument "devicePath" is no longer optional in function "openStreamDeck". If argument excluded in previous versions the first attached stream deck would be used.

If this is intentional, could anyone give an example of how to set a correct path to an attached stream deck?

I'm using node-elegato-stream-deck in an electron application

New Stream Deck Mini Revision not working on webhid demo site

Hi,
after buying a new Stream Deck Mini I ran into some troubles and soon realized that it is one of the newer revisions with the 0090product id. I saw that the new 5.5.0release adds support for this new device. Eager to try out the library I quickly visited your demo site and ran into the unexpected error message after following the displayed instructions:

No device access granted: Error: Stream Deck is of unexpected type.

I am using a Linux machine and configured it accordingly and ran sudo udevadm control --reload-rules:

cat /etc/udev/rules.d/50-elgato.rules
SUBSYSTEM=="input", GROUP="input", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE:="666", GROUP="plugdev"

Is the latest 5.5.0 version deployed or is this some kind of bug?

Already thanks for your help.

New Stream Deck XL

hi, i got an brand new streamdeck xl and it seems unknown to your project.
here's the output of lsub -v

ID 0fd9:008f Elgato Systems GmbH Stream Deck XL
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0fd9 Elgato Systems GmbH
idProduct 0x008f
bcdDevice 1.30
iManufacturer 1 Elgato
iProduct 2 Stream Deck XL
iSerial 3
bNumConfigurations 1

i hope this helps
if i can test something, write me

Gif support

Are gif animation files supported on fillImage() at the moment? Tried with sharp but got a still frame so far...

fillPanel wrong size on Mk2?

I'm trying to set the wallpaper like this on my Mk2

var streamDeck = myStreamDeck; const bmpImgField = await Jimp.read(path.resolve(__dirname, 'wallpaper.png')).then((img) => { return img.resize(myStreamDeck.ICON_SIZE * myStreamDeck.KEY_COLUMNS, myStreamDeck.ICON_SIZE * myStreamDeck.KEY_ROWS) }) const imgField = bmpImgField.bitmap.data streamDeck.fillPanel(imgField)

I'm getting this error:
(node:35810) UnhandledPromiseRejectionWarning: RangeError: Expected image buffer of length 233280, got length 311040
at StreamDeckOriginalMK2.fillPanel

Anything I'm doing wrong?

Thnaks.

text-generation example

Should the text-generation example be fully working at the moment?

On button presses I see the background image appear & disappear, as well as the "Filling" & "Clearing" terminal output, but no text (button number?) in the button itself.

On linux with nodejs v12.22.12. All the other examples seem to run OK.

chris

Error: Failed to find binding for HID_hidraw

When using npm start it works flawlessly, however, when I build the app, I get
Error: Failed to find binding for HID_hidraw

It's worth saying I'm using node 20 and electron 26

MacOS: listStreamDecks contains duplicates

On MacOS it seems that listStreamDecks returns some duplicates.
This may be a node-hid issue as this is the output I get from node-hid (See bellow)

Perhaps the library should filter by serial number to avoid duplicates ?

> HID.devices()
[
  {
    vendorId: 4057,
    productId: 96,
    path: 'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS07@14500000/IOUSBHostDevice@14500000/AppleUSB20Hub@14500000/AppleUSB20HubPort@14520000/USB 2.0 Hub@14520000/AppleUSB20Hub@14520000/AppleUSB20HubPort@14524000/Stream Deck@14524000/IOUSBHostInterface@0/AppleUserUSBHostHIDDevice',
    serialNumber: 'AL50H1C13698',
    manufacturer: 'Elgato Systems',
    product: 'Stream Deck',
    release: 256,
    interface: 0,
    usagePage: 12,
    usage: 1
  },
  {
    vendorId: 4057,
    productId: 96,
    path: 'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS07@14500000/IOUSBHostDevice@14500000/AppleUSB20Hub@14500000/AppleUSB20HubPort@14520000/USB 2.0 Hub@14520000/AppleUSB20Hub@14520000/AppleUSB20HubPort@14524000/Stream Deck@14524000/IOUSBHostInterface@0/AppleUserUSBHostHIDDevice',
    serialNumber: 'AL50H1C13698',
    manufacturer: 'Elgato Systems',
    product: 'Stream Deck',
    release: 256,
    interface: 0,
    usagePage: 9,
    usage: 65280
  },

RangeError when calling fillPanelBuffer or fillKeyBuffer

Thanks for the great project!

I'm bumping into some issues with regards of images within node, which I might be the one to blame for as I might miss something. It's with regard of writing an image to a key.

I have a solid coloured test image, which dimensions matches the ICON_SIZE constant, which is 96x96.
green

I wrote a small test script that reads that image, and sends it off to the device to display it:

import { openStreamDeck } from "@elgato-stream-deck/node";
import fs from "fs";

const device = await openStreamDeck();

const image = await fs.promises.readFile("assets/green.png", { encoding: 'utf8' });

await device.fillKeyBuffer(1, image, {format: 'rgb'});

But when I run this fairly simple script I get the following error:

/<redacted>/streamdeck-node/node_modules/@elgato-stream-deck/core/dist/models/base.js:90
            throw new RangeError(`Expected image buffer of length ${imageSize}, got length ${imageBuffer.length}`);
                  ^

RangeError: Expected image buffer of length 27648, got length 321
    at StreamDeckXL.fillKeyBuffer (/<redacted>/streamdeck-node/node_modules/@elgato-stream-deck/core/dist/models/base.js:90:19)
    at StreamDeckNode.fillKeyBuffer (/<redacted>/streamdeck-node/node_modules/@elgato-stream-deck/core/dist/proxy.js:46:28)
    at file:///<redacted>/streamdeck-node/tests/image.js:8:14

I understand why this error happens, because the image is tiny. But the image is still 96x96.

After checking out the webhid demo project I decided to make another small script that uses canvas in node to create the image, but I get similar results.

import { openStreamDeck } from "@elgato-stream-deck/node";
import { createCanvas } from '@napi-rs/canvas';

const device = await openStreamDeck();

const canvas = createCanvas(96, 96);
const context = canvas.getContext('2d');
context.fillStyle = '#9A920B'
context.fillRect(0, 0, 96, 96);

const image = await canvas.toBuffer('image/png');

await device.fillKeyBuffer(1, image, {format: 'rgb'});

I had similar issues with the fillPanelBuffer method, where I took a screenshot using puppeteer:

import { openStreamDeck } from "@elgato-stream-deck/node";
import puppeteer from 'puppeteer';

const device = await openStreamDeck();
const DEVICE_WIDTH = device.ICON_SIZE * device.KEY_COLUMNS;
const DEVICE_HEIGHT = device.ICON_SIZE * device.KEY_ROWS;

const browser = await puppeteer.launch({ headless: false, defaultViewport: {width: DEVICE_WIDTH, height: DEVICE_HEIGHT} });
const page = await browser.newPage();
await page.goto('https://google.com/')
const image = await page.screenshot({
    type: 'jpeg',
    clip: {
        x: 0,
        y: 0,
        width: DEVICE_WIDTH,
        height: DEVICE_HEIGHT
    }
});

await device.fillPanelBuffer(image);

But this resulted into a similar error:

/<redacted>/streamdeck-node/node_modules/@elgato-stream-deck/core/dist/models/base.js:105
            throw new RangeError(`Expected image buffer of length ${imageSize}, got length ${imageBuffer.length}`);
                  ^

RangeError: Expected image buffer of length 884736, got length 21664
    at StreamDeckXL.fillPanelBuffer (/<redacted>/streamdeck-node/node_modules/@elgato-stream-deck/core/dist/models/base.js:105:19)
    at StreamDeckNode.fillPanelBuffer (/<redacted>/streamdeck-node/node_modules/@elgato-stream-deck/core/dist/proxy.js:49:28)
    at file:///<redacted>/streamdeck-node/tests/chrome.js:21:14
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Dumping this image does result into a image with correct dimensions:
chrome

It could be that I miss some parsing of the image buffer, but I can't seem to find what's wrong.

Update Linux Directions to Reference use of Dynamic User ACLs

The directions described to allow access to the Stream Deck devices on Linux are written in a manner specific to how Ubuntu and Debian are configured, with a statically assigned group owning the device nodes. As noted in the Archwiki page for udev, this has been discouraged by the systemd developers and use of the plugdev group is classified as a bug for Archlinux packages.

The recommended solution on machines using systemd (aka most popular distros) is to tag the devices with a special tag "uaccess", which coordinates with systemd-logind to dynamically grant access when the user is logged in. The only caveat here is that access to the system over SSH doesn't apply the ACL, though given the nature of the devices this library interfaces with, I don't see that as a common issue.

Implementing this as an alternative to the currently documented rules would have the rules file looking like this:

SUBSYSTEM=="input", GROUP="input", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="660", TAG+="uaccess"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE="660", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE="660", TAG+="uaccess"

StreamDeck Mini is not recognized

Hi @Julusian,
thanks for this really great library. It has been working great with my StreamDeck XL, but I've recently bought a StreamDeck Mini on Amazon and it is not recognized.

const sd = require("@elgato-stream-deck/node");
sd.listStreamDecks()

just returns []

It is working with the official StreamDeck software, though.

I'm using the latest version of @elgato-stream-deck/node: v5.4.0.

The usb-detection library reports the following when I plug it in:

{
  locationId: 0,
  vendorId: 4057,
  productId: 144,
  deviceName: 'USB-Eingabegerät',
  manufacturer: '(Standardsystemgeräte)',
  serialNumber: 'BL22L2B09174',
  deviceAddress: 8
}

Therefore it has USB VID 0x0FD9 and PID 0x0090

Does that help?

npm install failure

npm install fails at postinstall (as below). I'm using nodejs 12 but same problem with 14, 16 & 18.
Any tips to fix?

npm install says:

> [email protected] postinstall /home/chris/src/node-elgato-stream-deck
> lerna bootstrap

lerna notice cli v4.0.0
lerna info bootstrap root only
lerna ERR! yarn install --mutex network:42424 --non-interactive exited 2 in 'elgato-stream-deck-packages'
lerna ERR! yarn install --mutex network:42424 --non-interactive exited 2 in 'elgato-stream-deck-packages'
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] postinstall: `lerna bootstrap`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/chris/.npm/_logs/2022-05-17T23_15_07_395Z-debug.log

The debug log says:

44350 info lifecycle [email protected]~postinstall: [email protected]
44351 verbose lifecycle [email protected]~postinstall: unsafe-perm in lifecycle true
44352 verbose lifecycle [email protected]~postinstall: PATH: /home/chris/.nvm/versions/node/v12.22.12/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/home/chris/src/node-elgato-stream-deck/node_modules/.bin:/home/chris/.nvm/versions/node/v12.22.12/bin:/home/chris/gowork/bin:/usr/local/sage/bin:/home/chris/bin:/usr/sbin:/sbin:/usr/lib64/go1.17.9/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib64/libexec/kf5:/usr/lib64/libreoffice/program:/usr/lib64/qt5/bin:/usr/lib64/zulu-openjdk11/bin:/home/chris/.platformio/penv/bin:/opt/crosstool-ng/bin
44353 verbose lifecycle [email protected]~postinstall: CWD: /home/chris/src/node-elgato-stream-deck
44354 silly lifecycle [email protected]~postinstall: Args: [ '-c', 'lerna bootstrap' ]
44355 silly lifecycle [email protected]~postinstall: Returned: code: 2  signal: null
44356 info lifecycle [email protected]~postinstall: Failed to exec postinstall script
44357 verbose stack Error: [email protected] postinstall: `lerna bootstrap`
44357 verbose stack Exit status 2
44357 verbose stack     at EventEmitter.<anonymous> (/home/chris/.nvm/versions/node/v12.22.12/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
44357 verbose stack     at EventEmitter.emit (events.js:314:20)
44357 verbose stack     at ChildProcess.<anonymous> (/home/chris/.nvm/versions/node/v12.22.12/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
44357 verbose stack     at ChildProcess.emit (events.js:314:20)
44357 verbose stack     at maybeClose (internal/child_process.js:1022:16)
44357 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:287:5)
44358 verbose pkgid [email protected]
44359 verbose cwd /home/chris/src/node-elgato-stream-deck
44360 verbose Linux 5.15.38
44361 verbose argv "/home/chris/.nvm/versions/node/v12.22.12/bin/node" "/home/chris/.nvm/versions/node/v12.22.12/bin/npm" "install"
44362 verbose node v12.22.12
44363 verbose npm  v6.14.16
44364 error code ELIFECYCLE
44365 error errno 2
44366 error [email protected] postinstall: `lerna bootstrap`
44366 error Exit status 2
44367 error Failed at the [email protected] postinstall script.
44367 error This is probably not a problem with npm. There is likely additional logging output above.
44368 verbose exit [ 2, true ]

Stream Deck Mobile Support?

I'm guessing the answer here is "no". But I'll ask anyway: Is there a way to use this library (I'm using the WebHID version these days) along with Elgato's Stream Deck Mobile app?

I believe that the app connects to Elgato's Stream Deck Manager desktop app which acts as an intermediary. Since this library (@elgato-stream-deck) doesn't use Elgato's desktop software, I'm guessing that there's no way for Stream Deck Mobile to act as a virtual WebHID/NodeHID device and be seen by @elgato-stream-deck. But I'd love to be wrong! So I'm asking here.

Use this library with Streamdeck App?

Hey there,

let me get this straight: I can only use this library OR the stream deck app?
Because if I try to use both I get an error with the library: cannot open device with path...

I would like to configure only one or two buttons with this library.

Getting an "Uncaught TypeError" in minimal test project

Hey there, I've setup the webhid-demo with all dependencies and was able to confirm it worked properly with my setup. Now I want to create a minimal test project to play around with the tools myself.

I've created a Vite-Vue3 project with nothing but a button for selecting the device, importing any of the @elgato-stream-deck/webhid packages fail with the same error, no matter whether I'm using JS or TS.

Uncaught TypeError: Class extends value undefined is not a constructor or null
    at node_modules/@elgato-stream-deck/webhid/dist/device.js (device.ts:9:35)
    at __require (chunk-RSJERJUL.js?v=04683f6b:3:50)
    at node_modules/@elgato-stream-deck/webhid/dist/index.js (index.ts:2:1)
    at __require (chunk-RSJERJUL.js?v=04683f6b:3:50)
    at @elgato-stream-deck_webhid.js?v=04683f6b:5:16

Here is my App.vue for testing purposes:

<script setup>
import { requestStreamDecks, getStreamDecks } from '@elgato-stream-deck/webhid';
import { ref } from 'vue';

const device = ref(null);

const selectDevice = async () => {
    console.log("Requesting new Device");
    try {
      const devices = await requestStreamDecks();
      device.value = devices[0];
    } catch(error) {
      console.error(error);
    }
};
</script>

<template>
  <div>
    <h1>Streamdeck Test</h1>
    <button @click="selectDevice">Select Device</button>
    <div v-if="device !== null">Device loaded</div>
    <div v-else>No device loaded</div>
    <hr />
  </div>
</template>

Even with this file, I am receiving the same error:

<script setup>
import requestStreamDecks from "@elgato-stream-deck/webhid";
</script>

<template>
  <div>Test</div>
</template>

Incompatible with Electron 21 due to V8 Memory Cage?

Hello! I am getting this error when using this module in Electron 21:

[22072:0928/013445.372:ERROR:node_bindings.cc(146)] Fatal error in V8: v8_ArrayBuffer_NewBackingStore When the V8 Sandbox is enabled, ArrayBuffer backing stores must be allocated inside the sandbox address space. Please use an appropriate ArrayBuffer::Allocator to allocate these buffers.

I believe it has to do with this change in Electron's code:

https://www.electronjs.org/blog/v8-memory-cage

MK2 open error

Running on a raspberry pi with the most current nodejs and npm

I am getting the following error:

TypeError: cannot open device with path 0001:0002:00

The response from lsusb is:

Bus 001 Device 002: ID 0fd9:0080 Elgato Systems GmbH Stream Deck MK.2

If that helps

Please add support for Stream Deck Mobile

It'd be nice if you could add support for the Stream Deck Mobile apps for iOS and Android. AFAICT, these are identical in features with the standard 15-key SD edition(s).

Addendum: It just occurred to me that it might be impossible since SD Mobile are apps, not hardware, and as such don't use USB connectivity and might use entirely different communication channels with the SD desktop app. 🤔

New serial number format with 2 additional characters

I came across a stream deck xl 20GAT9902 with serial A00NA32531SFWL which is 14 characters instead of the normal 12 characters.

I think getSerialNumber() in for example "packages/core/src/models/base-gen2.ts" only allows for the old 12 character types?

Thanks for your great work!

Bildschirmfoto 2023-11-30 um 10 57 43

Device.getStreamDecks fails when another vendor's device is paired

This code fails because it assumes that the device list is filtered by vendor. This is the case with navigator.hid.requestDevice, but not with navigator.hid.getDevices which returns all paired devices in respect of vendor

* Reopen previously selected streamdecks.

I have currently hacked the code by disabling the exception and returning null instead

	const model = DEVICE_MODELS.find((m) => m.productId === browserDevice.productId)
	if (!model) {
		// throw new Error('Stream Deck is of unexpected type.')
		console.warn('Stream Deck is of unexpected type.')
               return;
	}

Expose the exit hook for usage

With the usage of the exit-hook library, the only way I can successfully catch an exit is by using that same library in my code and establishing a hook before requiring your library. This seems hacky. Instead, could you expose a callback or event so that I can do something like lowering the brightness and clearing the deck prior to application exit along with my own cleanup.

Raspberry Pi WebHID

Anyone figured out how to setup the StreamDeck on Raspbian?

All i get is this - even tho udev rules are setup.
No device access granted: NotAllowedError: Failed to open the device.

The device runs flawlessly with the normal node code.

Add option to directly supply JPEG buffers for LCD/keys

Hey there! Awesome library, thank you very much for your work!

I'm writing a volume mixer for Linux with the Streamdeck Plus, and have started optimization. Profiling showed me that a lot of time was spent in the conversion functions and JPEG encoding (already using jpeg-turbo). Since I'm using sharp for generating the frames, I can skip all the preparation and immediately supply the right JPEG buffer - this skips one full-size buffer allocation per draw call as well as a bunch of unnecessary JS-side array options.

Testing showed me that this slightly reduced CPU usage without impacting negatively impacting speed. To properly allow this, I propose adding a new type as a union to the options of the different fill methods:

interface FillImageOptions {
	format: 'rgb' | 'rgba' | 'bgr' | 'bgra'
}

interface FillRawOptions {
	raw: true,
	// or maybe:
	// jpeg: true,
} 

function fillEncoderLcd(index: EncoderIndex, imageBuffer: Buffer, sourceOptions: FillImageOptions | FillRawOptions): Promise<void>

If this is passed, all previous checks and preparations should be skipped, passing the imageBuffer directly as the byteBuffer to the functions responsible for generating writes. This would of course mean opting out all other options, but that should hopefully be fine with documentation :)

This would allow for user-side experimentation and optimization. What do you think?

Pedal Support

Started to look at adding the Pedal to the devices, operates basically the same way just without screens.

[ 201.613991] usb 1-1.1: New USB device found, idVendor=0fd9, idProduct=0086, bcdDevice= 1.00 [ 201.614009] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 201.614023] usb 1-1.1: Product: Stream Deck Pedal [ 201.614036] usb 1-1.1: Manufacturer: Elgato [ 201.614049] usb 1-1.1: SerialNumber: FL51K1A0XXXX [ 201.626846] input: Elgato Stream Deck Pedal as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:0FD9:0086.0004/input/input3 [ 201.693874] hid-generic 0003:0FD9:0086.0004: input,hidraw0: USB HID v11.01 Device [Elgato Stream Deck Pedal] on usb-0000:01:00.0-1.1/input0

Simple adjustment to the udev rules allows it to be detected, new code is 0086. I pulled down a fork, might try to start looking at it but figured I would post up the ID at least in the meantime.

[MacOS]: openStreamDeck error with listStreamDecks()[0].path

Today I tried to use this lib but got an error now.

System:

  • MacOS 11.5.2
  • node 16.1.0
  • npm 7.21.0
  • yarn 1.22.11

I use the lib in typescript with nodemon, typescript and ts-node.

My current code:

import { openStreamDeck, listStreamDecks, StreamDeckDeviceInfo, getStreamDeckInfo } from 'elgato-stream-deck'

function getStreamDeck(): StreamDeckDeviceInfo {
    return listStreamDecks()[0]
}

function init() {
    const deviceInfo = getStreamDeck()
    const currentStreamDeck = openStreamDeck(deviceInfo.path)
}

init()

If I start the code I got this error:

/Users/user/Projects/project/node_modules/node-hid/nodehid.js:49
    this._raw = new (Function.prototype.bind.apply(binding.HID,
                ^
TypeError: cannot open device with path IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/usb-drd1@2280000/AppleT8103USBXHCI@01000000/usb-drd1-port-hs@01100000/USB2.0 Hub@01100000/AppleUSB20Hub@01100000/AppleUSB20HubPort@01140000/USB2.0 HUB@01140000/AppleUSB20Hub@01140000/AppleUSB20HubPort@01143000/Stream Deck XL@01143000/IOUSBHostInterface@0/AppleUserUSBHostHIDDevice
    at new HID (/Users/user/Projects/project/node_modules/node-hid/nodehid.js:49:17)
    at new StreamDeckBase (/Users/user/Projects/project/node_modules/elgato-stream-deck/src/models/base.ts:152:17)
    at new StreamDeckGen2Base (/Users/user/Projects/project/node_modules/elgato-stream-deck/src/models/base-gen2.ts:9:1)
    at new StreamDeckXL (/Users/user/Projects/project/node_modules/elgato-stream-deck/src/models/xl.ts:16:3)
    at Object.openStreamDeck (/Users/user/Projects/project/node_modules/elgato-stream-deck/src/index.ts:114:9)
    at init (/Users/user/Projects/project/src/app.ts:9:31)
    at Object.<anonymous> (/Users/user/Projects/project/src/app.ts:12:1)
    at Module._compile (node:internal/modules/cjs/loader:1109:14)
    at Module.m._compile (/Users/user/Projects/project/node_modules/ts-node/src/index.ts:1310:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1138:10)

Some ideas?

fillPanelBuffer() Promise not actually waiting for image to be transferred before resolving

I need to do a little more research on this. But, in the webHID version at least, the Promise returned from fillPanelBuffer() is resolving before the image has actually been transferred to the panel.

I'm building an Electron app that fills the panel before quitting the app. However, I currently have to put in a timeout in order to ensure that the image has been written.

async function fillOnQuit(deck, logoImage) {
  await deck.fillPanelBuffer(logoImage, { format: 'rgba' })
  // panel hasn't actually been filled yet
  await new Promise((resolve) => setTimeout(resolve, 1500))
}

Make node-hid libusb mode optional

From some crude performance testing, filling the whole panel on a pi 4 takes 300ms with libusb and 80ms with hidraw.

We can't always use hidraw because it doesnt support the original 15 key, but in some circumstances it would be acceptable to opt into hidraw mode when we know we dont need the support.

This could be done as:

  • a global flag to disable the libusb enforcement.
  • could we load a hidraw and a libusb version of node-hid at once and be selective about which devices we use on which?
  • could we mod node-hid to allow both to be loaded simultaneously, with us choosing between them in different calls?

Model number

This is more idle curiosity than a problem ....

My streamdeck XL returns "xl" as it's model. I noticed on the back of the physical device, along with the serial number is a model number 20GAT9901. A quick scan of the code didn't reveal any model numbers in that format - just original*, mini, xl & pedal.

Is there any way to extract the other form (20GAT9901) programmatically?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.