mirror of
https://github.com/danbulant/colors
synced 2026-07-05 11:00:43 +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