Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for RGBW lights #2

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from "./lib/movie.js";
export * from "./lib/light.js";
export * from "./lib/interfaces.js";
export * from "./lib/discovery.js";
export * from "./lib/fetchwrapper.js";
//# sourceMappingURL=index.d.ts.map
1 change: 1 addition & 0 deletions dist/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./lib/movie.js";
export * from "./lib/light.js";
export * from "./lib/interfaces.js";
export * from "./lib/discovery.js";
export * from "./lib/fetchwrapper.js";
1 change: 1 addition & 0 deletions dist/lib/discovery.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export declare function discoverTwinklyDevices(timeout?: number): Promise<Map<st
* @param device The discovered Twinkly device.
*/
export declare function handleDiscoveredDevices(): Promise<void>;
//# sourceMappingURL=discovery.d.ts.map
1 change: 1 addition & 0 deletions dist/lib/discovery.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion dist/lib/fetchwrapper.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default class FetchWrapper {
export declare class FetchWrapper {
private baseURL;
private timeout;
defaults: FetchDefaults;
Expand All @@ -20,3 +20,5 @@ export interface FetchDefaults {
export interface FetchResponse extends Response {
data?: any;
}
export default FetchWrapper;
//# sourceMappingURL=fetchwrapper.d.ts.map
1 change: 1 addition & 0 deletions dist/lib/fetchwrapper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion dist/lib/fetchwrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
export default class FetchWrapper {
export class FetchWrapper {
constructor(baseURL = "", timeout = 5000) {
this.defaults = {
headers: {},
Expand Down Expand Up @@ -88,3 +88,4 @@ export default class FetchWrapper {
}
}
}
export default FetchWrapper;
3 changes: 2 additions & 1 deletion dist/lib/frame.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Led } from "./led.js";
import type { Led } from "./led";
/**
* A frame of LEDs, used when you wish to set color pixel by pixel
*
Expand Down Expand Up @@ -28,3 +28,4 @@ export declare class Frame {
*/
getNLeds(): number;
}
//# sourceMappingURL=frame.d.ts.map
1 change: 1 addition & 0 deletions dist/lib/frame.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions dist/lib/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ export class Frame {
* @returns {Uint8Array}
*/
toOctet() {
let buffer = new ArrayBuffer(this.leds.length * 3);
let output = new Uint8Array(buffer);
const channels = this.leds[0].type.length || 3;
const buffer = new ArrayBuffer(this.leds.length * channels);
const output = new Uint8Array(buffer);
let offset = 0;
this.leds.forEach((led) => {
output.set(led.toOctet(), offset);
offset += 3;
offset += channels;
});
return output;
}
Expand Down
1 change: 1 addition & 0 deletions dist/lib/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ export interface layout {
coordinates: coordinate[];
code: applicationResponseCode;
}
//# sourceMappingURL=interfaces.d.ts.map
1 change: 1 addition & 0 deletions dist/lib/interfaces.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 23 additions & 2 deletions dist/lib/led.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,34 @@ export declare class Led {
red: number;
green: number;
blue: number;
white?: number;
private _type;
/**
* Creates an instance of the Led class.
*
* @param {number} red - Red value (0-255).
* @param {number} green - Green value (0-255).
* @param {number} blue - Blue value (0-255).
*/
constructor(red: number, green: number, blue: number);
constructor(red: number, green: number, blue: number, white?: number);
/**
* Gets the LED type.
* @returns {'rgb'|'rgbw'} The LED type.
*/
get type(): 'rgb' | 'rgbw';
/**
* Converts the LED to RGBW.
*
* @returns {Led} The updated Led instance.
*/
toRgbw(): this;
/**
* Converts the LED to RGB.
*
* @param {boolean} [preserveWhite] - If true, the white value will be preserved.
* @returns {Led} The updated Led instance.
*/
toRgb(preserveWhite?: boolean): this;
/**
* Converts the RGB values to a Uint8Array.
*
Expand All @@ -43,7 +63,7 @@ export declare class Led {
* @param {number} blue - New blue value.
* @returns {Led} The updated Led instance.
*/
setColor(red: number, green: number, blue: number): this;
setColor(red: number, green: number, blue: number, white?: number): this;
/**
* Inverts the RGB values.
*
Expand Down Expand Up @@ -85,3 +105,4 @@ export declare class Led {
*/
desaturate(factor: number): this;
}
//# sourceMappingURL=led.d.ts.map
1 change: 1 addition & 0 deletions dist/lib/led.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 55 additions & 5 deletions dist/lib/led.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,66 @@ export class Led {
* @param {number} green - Green value (0-255).
* @param {number} blue - Blue value (0-255).
*/
constructor(red, green, blue) {
constructor(red, green, blue, white) {
this.red = red;
this.green = green;
this.blue = blue;
this.white = white;
this._type = typeof white === 'number' ? 'rgbw' : 'rgb';
}
/**
* Gets the LED type.
* @returns {'rgb'|'rgbw'} The LED type.
*/
get type() {
return this._type;
}
/**
* Converts the LED to RGBW.
*
* @returns {Led} The updated Led instance.
*/
toRgbw() {
if (this._type === 'rgbw')
return this;
this.white = 0;
this._type = 'rgbw';
return this;
}
/**
* Converts the LED to RGB.
*
* @param {boolean} [preserveWhite] - If true, the white value will be preserved.
* @returns {Led} The updated Led instance.
*/
toRgb(preserveWhite = false) {
const white = this.white;
if (this._type === 'rgb')
return this;
this.white = undefined;
this._type = 'rgb';
if (white && preserveWhite) {
this.brighten(white / 255);
}
return this;
}
/**
* Converts the RGB values to a Uint8Array.
*
* @returns {Uint8Array} The RGB values in a Uint8Array format.
*/
toOctet() {
return new Uint8Array([this.red, this.green, this.blue]);
return new Uint8Array(this._type === 'rgbw'
? [this.white, this.red, this.green, this.blue]
: [this.red, this.green, this.blue]);
}
/**
* Checks if the LED color is turned on (non-zero).
*
* @returns {boolean} True if the LED is on, false otherwise.
*/
isOn() {
return this.red > 0 || this.green > 0 || this.blue > 0;
return this.red > 0 || this.green > 0 || this.blue > 0 || this.white > 0;
}
/**
* Sets all RGB values to 0, turning the LED off.
Expand All @@ -43,6 +83,7 @@ export class Led {
this.red = 0;
this.green = 0;
this.blue = 0;
this._type === 'rgbw' && (this.white = 0);
return this;
}
/**
Expand All @@ -53,10 +94,14 @@ export class Led {
* @param {number} blue - New blue value.
* @returns {Led} The updated Led instance.
*/
setColor(red, green, blue) {
setColor(red, green, blue, white) {
this.red = red;
this.green = green;
this.blue = blue;
if (typeof white === 'number') {
this.white = white;
this._type = 'rgbw';
}
return this;
}
/**
Expand All @@ -68,6 +113,7 @@ export class Led {
this.red = 255 - this.red;
this.green = 255 - this.green;
this.blue = 255 - this.blue;
typeof this.white === 'number' && (this.white = 255 - this.white);
return this;
}
/**
Expand All @@ -76,7 +122,7 @@ export class Led {
* @returns {string} String in the format 'rgb(r, g, b)'.
*/
toString() {
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
return `${this._type}(${this.red}, ${this.green}, ${this.blue}, ${this.white})`;
}
/**
* Brightens the LED color by a specified factor.
Expand All @@ -88,6 +134,7 @@ export class Led {
this.red = Math.min(255, Math.round(this.red * factor));
this.green = Math.min(255, Math.round(this.green * factor));
this.blue = Math.min(255, Math.round(this.blue * factor));
this._type === 'rgbw' && (this.white = Math.min(255, Math.round((this.white || 0) * factor)));
return this;
}
/**
Expand All @@ -100,6 +147,7 @@ export class Led {
this.red = Math.max(0, Math.round(this.red * factor));
this.green = Math.max(0, Math.round(this.green * factor));
this.blue = Math.max(0, Math.round(this.blue * factor));
this._type === 'rgbw' && (this.white = Math.max(0, Math.round((this.white || 0) * factor)));
return this;
}
/**
Expand All @@ -113,6 +161,7 @@ export class Led {
this.red = Math.min(255, Math.max(0, average + factor * (this.red - average)));
this.green = Math.min(255, Math.max(0, average + factor * (this.green - average)));
this.blue = Math.min(255, Math.max(0, average + factor * (this.blue - average)));
this._type === 'rgbw' && (this.white = Math.min(255, Math.max(0, average + factor * ((this.white || 0) - average))));
return this;
}
/**
Expand All @@ -126,6 +175,7 @@ export class Led {
this.red = this.red + factor * (average - this.red);
this.green = this.green + factor * (average - this.green);
this.blue = this.blue + factor * (average - this.blue);
this._type === 'rgbw' && (this.white = (this.white || 0) + factor * (average - (this.white || 0)));
return this;
}
}
10 changes: 6 additions & 4 deletions dist/lib/light.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// <reference types="node" />
import { AxiosInstance, AxiosResponse } from "axios";
import FetchWrapper, { FetchResponse } from "./fetchwrapper.js";
import { Frame } from "./frame.js";
import { Movie } from "./movie.js";
import { rgbColor, hsvColor, deviceMode, timer, coordinate, layout } from "./interfaces.js";
import { FetchWrapper, FetchResponse } from "./fetchwrapper";
import { Frame } from "./frame";
import { Movie } from "./movie";
import { rgbColor, hsvColor, deviceMode, timer, coordinate, layout } from "./interfaces";
/**
* Represents a Twinkly device
* @public
Expand All @@ -16,6 +16,7 @@ export declare class Light {
token: AuthenticationToken | undefined;
activeLoginCall: boolean;
nleds: number | undefined;
name: string | undefined;
udpClient: any;
/**
* Creates an instance of Light.
Expand Down Expand Up @@ -354,3 +355,4 @@ export declare class OneColorFrame extends Frame {
*/
constructor(rgb: rgbColor, nleds: number);
}
//# sourceMappingURL=light.d.ts.map
1 change: 1 addition & 0 deletions dist/lib/light.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions dist/lib/light.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
import { generateRandomHex } from "./utils.js";
import axios from "axios";
import FetchWrapper from "./fetchwrapper.js";
import { FetchWrapper } from "./fetchwrapper";
import delay from "delay";
// dynamically import udp for compatibility with browser
// import * as udp from "node:dgram";
import { Led } from "./led.js";
import { Frame } from "./frame.js";
import { Movie } from "./movie.js";
import { deviceMode, applicationResponseCode, } from "./interfaces.js";
import { Led } from "./led";
import { Frame } from "./frame";
import { Movie } from "./movie";
import { deviceMode, applicationResponseCode, } from "./interfaces";
// create error
let errNoToken = Error("No valid token");
/**
Expand Down Expand Up @@ -239,8 +239,11 @@ export class Light {
* @returns {Promise<object>} Results vary, see https://xled-docs.readthedocs.io/en/latest/rest_api.html#device-details
*/
getDeviceDetails() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
let data = yield this.sendGetRequest("/gestalt", undefined, false);
(_a = this.nleds) !== null && _a !== void 0 ? _a : (this.nleds = data.number_of_led);
(_b = this.name) !== null && _b !== void 0 ? _b : (this.name = data.device_name);
return data;
});
}
Expand Down Expand Up @@ -271,6 +274,8 @@ export class Light {
*/
getName() {
return __awaiter(this, void 0, void 0, function* () {
if (this.name)
return this.name;
let data = yield this.sendGetRequest("/device_name");
let res = data.name;
return res;
Expand Down
Loading