Files
razerkb-light-control/src/index.js
Lewis Diamond 45e363536a Before cleanup
2020-12-19 19:34:27 -05:00

153 lines
4.1 KiB
JavaScript
Executable File

#!/bin/env node
const debug = require("debug");
const { spawnSync } = require("child_process");
const yargs = require("yargs");
const suncalc = require("suncalc");
const dbus = require("./dbus");
const pulse = require("./pulse");
const mpd = require("./mpd");
const { colors, brightness } = require("./colors");
const o = yargs.options({
a: {
alias: "audio",
default: "analog-surround-51",
describe: "String used to match the pulse audio device",
type: "string",
},
m: {
alias: ["mic", "record"],
default: "C-Media_Electronics_Inc._USB_PnP_Sound_Device",
describe: "String used to match the pulse microphone device",
type: "string",
},
v: {
alias: "verbose",
default: 0,
describe: "Verbosity level, add more -v for more verbosity",
type: "count",
},
mpdport: {
alias: "p",
default: 6600,
describe: "MPD port",
type: "number",
},
mpdhost: {
alias: "h",
default: "localhost",
describe: "MPD Host",
type: "string",
},
}).argv;
const AUDIO_NAME = o.a;
const MIC_NAME = o.m;
const levels = ["*:error", "*:warn", "*:info", "*:log", "*:debug"].slice(
0,
o.v + 1,
);
debug.enable(levels.join(","));
function isNight() {
const now = new Date();
const night = suncalc.getTimes(now, 45.524128, -73.735409);
const isnight = now >= night.sunset || now <= night.sunrise;
return isnight;
}
function getBrightness() {
return isNight() ? 60 : 100;
}
const volume =
(Math.min(
parseInt(
spawnSync(
`pactl list | grep -E "Name: .*${AUDIO_NAME}$|Volume" | grep "Name:" -A1 | tail -1 | cut -d% -f1 | cut -d/ -f2 | tr -d " "`,
{ shell: true },
).stdout,
),
30,
) /
30) *
100;
async function setMutedMic() {
const muted = !spawnSync(
`pacmd dump | grep ^set-source-mute.*${MIC_NAME}.*yes`,
{ shell: true },
).status;
const b = muted ? getBrightness() : 100;
return dbus.staticMatrix(
...(muted
? brightness(colors.BASE_COLOR, b).rgb()
: brightness(colors.ALERT_COLOR, b).rgb()),
6,
22,
);
}
async function setAudio(matrix) {
const keys = [21];
const muted = !spawnSync(
`pacmd dump | grep ^set-sink-mute.*${AUDIO_NAME}.*yes`,
{ shell: true },
).status;
if (muted) {
keys.forEach(x =>
dbus.setKey(matrix, 0, x, ...colors.SAFE_COLOR.rgb()),
);
} else if (volume === 0) {
keys.forEach(x => dbus.setKey(matrix, 0, x, ...colors.BLUE.rgb()));
} else {
const volume = parseInt(
spawnSync(
`pactl list | grep -E "Name: .*${AUDIO_NAME}$|Volume" | grep "Name:" -A1 | tail -1 | cut -d% -f1 | cut -d/ -f2 | tr -d " "`,
{ shell: true },
).stdout,
);
const c = brightness(
volume < DANGEROUS_VOLUME
? colors.BASE_COLOR.rgb()
: colors.ALERT_COLOR.rgb(),
(volume / 50) * 100,
);
keys.forEach(x => dbus.setKey(matrix, 0, x, ...c.rgb()));
}
}
async function run() {
const interfaces = await dbus.connect();
const matrix = await setMutedMic();
setAudio(matrix);
setPlaying(matrix);
await interfaces.brightness.setBrightness(100);
await interfaces.chroma.setKeyRow(matrix);
dbus.disconnect();
}
async function daemon() {
const matrix = dbus.staticMatrix(...colors.BASE_COLOR.rgb(), 6, 22);
const setKey = (...args) => {
dbus.setKey(matrix, ...args);
};
const interfaces = await dbus.connect();
const draw = async () => await interfaces.chroma.setKeyRow(matrix);
const mpdDisconnect = mpd(
{ host: o.mpdhost, port: o.mpdport },
setKey,
draw,
)();
const p = pulse.connect({ out: AUDIO_NAME, mic: MIC_NAME, setKey, draw });
process.on("SIGINT", () => {
mpdDisconnect();
dbus.disconnect();
p.disconnect();
});
}
daemon();