homebridge-goodwe-es 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -17
- package/LICENSE +21 -21
- package/README.md +167 -142
- package/alerts.js +31 -3
- package/config.schema.json +18 -0
- package/goodwe.js +119 -119
- package/homebridge-ui/public/index.html +73 -73
- package/index.js +318 -318
- package/package.json +45 -45
- package/storage.js +243 -243
- package/web/index.html +509 -509
- package/web.js +292 -292
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 1.
|
|
4
|
-
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
## 1.
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.3.0
|
|
4
|
+
- New Pushover push channel (app token + user key, optional device and sound). Grid outages use high priority (1) or emergency (2, repeats until acknowledged, configurable retry/expire); minor notices can be sent silently.
|
|
5
|
+
|
|
6
|
+
## 1.2.1
|
|
7
|
+
- Daily house consumption is now integrated from house power (the inverter's own load counter misses loads fed straight from the grid).
|
|
8
|
+
- Clearer log line when raw readings are kept forever.
|
|
9
|
+
|
|
10
|
+
## 1.2.0
|
|
11
|
+
- Daily-total light sensors: consumption, grid import/export, battery charge/discharge (kWh), for the Homebridge UI Accessories widget or the Home app.
|
|
12
|
+
|
|
13
|
+
## 1.1.0
|
|
14
|
+
- SQLite history (Node's built-in `node:sqlite`): raw readings at a configurable interval, daily summary, raw-data retention.
|
|
15
|
+
- LAN-only web dashboard (live and daily views, table or chart) and streamed CSV export by date range.
|
|
16
|
+
- Grid-outage and over-temperature alerts as HomeKit contact sensors and push notifications (ntfy, Telegram, webhook).
|
|
17
|
+
- Custom settings page in the Homebridge UI.
|
|
18
|
+
|
|
19
|
+
## 1.0.0
|
|
20
|
+
- Local UDP reader (AA55 protocol, port 8899) exposing power, energy, battery and temperature sensors.
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 mrdcl
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mrdcl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,142 +1,167 @@
|
|
|
1
|
-
# homebridge-goodwe-es
|
|
2
|
-
|
|
3
|
-
Local Homebridge plugin for **GoodWe ES / EM hybrid inverters** (for example GW5048D-ES). It reads the inverter over the LAN with the AA55 UDP protocol on port 8899. No cloud account, no SEMS portal, and no npm dependencies.
|
|
4
|
-
|
|
5
|
-
*Versión en español más abajo.*
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **HomeKit sensors**
|
|
10
|
-
- Live readings: solar power, house load, grid import and export (W), battery SOC (shown as humidity with a battery service), inverter and battery temperature.
|
|
11
|
-
- Daily totals in kWh: generation, consumption, grid import and export, battery charge and discharge.
|
|
12
|
-
- **History** in a separate SQLite file using Node's built-in `node:sqlite`.
|
|
13
|
-
- Raw readings are stored at a configurable interval, with configurable retention.
|
|
14
|
-
- A daily summary is kept forever.
|
|
15
|
-
- **Web dashboard**, reachable from the LAN or Tailscale only, on port 8582 by default.
|
|
16
|
-
- Live and daily views, each as a table or a chart.
|
|
17
|
-
- The page can be embedded in any dashboard that has an iframe widget.
|
|
18
|
-
- **CSV export** for any date range.
|
|
19
|
-
- Covers raw readings, daily summaries or events.
|
|
20
|
-
- Streamed, so there is no row limit.
|
|
21
|
-
- Excel-friendly or standard format.
|
|
22
|
-
- **Alerts** for grid outage (and its restoration) and for inverter or battery over-temperature.
|
|
23
|
-
- Each alert is a HomeKit contact sensor (closed = normal, open = alert), so the Home app can notify you.
|
|
24
|
-
- Optional push channels: [ntfy](https://ntfy.sh), Telegram, or a generic webhook (n8n, Home Assistant, …).
|
|
25
|
-
- **Custom settings page** in the Homebridge UI.
|
|
26
|
-
- Shows the plugin status and links to the dashboard and the CSV export.
|
|
27
|
-
- Has buttons to send a test notification and to test the HomeKit alert sensors.
|
|
28
|
-
|
|
29
|
-
> The configuration UI and the default accessory names are in Spanish. You can rename the accessories in the Home app.
|
|
30
|
-
|
|
31
|
-
Energy values are sent to HomeKit as light sensors, because HomeKit has no power characteristic. The number you see is W or kWh, even though the Home app labels it "lux".
|
|
32
|
-
|
|
33
|
-
## Requirements
|
|
34
|
-
|
|
35
|
-
- Homebridge 1.6 or newer, including 2.x.
|
|
36
|
-
- **Node.js 22.13 or newer**, which is the first version where `node:sqlite` is available without a flag. On Node 22 you may see an "ExperimentalWarning" for SQLite; it is harmless.
|
|
37
|
-
- A GoodWe ES/EM inverter with its Wi-Fi/LAN module reachable from the Homebridge host on UDP port 8899. Give the inverter a fixed IP in your router.
|
|
38
|
-
|
|
39
|
-
## Installation
|
|
40
|
-
|
|
41
|
-
Search for **"GoodWe ES"** in the Homebridge UI *Plugins* tab, or run:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npm install -g homebridge-goodwe-es
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Configuration
|
|
48
|
-
|
|
49
|
-
Use the plugin settings page in the Homebridge UI. A minimal `config.json` block looks like this:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"platform": "GoodWeES",
|
|
54
|
-
"name": "GoodWe",
|
|
55
|
-
"host": "192.168.1.50"
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Full example, with every section optional:
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"platform": "GoodWeES",
|
|
64
|
-
"host": "192.168.1.50",
|
|
65
|
-
"pollInterval": 10,
|
|
66
|
-
"history": { "enabled": true, "rawInterval": 60, "rawRetentionDays": 180 },
|
|
67
|
-
"web": { "enabled": true, "port": 8582, "bind": "0.0.0.0", "allowPublic": false },
|
|
68
|
-
"alerts": {
|
|
69
|
-
"homekit": true,
|
|
70
|
-
"notifyRecovery": true,
|
|
71
|
-
"outage": { "enabled": true, "voltageThreshold": 100, "debounceSeconds": 30, "restoreSeconds": 60 },
|
|
72
|
-
"temperature": { "enabled": true, "inverterMax": 60, "batteryMax": 45, "hysteresis": 3, "cooldownMinutes": 30 }
|
|
73
|
-
},
|
|
74
|
-
"notify": {
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
1
|
+
# homebridge-goodwe-es
|
|
2
|
+
|
|
3
|
+
Local Homebridge plugin for **GoodWe ES / EM hybrid inverters** (for example GW5048D-ES). It reads the inverter over the LAN with the AA55 UDP protocol on port 8899. No cloud account, no SEMS portal, and no npm dependencies.
|
|
4
|
+
|
|
5
|
+
*Versión en español más abajo.*
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **HomeKit sensors**
|
|
10
|
+
- Live readings: solar power, house load, grid import and export (W), battery SOC (shown as humidity with a battery service), inverter and battery temperature.
|
|
11
|
+
- Daily totals in kWh: generation, consumption, grid import and export, battery charge and discharge.
|
|
12
|
+
- **History** in a separate SQLite file using Node's built-in `node:sqlite`.
|
|
13
|
+
- Raw readings are stored at a configurable interval, with configurable retention.
|
|
14
|
+
- A daily summary is kept forever.
|
|
15
|
+
- **Web dashboard**, reachable from the LAN or Tailscale only, on port 8582 by default.
|
|
16
|
+
- Live and daily views, each as a table or a chart.
|
|
17
|
+
- The page can be embedded in any dashboard that has an iframe widget.
|
|
18
|
+
- **CSV export** for any date range.
|
|
19
|
+
- Covers raw readings, daily summaries or events.
|
|
20
|
+
- Streamed, so there is no row limit.
|
|
21
|
+
- Excel-friendly or standard format.
|
|
22
|
+
- **Alerts** for grid outage (and its restoration) and for inverter or battery over-temperature.
|
|
23
|
+
- Each alert is a HomeKit contact sensor (closed = normal, open = alert), so the Home app can notify you.
|
|
24
|
+
- Optional push channels: [Pushover](https://pushover.net), [ntfy](https://ntfy.sh), Telegram, or a generic webhook (n8n, Home Assistant, …).
|
|
25
|
+
- **Custom settings page** in the Homebridge UI.
|
|
26
|
+
- Shows the plugin status and links to the dashboard and the CSV export.
|
|
27
|
+
- Has buttons to send a test notification and to test the HomeKit alert sensors.
|
|
28
|
+
|
|
29
|
+
> The configuration UI and the default accessory names are in Spanish. You can rename the accessories in the Home app.
|
|
30
|
+
|
|
31
|
+
Energy values are sent to HomeKit as light sensors, because HomeKit has no power characteristic. The number you see is W or kWh, even though the Home app labels it "lux".
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- Homebridge 1.6 or newer, including 2.x.
|
|
36
|
+
- **Node.js 22.13 or newer**, which is the first version where `node:sqlite` is available without a flag. On Node 22 you may see an "ExperimentalWarning" for SQLite; it is harmless.
|
|
37
|
+
- A GoodWe ES/EM inverter with its Wi-Fi/LAN module reachable from the Homebridge host on UDP port 8899. Give the inverter a fixed IP in your router.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
Search for **"GoodWe ES"** in the Homebridge UI *Plugins* tab, or run:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install -g homebridge-goodwe-es
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
Use the plugin settings page in the Homebridge UI. A minimal `config.json` block looks like this:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"platform": "GoodWeES",
|
|
54
|
+
"name": "GoodWe",
|
|
55
|
+
"host": "192.168.1.50"
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Full example, with every section optional:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"platform": "GoodWeES",
|
|
64
|
+
"host": "192.168.1.50",
|
|
65
|
+
"pollInterval": 10,
|
|
66
|
+
"history": { "enabled": true, "rawInterval": 60, "rawRetentionDays": 180 },
|
|
67
|
+
"web": { "enabled": true, "port": 8582, "bind": "0.0.0.0", "allowPublic": false },
|
|
68
|
+
"alerts": {
|
|
69
|
+
"homekit": true,
|
|
70
|
+
"notifyRecovery": true,
|
|
71
|
+
"outage": { "enabled": true, "voltageThreshold": 100, "debounceSeconds": 30, "restoreSeconds": 60 },
|
|
72
|
+
"temperature": { "enabled": true, "inverterMax": 60, "batteryMax": 45, "hysteresis": 3, "cooldownMinutes": 30 }
|
|
73
|
+
},
|
|
74
|
+
"notify": {
|
|
75
|
+
"pushover": { "enabled": false, "token": "", "user": "", "device": "", "sound": "", "urgentPriority": 1, "quietDefault": false, "retry": 120, "expire": 1800 },
|
|
76
|
+
"ntfy": { "enabled": true, "server": "https://ntfy.sh", "topic": "choose-a-long-random-topic" },
|
|
77
|
+
"telegram": { "enabled": false, "botToken": "", "chatId": "" },
|
|
78
|
+
"webhook": { "enabled": false, "url": "https://example.com/hook", "authHeader": "" }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Where the data goes**
|
|
84
|
+
|
|
85
|
+
- The database is stored at `<Homebridge storage>/goodwe-es-data/goodwe.db` unless you set `history.dbPath`.
|
|
86
|
+
- Set `rawRetentionDays: 0` to keep raw readings forever.
|
|
87
|
+
|
|
88
|
+
**Secrets**
|
|
89
|
+
|
|
90
|
+
- Pushover keys, bot tokens, ntfy tokens and webhook headers live only in your Homebridge config.
|
|
91
|
+
- Anyone who knows an ntfy.sh topic can read it, so pick a long random one.
|
|
92
|
+
|
|
93
|
+
### Pushover
|
|
94
|
+
|
|
95
|
+
1. Install the Pushover app on your phone and sign in. Your **User Key** is shown on the [pushover.net](https://pushover.net) dashboard.
|
|
96
|
+
2. Create an application at [pushover.net/apps/build](https://pushover.net/apps/build) (name it, for example, "GoodWe"). Copy its **API Token**.
|
|
97
|
+
3. In the plugin settings, open *Canales push → Pushover*, enable it and paste the token and user key. Optionally set a device name (empty = all your devices) and a sound.
|
|
98
|
+
4. Use the *test notification* button on the settings page to check it.
|
|
99
|
+
|
|
100
|
+
Alert priorities:
|
|
101
|
+
|
|
102
|
+
| Alert | Pushover priority |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| Grid outage | `urgentPriority`: `1` (high, bypasses quiet hours, default) or `2` (emergency, repeats every `retry` seconds until acknowledged or until `expire` seconds pass; minimum retry 30 s, maximum expire 10800 s) |
|
|
105
|
+
| Grid restored, over-temperature | `0` (normal) |
|
|
106
|
+
| Temperature back to normal, test messages | `0`, or `-1` (no sound) when `quietDefault` is on |
|
|
107
|
+
|
|
108
|
+
### Dashboard and CSV
|
|
109
|
+
|
|
110
|
+
Open `http://<homebridge-ip>:8582/`. The page accepts these URL options:
|
|
111
|
+
|
|
112
|
+
| Option | Values |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `view` | `live`, `daily` |
|
|
115
|
+
| `mode` | `table`, `chart` |
|
|
116
|
+
| `compact` | `1` |
|
|
117
|
+
| `theme` | `dark`, `light` |
|
|
118
|
+
|
|
119
|
+
Example: `http://<homebridge-ip>:8582/?view=daily&mode=chart&compact=1`.
|
|
120
|
+
|
|
121
|
+
CSV export URL: `http://<homebridge-ip>:8582/export.csv?type=raw|daily|events&from=YYYY-MM-DD&to=YYYY-MM-DD&format=excel|std`.
|
|
122
|
+
|
|
123
|
+
By default the server only answers private addresses: RFC 1918 ranges, loopback and Tailscale's 100.64.0.0/10. Do not expose it to the internet.
|
|
124
|
+
|
|
125
|
+
### Outage detection
|
|
126
|
+
|
|
127
|
+
The grid counts as down when the inverter reports off-grid mode, or when grid voltage drops below `voltageThreshold`. Both the outage and the restoration must hold for the debounce time before an alert is sent. The "restored" message includes how long the outage lasted.
|
|
128
|
+
|
|
129
|
+
## Credits
|
|
130
|
+
|
|
131
|
+
The register map follows the open-source [goodwe](https://github.com/marcelblijleven/goodwe) Python library (ES family). This project is not affiliated with GoodWe.
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Español
|
|
140
|
+
|
|
141
|
+
Plugin de Homebridge que lee **localmente** los inversores híbridos **GoodWe ES/EM** por UDP (protocolo AA55, puerto 8899). No usa la nube y no tiene dependencias.
|
|
142
|
+
|
|
143
|
+
### Qué incluye
|
|
144
|
+
|
|
145
|
+
- **Sensores HomeKit**
|
|
146
|
+
- Potencias en W: solar, consumo de la casa, importación y exportación de red.
|
|
147
|
+
- Batería (SOC) y temperaturas del inversor y la batería.
|
|
148
|
+
- Acumulados del día en kWh: generación, consumo, importación, exportación, carga y descarga de batería.
|
|
149
|
+
- **Historial en SQLite** con intervalo y retención configurables, más un resumen diario que se conserva siempre.
|
|
150
|
+
- **Panel web en la red local** (puerto 8582), con vistas actual y diaria, en tabla o gráfico.
|
|
151
|
+
- **Exportación CSV** por rango de fechas, sin límite de filas.
|
|
152
|
+
- **Alertas**
|
|
153
|
+
- Cubren corte de luz (y su regreso) y temperatura alta.
|
|
154
|
+
- Se reciben por sensores de contacto en la app Casa, y opcionalmente por Pushover, ntfy, Telegram o un webhook.
|
|
155
|
+
|
|
156
|
+
Requiere **Node.js 22.13 o superior**. Instálalo buscando «GoodWe ES» en la pestaña *Plugins* de Homebridge y configúralo desde su página de ajustes; solo es obligatoria la IP del inversor. Los tokens (Pushover, Telegram, ntfy, webhook) se ingresan en la configuración de Homebridge y nunca se guardan en el código.
|
|
157
|
+
|
|
158
|
+
#### Pushover
|
|
159
|
+
|
|
160
|
+
1. Instala la app Pushover en el teléfono e inicia sesión. Tu **User Key** aparece en la página principal de [pushover.net](https://pushover.net).
|
|
161
|
+
2. Crea una aplicación en [pushover.net/apps/build](https://pushover.net/apps/build) (por ejemplo, «GoodWe») y copia su **API Token**.
|
|
162
|
+
3. En los ajustes del plugin, abre *Canales push → Pushover*, actívalo y pega el token y la user key. Opcionalmente indica un dispositivo (vacío = todos) y un sonido.
|
|
163
|
+
4. Prueba con el botón de notificación de prueba de la página de ajustes.
|
|
164
|
+
|
|
165
|
+
Prioridades: el corte de luz usa prioridad **alta** (1, suena aunque haya horario silencioso) o **emergencia** (2, se repite cada `retry` segundos hasta que la confirmes o pasen `expire` segundos). El regreso de la luz y la temperatura alta usan prioridad normal (0). La temperatura normalizada y las pruebas usan 0, o −1 (sin sonido) si activas «Avisos menores sin sonido».
|
|
166
|
+
|
|
167
|
+
Los sensores de energía aparecen como sensores de luz: el número que muestran es el valor en W o kWh, aunque la unidad diga «lux». Para verlos en el inicio de Homebridge, agrega el widget **Accesorios** y elige los sensores del GoodWe.
|
package/alerts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
// Grid-outage and over-temperature alerts, plus push channels (
|
|
3
|
-
// generic webhook). Uses the global fetch of Node >= 18; no dependencies.
|
|
2
|
+
// Grid-outage and over-temperature alerts, plus push channels (Pushover, ntfy,
|
|
3
|
+
// Telegram, generic webhook). Uses the global fetch of Node >= 18; no dependencies.
|
|
4
4
|
|
|
5
5
|
const REQUEST_TIMEOUT_MS = 10000;
|
|
6
6
|
|
|
@@ -39,8 +39,11 @@ class Notifier {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
channels() {
|
|
42
|
-
const { ntfy = {}, telegram = {}, webhook = {} } = this.config;
|
|
42
|
+
const { pushover = {}, ntfy = {}, telegram = {}, webhook = {} } = this.config;
|
|
43
43
|
const list = [];
|
|
44
|
+
if (pushover.enabled && pushover.token && pushover.user) {
|
|
45
|
+
list.push(['pushover', (m) => this.sendPushover(pushover, m)]);
|
|
46
|
+
}
|
|
44
47
|
if (ntfy.enabled && ntfy.topic) {
|
|
45
48
|
list.push(['ntfy', (m) => this.sendNtfy(ntfy, m)]);
|
|
46
49
|
}
|
|
@@ -68,6 +71,31 @@ class Notifier {
|
|
|
68
71
|
return results;
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
// Pushover priorities: urgent -> configurable (1 = high, bypasses quiet hours;
|
|
75
|
+
// 2 = emergency, repeats until acknowledged), high -> 0, default -> 0 or -1 (quiet).
|
|
76
|
+
sendPushover(cfg, msg) {
|
|
77
|
+
const urgent = [1, 2].includes(Number(cfg.urgentPriority)) ? Number(cfg.urgentPriority) : 1;
|
|
78
|
+
const priority = msg.priority === 'urgent' ? urgent : msg.priority === 'high' ? 0 : (cfg.quietDefault ? -1 : 0);
|
|
79
|
+
const body = new URLSearchParams({
|
|
80
|
+
token: cfg.token,
|
|
81
|
+
user: cfg.user,
|
|
82
|
+
title: String(msg.title || '').slice(0, 250),
|
|
83
|
+
message: String(msg.message || msg.title || '').slice(0, 1024),
|
|
84
|
+
priority: String(priority),
|
|
85
|
+
});
|
|
86
|
+
if (cfg.device) {
|
|
87
|
+
body.set('device', cfg.device);
|
|
88
|
+
}
|
|
89
|
+
if (cfg.sound) {
|
|
90
|
+
body.set('sound', cfg.sound);
|
|
91
|
+
}
|
|
92
|
+
if (priority === 2) {
|
|
93
|
+
body.set('retry', String(Math.max(30, Number(cfg.retry) || 120)));
|
|
94
|
+
body.set('expire', String(Math.min(10800, Number(cfg.expire) || 1800)));
|
|
95
|
+
}
|
|
96
|
+
return post('https://api.pushover.net/1/messages.json', body);
|
|
97
|
+
}
|
|
98
|
+
|
|
71
99
|
sendNtfy(cfg, msg) {
|
|
72
100
|
const server = (cfg.server || 'https://ntfy.sh').replace(/\/+$/, '');
|
|
73
101
|
const headers = { 'Content-Type': 'application/json' };
|
package/config.schema.json
CHANGED
|
@@ -88,6 +88,24 @@
|
|
|
88
88
|
"title": "Canales push",
|
|
89
89
|
"type": "object",
|
|
90
90
|
"properties": {
|
|
91
|
+
"pushover": {
|
|
92
|
+
"title": "Pushover",
|
|
93
|
+
"type": "object",
|
|
94
|
+
"properties": {
|
|
95
|
+
"enabled": { "title": "Activar", "type": "boolean", "default": false },
|
|
96
|
+
"token": { "title": "API token de la aplicación", "type": "string", "description": "Crea una aplicación en pushover.net/apps/build." },
|
|
97
|
+
"user": { "title": "User key", "type": "string", "description": "Aparece en tu página principal de pushover.net." },
|
|
98
|
+
"device": { "title": "Dispositivo (opcional)", "type": "string", "description": "Nombre del dispositivo en Pushover; vacío envía a todos." },
|
|
99
|
+
"sound": { "title": "Sonido (opcional)", "type": "string", "description": "Por ejemplo: pushover, siren, falling. Vacío usa el de la app." },
|
|
100
|
+
"urgentPriority": { "title": "Prioridad del corte de luz", "type": "integer", "default": 1, "oneOf": [
|
|
101
|
+
{ "title": "Alta (suena aunque haya horario silencioso)", "enum": [1] },
|
|
102
|
+
{ "title": "Emergencia (se repite hasta confirmarla)", "enum": [2] }
|
|
103
|
+
] },
|
|
104
|
+
"quietDefault": { "title": "Avisos menores sin sonido", "type": "boolean", "default": false },
|
|
105
|
+
"retry": { "title": "Emergencia: repetir cada (s)", "type": "integer", "default": 120, "minimum": 30 },
|
|
106
|
+
"expire": { "title": "Emergencia: dejar de repetir tras (s)", "type": "integer", "default": 1800, "maximum": 10800 }
|
|
107
|
+
}
|
|
108
|
+
},
|
|
91
109
|
"ntfy": {
|
|
92
110
|
"title": "ntfy",
|
|
93
111
|
"type": "object",
|