mirror of
https://github.com/danbulant/colors
synced 2026-06-18 13:51:14 +00:00
first commit
This commit is contained in:
commit
09cb648e5b
7 changed files with 177 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/node_modules
|
||||
/pnpm-lock.yaml
|
||||
28
index.ts
Normal file
28
index.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { JoyStick } from "./joystick";
|
||||
|
||||
const devices = await JoyStick.getList();
|
||||
|
||||
for(const device of devices) {
|
||||
const colors = await device.getColors();
|
||||
const max = await device.getMaxColors();
|
||||
console.log(`Found device ${device.name}:
|
||||
Colors:
|
||||
RED ${colors.red}
|
||||
GREEN ${colors.green}
|
||||
BLUE ${colors.blue}
|
||||
Max colors:
|
||||
RED ${max.red}
|
||||
GREEN ${max.green}
|
||||
BLUE ${max.blue}`)
|
||||
const newColors = {
|
||||
red: Math.floor(Math.random() * max.red),
|
||||
green: Math.floor(Math.random() * max.green),
|
||||
blue: Math.floor(Math.random() * max.blue),
|
||||
};
|
||||
await device.setColors(newColors);
|
||||
console.log(`
|
||||
Updated colors:
|
||||
RED ${newColors.red}
|
||||
GREEN ${newColors.green}
|
||||
BLUE ${newColors.blue}`);
|
||||
}
|
||||
81
joystick.ts
Normal file
81
joystick.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { exec, readUTF, writeUTF } from "./utils";
|
||||
import * as fs from "fs";
|
||||
|
||||
interface IJoyStick {
|
||||
name: string;
|
||||
led: string;
|
||||
dev: string;
|
||||
}
|
||||
|
||||
interface Colors {
|
||||
red: number;
|
||||
green: number;
|
||||
blue: number;
|
||||
}
|
||||
|
||||
export class JoyStick implements IJoyStick {
|
||||
name: string;
|
||||
led: string;
|
||||
dev: string;
|
||||
|
||||
constructor(data: IJoyStick) {
|
||||
this.name = data.name;
|
||||
this.led = data.led;
|
||||
this.dev = data.dev;
|
||||
}
|
||||
|
||||
async getColors() {
|
||||
const [ red, green, blue ] = (await Promise.all([
|
||||
readUTF(`/sys/class/leds/${this.led}:red/brightness`),
|
||||
readUTF(`/sys/class/leds/${this.led}:green/brightness`),
|
||||
readUTF(`/sys/class/leds/${this.led}:blue/brightness`),
|
||||
])).map(t => parseInt(t));
|
||||
|
||||
return { red, green, blue } as Colors;
|
||||
}
|
||||
|
||||
async setColors(colors: Colors) {
|
||||
await Promise.all([
|
||||
writeUTF(`/sys/class/leds/${this.led}:red/brightness`, colors.red.toString()),
|
||||
writeUTF(`/sys/class/leds/${this.led}:green/brightness`, colors.green.toString()),
|
||||
writeUTF(`/sys/class/leds/${this.led}:blue/brightness`, colors.blue.toString()),
|
||||
]);
|
||||
}
|
||||
|
||||
private _maxColors?: Colors;
|
||||
async getMaxColors() {
|
||||
if(!this._maxColors) {
|
||||
const [ red, green, blue ] = (await Promise.all([
|
||||
readUTF(`/sys/class/leds/${this.led}:red/max_brightness`),
|
||||
readUTF(`/sys/class/leds/${this.led}:green/max_brightness`),
|
||||
readUTF(`/sys/class/leds/${this.led}:blue/max_brightness`),
|
||||
])).map(t => parseInt(t));
|
||||
this._maxColors = { red, green, blue };
|
||||
}
|
||||
|
||||
return this._maxColors;
|
||||
}
|
||||
|
||||
private static async getDevice(name: string) {
|
||||
const out = await exec(["udevadm", "info", "-n", name]);
|
||||
const data: Record<string, string> = {};
|
||||
for(const line of out.split("\n")) {
|
||||
if(line[0] !== "E") continue;
|
||||
const [, key, val] = line.match(/^E: ([A-Z_]+)=(.*)$/)!;
|
||||
data[key] = val;
|
||||
}
|
||||
return new JoyStick({
|
||||
name: data.ID_SERIAL,
|
||||
led: data.DEVPATH.split("/")[8],
|
||||
dev: data.DEVNAME
|
||||
});
|
||||
}
|
||||
|
||||
static async getList() {
|
||||
const devices = await Promise.all([
|
||||
...fs.readdirSync("/dev/input")
|
||||
].filter(t => t.startsWith("js"))
|
||||
.map(t => this.getDevice(`/dev/input/${t}`)));
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
6
package.json
Normal file
6
package.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"got": "^11.8.2",
|
||||
"node-vibrant": "^3.2.1-alpha.1"
|
||||
}
|
||||
}
|
||||
21
spotify.ts
Normal file
21
spotify.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { exec } from "./utils";
|
||||
|
||||
interface Track {
|
||||
length: number;
|
||||
artURL: string;
|
||||
id: string;
|
||||
url: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
albumArtist: string;
|
||||
}
|
||||
|
||||
class Spotify {
|
||||
async getCurrentTrack() {
|
||||
const data: Record<string, string> = {};
|
||||
const out = await exec(["qdbus", "org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.Metadata"]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default new Spotify();
|
||||
8
tsconfig.json
Normal file
8
tsconfig.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"target": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
}
|
||||
31
utils.ts
Normal file
31
utils.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { promises as afs } from "fs";
|
||||
import { spawn } from "child_process";
|
||||
import got from "got";
|
||||
import Vibrant from 'node-vibrant';
|
||||
|
||||
export async function readUTF(file: string) {
|
||||
return await afs.readFile(file, { encoding: "utf-8" }) as string;
|
||||
}
|
||||
export async function writeUTF(file: string, data: string) {
|
||||
return await afs.writeFile(file, data);
|
||||
}
|
||||
|
||||
export function exec(cmd: string[]) {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
var output = "";
|
||||
const p = spawn(cmd.shift(), cmd);
|
||||
p.stdout.on("data", (chunk) => output += chunk);
|
||||
p.on("exit", (code) => {
|
||||
if(code) return reject(code);
|
||||
resolve(output);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function getColor(image: string) {
|
||||
var resp = await got(image, {
|
||||
responseType: "buffer"
|
||||
});
|
||||
var vibrant = new Vibrant(resp.body);
|
||||
var color = await vibrant.getPalette();
|
||||
}
|
||||
Loading…
Reference in a new issue