kasper / phoenix

A lightweight macOS window and app manager scriptable with JavaScript
https://kasper.github.io/phoenix/
Other
4.39k stars 128 forks source link

Request: Provide API for battery percentage #319

Closed philc closed 1 year ago

philc commented 1 year ago

Similar in spirit to the hs.battery.percentage API in Hammerspoon.

This is useful for showing the battery percentage in a HUD. The battery percentage can be obtained by shelling out to pmset -g batt. That is a bit more cumbersome.

mafredri commented 1 year ago

I can’t speak for Kasper and I have no say in the direction of this project, but Phoenix is very focused on window management. Battery status falls under system monitoring IMO and I see it unlikely to land in Phoenix.

That said, shelling out doesn’t have to be cumbersome. I invite you to take inspiration from my implementation which you could use like this (untested, but you get the gist of it):

const bat = await task(‘pmset’, ‘-g’, ‘batt’).then(out => out.match(…)[0])

https://github.com/mafredri/phoenix-config/blob/af7ee9657a14eb70cb69652ccd1849faf327dc09/src/task.ts

philc commented 1 year ago

@mafredri After considering, I agree with you that the battery percentage is easy enough to obtain with a shell command and isn't a high-value addition to the API. Originally, I thought it could only be obtained with Applescript, which would be painful because of the latency, but then I discovered pmset.

Task would be much less cumbersome to invoke if it returned a Promise. Your succinct one-liner requires the creation/discovery of the 20 lines of supporting functions you have in your task.js helper to make Task async compatible.

mafredri commented 1 year ago

@philc I mean sure, but it only depends on how fancy you want to be. I could implement it with exactly the same functionality in much less code (promisifying the API is quite easy):

export function taskSlim(name: string, ...args: string[]): Promise<Task> {
    return new Promise((resolve, reject) => {
        Task.run('/bin/sh', ['-c', [name, ...args].join(' ')], (t) => {
            if (t.status !== 0) {
                return reject(t);
            }
            return resolve(t);
        });
    });
}
const bat = await taskSlim('pmset', '-g', 'batt').then(t => t.output.match(/[0-9]+%/)?.[0]);
kasper commented 1 year ago

To build on @mafredri’s point, I’m hesitant to add too much scope into this project to keep the focus tight. Using tasks should allow you to extend your Phoenix setup in many different ways.

Promisifying is a good idea, some older macOS versions don’t support JavaScript 6, but it could be added conditionally. A nice improvement idea. 🙌