Skip to content

Commit cddd838

Browse files
committed
PowerPulse: add wireless battery monitor desklet
1 parent 7bbbef3 commit cddd838

26 files changed

Lines changed: 4891 additions & 0 deletions

powerpulse@vicman.app/README.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# PowerPulse
2+
3+
**Desklet para Linux Mint Cinnamon** que muestra de forma rápida y visual el nivel de batería de tus dispositivos inalámbricos.
4+
5+
Combina **UPower** (D-Bus) y **HeadsetControl** en una tarjeta compacta sobre el escritorio.
6+
7+
Repositorio: [https://github.com/vicman/PowerPulse](https://github.com/vicman/PowerPulse)
8+
9+
![PowerPulse en el escritorio](docs/screenshot.png)
10+
11+
<p align="center">
12+
<em>MX Keys · Logitech G933 · Laptop · Basilisk V3 Pro — ordenados por batería ascendente</em>
13+
</p>
14+
15+
---
16+
17+
## Características
18+
19+
- Descubrimiento automático de baterías vía **UPower** (portátil, teclado, ratón, headset, etc.)
20+
- Soporte opcional de **HeadsetControl** (p. ej. Logitech G933)
21+
- Vista **compacta**: icono, nombre, porcentaje y barra
22+
- Vista **expandida** al hacer clic (detalles in-place, sin ventanas)
23+
- Resumen global al hacer clic en el título **PowerPulse**
24+
- Orden configurable (por defecto: batería ascendente — lo más bajo primero)
25+
- Indicadores visuales: ⚡ carga · 🔌 enchufe · 🔋 batería · ⚠ baja · 🟥 crítico
26+
- Notificaciones de batería baja (una sola vez por ciclo)
27+
- Temas claros/oscuros, HiDPI, localización ES/EN
28+
- Arquitectura modular lista para nuevos proveedores (OpenRazer, Solaar, Bluetooth…)
29+
30+
## Requisitos
31+
32+
| Componente | Obligatorio | Notas |
33+
|------------|-------------|--------|
34+
| Linux Mint Cinnamon 6.x || Probado en Cinnamon 6.6 / Mint 22 |
35+
| UPower || Incluido en Mint |
36+
| [HeadsetControl](https://github.com/Sapd/HeadsetControl) | No | Solo para auriculares compatibles (G933, etc.) |
37+
38+
Sin HeadsetControl, PowerPulse sigue mostrando todos los dispositivos reportados por UPower.
39+
40+
## Instalación
41+
42+
### Paquete del sistema (recomendado)
43+
44+
Genera e instala el `.deb` nativo de Linux Mint / Debian / Ubuntu:
45+
46+
```bash
47+
chmod +x build-installer.sh
48+
./build-installer.sh
49+
sudo apt install ./dist/cinnamon-desklet-powerpulse_1.3.0_all.deb
50+
```
51+
52+
También puedes hacer **doble clic** en el `.deb` desde el gestor de archivos.
53+
54+
El zip de distribución (`dist/powerpulse@vicman.app-1.3.0.zip`) incluye el README y el `.deb`.
55+
56+
Si antes lo instalaste con `./install.sh`, quita la copia de usuario para que no oculte el paquete del sistema:
57+
58+
```bash
59+
./uninstall.sh
60+
```
61+
62+
Luego:
63+
64+
1. Clic derecho en el escritorio → **Añadir Desklets…**
65+
2. Busca **PowerPulse** y añádelo
66+
67+
```bash
68+
sudo apt remove cinnamon-desklet-powerpulse
69+
```
70+
71+
### Instalación en la carpeta de usuario
72+
73+
```bash
74+
git clone https://github.com/vicman/PowerPulse.git
75+
cd PowerPulse
76+
chmod +x install.sh uninstall.sh
77+
./install.sh
78+
```
79+
80+
El script copia el Desklet a:
81+
82+
```text
83+
~/.local/share/cinnamon/desklets/powerpulse@vicman.app/
84+
```
85+
86+
Luego:
87+
88+
1. Clic derecho en el escritorio → **Añadir Desklets…**
89+
2. Busca **PowerPulse** y añádelo
90+
91+
### Desinstalación (carpeta de usuario)
92+
93+
```bash
94+
./uninstall.sh
95+
```
96+
97+
## Uso rápido
98+
99+
| Acción | Resultado |
100+
|--------|-----------|
101+
| Clic en un dispositivo | Expande / contrae sus detalles |
102+
| Clic en **PowerPulse** | Resumen global (conteos, proveedores, versión) |
103+
| Clic derecho | Menú contextual |
104+
| Menú → **Actualizar ahora** | Fuerza una lectura nueva |
105+
106+
### Menú contextual
107+
108+
- Actualizar ahora
109+
- Gestión de energía
110+
- Ordenar por…
111+
- Modo compacto
112+
- Expandir / contraer todo
113+
- Configuración
114+
- Copiar resumen
115+
116+
## Configuración
117+
118+
Desde el menú del Desklet o *Preferencias → Desklets → PowerPulse*:
119+
120+
- Intervalo de actualización
121+
- Orden predeterminado (batería ↑ / ↓, nombre, tipo, última actualización, manual)
122+
- Nombre amigable de la batería del portátil (por defecto `Laptop`)
123+
- Mostrar solo conectados, iconos, porcentaje, barras
124+
- Tiempo restante, voltaje, salud y ciclos (en la vista expandida)
125+
- Umbral de batería baja y notificaciones
126+
- Comando y timeout de HeadsetControl
127+
128+
## Captura
129+
130+
![Captura de PowerPulse](docs/screenshot.png)
131+
132+
## Arquitectura
133+
134+
Diseñado para ampliar proveedores **sin tocar el núcleo de la UI**:
135+
136+
```text
137+
powerpulse@vicman.app/
138+
├── desklet.js # Orquestador
139+
├── providers/ # UPower, HeadsetControl (+ futuros)
140+
├── models/ # Modelo de dispositivo y ordenación
141+
├── ui/ # Tarjetas y panel de resumen
142+
├── animations/ # Animaciones cortas
143+
├── utils/ # Formato y parser
144+
├── settings/
145+
├── stylesheet.css
146+
├── settings-schema.json
147+
└── metadata.json
148+
```
149+
150+
Proveedores previstos a futuro: OpenRazer, Solaar, Bluetooth Battery Service, gamepads, UPS, stylus, Android/iPhone, Apple Magic Devices.
151+
152+
## Desarrollo
153+
154+
```bash
155+
# Editar → reinstalar → recargar Cinnamon (Alt+F2 → r → Enter)
156+
./install.sh
157+
158+
# Pruebas unitarias del parser / ordenación
159+
node tests/run_tests.js
160+
161+
# Diagnóstico del sistema
162+
./diagnose.sh
163+
upower -e
164+
headsetcontrol -b
165+
```
166+
167+
## Identidad
168+
169+
| | |
170+
|--|--|
171+
| **Nombre** | PowerPulse |
172+
| **UUID** | `powerpulse@vicman.app` |
173+
| **Versión** | 1.3.0 |
174+
| **Autor** | VicMan |
175+
| **Repositorio** | [https://github.com/vicman/PowerPulse](https://github.com/vicman/PowerPulse) |
176+
| **Licencia** | [GPL-3.0](LICENSE) |
177+
| **Plataforma** | Linux Mint Cinnamon 6.x |
178+
179+
## Licencia
180+
181+
Este proyecto se distribuye bajo los términos de la **GNU General Public License v3.0**.
182+
Consulta el archivo [LICENSE](LICENSE) para el texto completo.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* Lightweight Clutter animations for PowerPulse.
3+
* Prefer short easings; avoid continuous timers.
4+
*/
5+
6+
const Clutter = imports.gi.Clutter;
7+
8+
const DUR_EXPAND = 220;
9+
const DUR_BAR = 280;
10+
11+
function easeActor(actor, props) {
12+
if (!actor || typeof actor.ease !== "function") {
13+
Object.keys(props).forEach((key) => {
14+
if (key === "onComplete" || key === "duration" || key === "mode") {
15+
return;
16+
}
17+
try {
18+
if (key === "opacity") {
19+
actor.opacity = props[key];
20+
} else if (key === "height" && typeof actor.set_height === "function") {
21+
actor.set_height(props[key]);
22+
} else if (key === "width" && typeof actor.set_width === "function") {
23+
actor.set_width(props[key]);
24+
}
25+
} catch (e) {}
26+
});
27+
if (typeof props.onComplete === "function") {
28+
props.onComplete();
29+
}
30+
return;
31+
}
32+
33+
const params = Object.assign({
34+
duration: DUR_EXPAND,
35+
mode: Clutter.AnimationMode.EASE_OUT_CUBIC
36+
}, props);
37+
actor.ease(params);
38+
}
39+
40+
function fadeIn(actor, duration) {
41+
if (!actor) {
42+
return;
43+
}
44+
actor.show();
45+
actor.opacity = 0;
46+
easeActor(actor, {
47+
opacity: 255,
48+
duration: duration || DUR_EXPAND,
49+
mode: Clutter.AnimationMode.EASE_OUT_QUAD
50+
});
51+
}
52+
53+
function fadeOut(actor, duration, onDone) {
54+
if (!actor) {
55+
if (onDone) onDone();
56+
return;
57+
}
58+
easeActor(actor, {
59+
opacity: 0,
60+
duration: duration || DUR_EXPAND,
61+
mode: Clutter.AnimationMode.EASE_IN_QUAD,
62+
onComplete: () => {
63+
try { actor.hide(); } catch (e) {}
64+
if (onDone) onDone();
65+
}
66+
});
67+
}
68+
69+
function animateWidth(actor, width, duration) {
70+
if (!actor) {
71+
return;
72+
}
73+
easeActor(actor, {
74+
width: Math.max(2, Math.round(width)),
75+
duration: duration || DUR_BAR,
76+
mode: Clutter.AnimationMode.EASE_OUT_CUBIC
77+
});
78+
}
79+
80+
module.exports = {
81+
DUR_EXPAND,
82+
DUR_BAR,
83+
easeActor,
84+
fadeIn,
85+
fadeOut,
86+
animateWidth
87+
};

0 commit comments

Comments
 (0)