Socket
Socket
Sign inDemoInstall

elgato-stream-deck

Package Overview
Dependencies
73
Maintainers
2
Versions
22
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.0 to 1.2.0

wallaby.js

21

CHANGELOG.md

@@ -0,1 +1,22 @@

<a name="1.2.0"></a>
# [1.2.0](https://github.com/Lange/node-elgato-stream-deck/compare/v1.1.0...v1.2.0) (2017-06-23)
### Features
* add `clearKey` method #4
* add Typescript typings #13
* add `setBrightness` and `sendFeatureReport` [4d904f0](https://github.com/Lange/node-elgato-stream-deck/commit/4d904f0c7d40154186914599d877b5879179d48b)
### Bug Fixes
* throw an error when no stream decks are present [c44a1bf](https://github.com/Lange/node-elgato-stream-deck/commit/c44a1bf3ae51bfdc7e9963f131a2ce02746b2975
)
* fix device detection on linux [e0b128c](https://github.com/Lange/node-elgato-stream-deck/commit/e0b128c82aa6e5075e3f8a77d9fca43103b83bc4)
* `fillImage` fix blue and red channels being swapped [8efdb6b](https://github.com/Lange/node-elgato-stream-deck/commit/8efdb6bf0cb1fde3920c850c6b57d25e56648e09)
### Misc
* Full test coverage
<a name="1.1.0"></a>

@@ -2,0 +23,0 @@ # [1.1.0](https://github.com/Lange/node-elgato-stream-deck/compare/v1.0.0...v1.1.0) (2017-05-18)

182

index.js

@@ -16,8 +16,9 @@ 'use strict';

const NUM_TOTAL_PIXELS = NUM_FIRST_PAGE_PIXELS + NUM_SECOND_PAGE_PIXELS;
const keyState = new Array(NUM_KEYS).fill(false);
const devices = HID.devices();
const connectedStreamDecks = devices.filter(device => {
return device.product === 'Stream Deck' && device.manufacturer === 'Elgato Systems';
return device.vendorId === 0x0fd9 && device.productId === 0x0060;
});
/* istanbul ignore if */
if (connectedStreamDecks.length > 1) {

@@ -27,2 +28,7 @@ throw new Error('More than one Stream Deck is connected. This is unsupported at this time.');

/* istanbul ignore if */
if (connectedStreamDecks.length < 1) {
throw new Error('No Stream Decks are connected.');
}
class StreamDeck extends EventEmitter {

@@ -32,2 +38,3 @@ constructor(device) {

this.device = device;
this.keyState = new Array(NUM_KEYS).fill(false);

@@ -41,3 +48,3 @@ this.device.on('data', data => {

const keyPressed = Boolean(data[i]);
if (keyPressed !== keyState[i]) {
if (keyPressed !== this.keyState[i]) {
if (keyPressed) {

@@ -50,3 +57,3 @@ this.emit('down', i);

keyState[i] = keyPressed;
this.keyState[i] = keyPressed;
}

@@ -60,2 +67,8 @@ });

/**
* Writes a Buffer to the Stream Deck.
*
* @param {Buffer} buffer The buffer written to the Stream Deck
* @returns undefined
*/
write(buffer) {

@@ -65,3 +78,27 @@ return this.device.write(StreamDeck.bufferToIntArray(buffer));

/**
* Sends a HID feature report to the Stream Deck.
*
* @param {Buffer} buffer The buffer send to the Stream Deck.
* @returns undefined
*/
sendFeatureReport(buffer) {
return this.device.sendFeatureReport(StreamDeck.bufferToIntArray(buffer));
}
/**
* Fills the given key with a solid color.
*
* @param {number} keyIndex The key to fill 0 - 14
* @param {number} r The color's red value. 0 - 255
* @param {number} g The color's green value. 0 - 255
* @param {number} b The color's blue value. 0 -255
*/
fillColor(keyIndex, r, g, b) {
StreamDeck.checkValidKeyIndex(keyIndex);
StreamDeck.checkRGBValue(r);
StreamDeck.checkRGBValue(g);
StreamDeck.checkRGBValue(b);
const pixel = Buffer.from([b, g, r]);

@@ -72,5 +109,37 @@ this._writePage1(keyIndex, Buffer.alloc(NUM_FIRST_PAGE_PIXELS * 3, pixel));

/**
* Checks a value is a valid RGB value. A number between 0 and 255.
*
* @static
* @param {number} value The number to check
*/
static checkRGBValue(value) {
if (value < 0 || value > 255) {
throw new TypeError('Expected a valid color RGB value 0 - 255');
}
}
/**
* Checks a keyIndex is a valid key for a stream deck. A number between 0 and 14.
*
* @static
* @param {number} keyIndex The keyIndex to check
*/
static checkValidKeyIndex(keyIndex) {
if (keyIndex < 0 || keyIndex > 14) {
throw new TypeError('Expected a valid keyIndex 0 - 14');
}
}
/**
* Fills the given key with an image in a Buffer.
*
* @param {number} keyIndex The key to fill 0 - 14
* @param {Buffer} imageBuffer
*/
fillImage(keyIndex, imageBuffer) {
StreamDeck.checkValidKeyIndex(keyIndex);
if (imageBuffer.length !== 15552) {
throw new Error(`Expected image buffer of length 15552, got length ${imageBuffer.length}`);
throw new RangeError(`Expected image buffer of length 15552, got length ${imageBuffer.length}`);
}

@@ -86,3 +155,3 @@

const b = imageBuffer.readUInt8(i + 2);
row.push(b, g, r);
row.push(r, g, b);
}

@@ -98,6 +167,15 @@ pixels = pixels.concat(row.reverse());

/**
* Fill's the given key with an image from a file.
*
* @param {number} keyIndex The key to fill 0 - 14
* @param {String} filePath A file path to an image file
* @returns {Promise<void>} Resolves when the file has been written
*/
fillImageFromFile(keyIndex, filePath) {
StreamDeck.checkValidKeyIndex(keyIndex);
return sharp(filePath)
.flatten() // Eliminate alpha channel, if any.
.resize(this.ICON_SIZE, this.ICON_SIZE)
.resize(this.ICON_SIZE)
.raw()

@@ -110,2 +188,34 @@ .toBuffer()

/**
* Clears the given key.
*
* @param {number} keyIndex The key to clear 0 - 14
* @returns {undefined}
*/
clearKey(keyIndex) {
StreamDeck.checkValidKeyIndex(keyIndex);
return this.fillColor(keyIndex, 0, 0, 0);
}
/**
* Sets the brightness of the keys on the Stream Deck
*
* @param {number} percentage The percentage brightness
*/
setBrightness(percentage) {
if (percentage < 0 || percentage > 100) {
throw new RangeError('Expected brightness percentage to be between 0 and 100');
}
this.sendFeatureReport(this._padToLength(Buffer.from([0x05, 0x55, 0xaa, 0xd1, 0x01, percentage]), 17));
}
/**
* Writes a Stream Deck's page 1 headers and image data to the Stream Deck.
*
* @private
* @param {number} keyIndex The key to write to 0 - 14
* @param {Buffer} buffer Image data for page 1
* @returns {undefined}
*/
_writePage1(keyIndex, buffer) {

@@ -124,20 +234,48 @@ const header = Buffer.from([

const packetWithHeader = Buffer.concat([header, buffer]);
const numZeroesToFill = PAGE_PACKET_SIZE - packetWithHeader.length;
const packet = Buffer.concat([packetWithHeader, Buffer.alloc(numZeroesToFill)]);
const packet = this._padToLength(Buffer.concat([header, buffer]), PAGE_PACKET_SIZE);
return this.write(packet);
}
/**
* Writes a Stream Deck's page 2 headers and image data to the Stream Deck.
*
* @private
* @param {number} keyIndex The key to write to 0 - 14
* @param {Buffer} buffer Image data for page 2
* @returns {undefined}
*/
_writePage2(keyIndex, buffer) {
const header = Buffer.from([
0x02, 0x01, 0x02, 0x00, 0x01, keyIndex + 1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]);
const packetWithHeader = Buffer.concat([header, buffer]);
const numZeroesToFill = PAGE_PACKET_SIZE - packetWithHeader.length;
const packet = Buffer.concat([packetWithHeader, Buffer.alloc(numZeroesToFill)]);
const header = Buffer.from([0x02, 0x01, 0x02, 0x00, 0x01, keyIndex + 1]);
const packet = this._padToLength(Buffer.concat([header, this._pad(10), buffer]), PAGE_PACKET_SIZE);
return this.write(packet);
}
/**
* Pads a given buffer till padLength with 0s.
*
* @private
* @param {Buffer} buffer Buffer to pad
* @param {number} padLength The length to pad to
* @returns {Buffer} The Buffer padded to the length requested
*/
_padToLength(buffer, padLength) {
return Buffer.concat([buffer, this._pad(padLength - buffer.length)]);
}
/**
* Returns an empty buffer (filled with zeroes) of the given length
*
* @private
* @param {number} padLength Length of the buffer
* @returns {Buffer}
*/
_pad(padLength) {
return Buffer.alloc(padLength);
}
/**
* The pixel size of an icon written to the Stream Deck key.
*
* @readonly
*/
get ICON_SIZE() {

@@ -147,2 +285,10 @@ return ICON_SIZE;

/**
* Converts a buffer into an number[]. Used to supply the underlying
* node-hid device with the format it accepts.
*
* @static
* @param {Buffer} buffer Buffer to convert
* @returns {number[]} the converted buffer
*/
static bufferToIntArray(buffer) {

@@ -149,0 +295,0 @@ const array = [];

@@ -0,0 +0,0 @@ MIT License

{
"name": "elgato-stream-deck",
"version": "1.1.0",
"description": "A npm module for interfacing with the Elgato Stream Deck",
"version": "1.2.0",
"description": "An npm module for interfacing with the Elgato Stream Deck",
"main": "index.js",
"typings": "typings.d.ts",
"dependencies": {

@@ -10,5 +11,13 @@ "node-hid": "^0.5.4"

"devDependencies": {
"ava": "^0.19.1",
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"eslint-config-xo": "^0.18.2",
"eslint-plugin-ava": "^4.2.0",
"mockery": "^2.0.0",
"nyc": "^10.3.2",
"pureimage": "0.0.21",
"sharp": "^0.17.3",
"sinon": "^2.2.0",
"stream-buffers": "^3.0.1",
"weallbehave": "^1.2.0",

@@ -18,3 +27,6 @@ "weallcontribute": "^1.0.8"

"scripts": {
"test": "npm run static",
"pretest": "npm run static",
"test": "nyc ava",
"report": "nyc report --reporter=html",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"static": "eslint .",

@@ -32,2 +44,3 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",

"deck",
"streamdeck",
"hid",

@@ -68,3 +81,6 @@ "usb",

"lib"
]
],
"engines": {
"node": ">=4"
}
}

@@ -1,2 +0,2 @@

# elgato-stream-deck [![npm version](https://img.shields.io/npm/v/elgato-stream-deck.svg)](https://npm.im/elgato-stream-deck) [![license](https://img.shields.io/npm/l/elgato-stream-deck.svg)](https://npm.im/elgato-stream-deck) [![Travis](https://travis-ci.org/Lange/node-elgato-stream-deck.svg?branch=master)](https://travis-ci.org/Lange/node-elgato-stream-deck) [![Join the chat at https://gitter.im/node-elgato-stream-deck/Lobby](https://badges.gitter.im/node-elgato-stream-deck/Lobby.svg)](https://gitter.im/node-elgato-stream-deck/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# elgato-stream-deck [![npm version](https://img.shields.io/npm/v/elgato-stream-deck.svg)](https://npm.im/elgato-stream-deck) [![license](https://img.shields.io/npm/l/elgato-stream-deck.svg)](https://npm.im/elgato-stream-deck) [![Travis](https://travis-ci.org/Lange/node-elgato-stream-deck.svg?branch=master)](https://travis-ci.org/Lange/node-elgato-stream-deck) [![Coverage Status](https://coveralls.io/repos/github/Lange/node-elgato-stream-deck/badge.svg?branch=master)](https://coveralls.io/github/Lange/node-elgato-stream-deck?branch=master) [![Join the chat at https://gitter.im/node-elgato-stream-deck/Lobby](https://badges.gitter.im/node-elgato-stream-deck/Lobby.svg)](https://gitter.im/node-elgato-stream-deck/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

@@ -12,2 +12,33 @@ ![alt text](media/streamdeck_ui.png "elgato-stream-deck")

If that fails (**or if you are on a Raspberry Pi**), you will need to install a compiler toolchain to enable npm to build
some of `node-elgato-stream-deck`'s dependencies from source.
* Windows
* Install [`windows-build-tools`](https://github.com/felixrieseberg/windows-build-tools):
```bash
npm install --global windows-build-tools
```
* MacOS
* Install [Xcode](https://developer.apple.com/xcode/download/), then:
```bash
xcode-select --install
```
* Linux (**including Raspberry Pi**)
* Follow the instructions for Linux in the ["Compiling from source"](https://github.com/node-hid/node-hid#compiling-from-source) steps for `node-hid`:
```bash
sudo apt-get install build-essential git
sudo apt-get install gcc-4.8 g++-4.8 && export CXX=g++-4.8
sudo apt-get install sudo apt install libusb-1.0-0 libusb-1.0-0-dev
```
* Install a recent version of Node.js. We've had success with v7:
```bash
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt-get install -y nodejs
```
* Try installing `node-elgato-stream-deck`
* If you still have issues, ensure everything is updated and try again:
```bash
sudo apt-get update && sudo apt-get upgrade
```
## Table of Contents

@@ -24,2 +55,4 @@

* [`fillImage`](#fill-image)
* [`clearKey`](#clear-key)
* [`setBrightness`](#set-brightness)
* [Events](#events)

@@ -29,8 +62,11 @@ * [`down`](#down)

* [`error`](#error)
* [Protocol Notes](#protocol-notes)
### Example
#### JavaScript
```javascript
const path = require('path');
const streamDeck = require('elgato-stream-deck')
const streamDeck = require('elgato-stream-deck');

@@ -60,11 +96,35 @@ streamDeck.on('down', keyIndex => {

#### TypeScript
```typescript
import streamDeck = require('elgato-stream-deck');
streamDeck.on('down', keyIndex => {
console.log('key %d down', keyIndex);
});
streamDeck.on('up', keyIndex => {
console.log('key %d up', keyIndex);
});
streamDeck.on('error', error => {
console.error(error);
});
```
### Features
* Miltiplatform support: Windows 7-10, MacOS, Linux, and even Raspberry Pi!
* Key `down` and key `up` events
* Fill keys with images or solid RGB colors
* Typescript support
* Set the Stream Deck brightness
### Planned Features
* Key combinations
* [Hotplugging](https://github.com/Lange/node-elgato-stream-deck/issues/14)
* [Key combinations](https://github.com/Lange/node-elgato-stream-deck/issues/9)
* Support "pages" feature from the official Elgato Stream Deck software
* [Text labels](https://github.com/Lange/node-elgato-stream-deck/issues/6)
* [Changing the standby image](https://github.com/Lange/node-elgato-stream-deck/issues/11)

@@ -135,3 +195,3 @@ ### Contributing

.flatten() // Eliminate alpha channel, if any.
.resize(streamDeck.ICON_SIZE, streamDeck.ICON_SIZE) // Scale down to the right size, cropping if necessary.
.resize(streamDeck.ICON_SIZE) // Scale down to the right size, cropping if necessary.
.raw() // Give us uncompressed RGB

@@ -147,2 +207,24 @@ .toBuffer()

#### <a name="clear-key"></a> `> streamDeck.clearKey(keyIndex) -> undefined`
Synchronously clears the given `keyIndex`'s screen.
##### Example
```javascript
// Clear the third button from the left in the first row.
streamDeck.clearKey(2);
```
#### <a name="set-brightness"></a> `> streamDeck.setBrightness(percentage) -> undefined`
Synchronously set the brightness of the Stream Deck.
##### Example
```javascript
// Set the Stream Deck to maximum brightness
streamDeck.setBrightness(100);
```
### Events

@@ -182,5 +264,9 @@

```javascript
streamDeck.on('error', keyIndex => {
console.log('key %d error', keyIndex);
streamDeck.on('error', error => {
console.error(error);
});
```
### Protocol Notes
Raw protocol notes can be found in [NOTES.md](NOTES.md). These detail the protocol and method for interacting with the Stream Deck which this module implements.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc