homebridge-rainforest-eagle3 1.0.0 → 1.2.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/README.md +119 -15
- package/config.schema.json +78 -0
- package/dist/eveCharacteristics.d.ts +7 -0
- package/dist/eveCharacteristics.d.ts.map +1 -1
- package/dist/eveCharacteristics.js +12 -0
- package/dist/eveCharacteristics.js.map +1 -1
- package/dist/exportMeterAccessory.d.ts +2 -0
- package/dist/exportMeterAccessory.d.ts.map +1 -1
- package/dist/exportMeterAccessory.js +13 -6
- package/dist/exportMeterAccessory.js.map +1 -1
- package/dist/gridMeterAccessory.d.ts +2 -0
- package/dist/gridMeterAccessory.d.ts.map +1 -1
- package/dist/gridMeterAccessory.js +13 -6
- package/dist/gridMeterAccessory.js.map +1 -1
- package/dist/matterEnergy.d.ts +176 -0
- package/dist/matterEnergy.d.ts.map +1 -0
- package/dist/matterEnergy.js +332 -0
- package/dist/matterEnergy.js.map +1 -0
- package/dist/platform.d.ts +13 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +64 -2
- package/dist/platform.js.map +1 -1
- package/dist/powerSwitch.d.ts +24 -0
- package/dist/powerSwitch.d.ts.map +1 -0
- package/dist/powerSwitch.js +70 -0
- package/dist/powerSwitch.js.map +1 -0
- package/dist/settings.d.ts +7 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/updatePolicy.d.ts +43 -0
- package/dist/updatePolicy.d.ts.map +1 -0
- package/dist/updatePolicy.js +115 -0
- package/dist/updatePolicy.js.map +1 -0
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# homebridge-rainforest-eagle3
|
|
2
|
+
[](LICENSE)
|
|
3
|
+
[](https://github.com/dacarson/homebridge-rainforest-eagle3/releases)
|
|
4
|
+
[](https://www.npmjs.com/package/homebridge-rainforest-eagle3)
|
|
2
5
|
|
|
3
|
-
A [Homebridge](https://homebridge.io) plugin for the [Rainforest Automation EAGLE-
|
|
6
|
+
A [Homebridge](https://homebridge.io) plugin for the [Rainforest Automation EAGLE-3](https://www.rainforestautomation.com) smart meter gateway. Exposes your utility grid meter as an **Eve Energy** accessory in Apple HomeKit, with real-time power demand, cumulative import energy, and native Eve app consumption history.
|
|
7
|
+
|
|
8
|
+
<img width="300" alt="Grid Meter - Export" src="https://github.com/user-attachments/assets/9f2bfed2-6ab8-45e0-ab5b-d5ac91f5a38a" />
|
|
9
|
+
<img width="300" alt="Grid Meter - Import" src="https://github.com/user-attachments/assets/3c0cba11-386a-4185-bd54-f1c0861454dc" />
|
|
4
10
|
|
|
5
11
|
---
|
|
6
12
|
|
|
@@ -9,10 +15,10 @@ A [Homebridge](https://homebridge.io) plugin for the [Rainforest Automation EAGL
|
|
|
9
15
|
- Real-time grid demand in Watts (visible in the Eve app and HomeKit detail view)
|
|
10
16
|
- Cumulative energy imported (kWh) as a lifetime total
|
|
11
17
|
- Optional **export meter** accessory for homes with solar net metering — shows real-time export watts and lifetime energy exported to the grid
|
|
18
|
+
- Optional: live watts and energy in the Apple Home **Energy** view via Matter (see [Apple Home Energy & Matter](#apple-home-energy--matter))
|
|
12
19
|
- Up to 7 days of native consumption/export history in the Eve app via [fakegato-history](https://github.com/simont77/fakegato-history)
|
|
13
|
-
- Polls the EAGLE-
|
|
20
|
+
- Polls the EAGLE-3 **local** HTTP API — no cloud account or internet required at runtime
|
|
14
21
|
- Stateless Basic Auth — no session management, no re-login lifecycle
|
|
15
|
-
- Designed to complement [homebridge-pvs6](https://github.com/dacarson/homebridge-pvs6) for a complete solar + grid picture in Apple Home
|
|
16
22
|
|
|
17
23
|
---
|
|
18
24
|
|
|
@@ -20,15 +26,17 @@ A [Homebridge](https://homebridge.io) plugin for the [Rainforest Automation EAGL
|
|
|
20
26
|
|
|
21
27
|
| Device | Status |
|
|
22
28
|
|---|---|
|
|
23
|
-
| Rainforest EAGLE-
|
|
24
|
-
| Rainforest EAGLE-
|
|
29
|
+
| Rainforest EAGLE-3 | Tested |
|
|
30
|
+
| Rainforest EAGLE-200 (RFA-Z114) | Expected compatible — uses the same local API; unverified |
|
|
25
31
|
| Original EAGLE (Z109) | Not supported — uses a different relay-server API |
|
|
26
32
|
|
|
27
33
|
---
|
|
28
34
|
|
|
29
35
|
## How It Works
|
|
30
36
|
|
|
31
|
-
The EAGLE-
|
|
37
|
+
The EAGLE-3 connects to your utility smart meter over ZigBee (HAN) and exposes live meter data over a local HTTP API. This plugin polls that API every `pollInterval` seconds and publishes the data as a HomeKit accessory. All communication is on your local network — no external services involved.
|
|
38
|
+
|
|
39
|
+
The EAGLE-3's embedded HTTP server requires HTTP/1.0. Standard HTTP libraries (axios, fetch) negotiate HTTP/1.1 and are incompatible, so the plugin uses raw TCP sockets to communicate with the device.
|
|
32
40
|
|
|
33
41
|
The accessory renders as a **smart plug** in Apple Home:
|
|
34
42
|
|
|
@@ -40,10 +48,10 @@ The accessory renders as a **smart plug** in Apple Home:
|
|
|
40
48
|
|
|
41
49
|
## Requirements
|
|
42
50
|
|
|
43
|
-
- [Homebridge](https://homebridge.io)
|
|
51
|
+
- [Homebridge](https://homebridge.io) v2.0 or later (v2.4.0+ and iOS 27+ if you want the optional Apple Home Energy view via Matter)
|
|
44
52
|
- Node.js 18 or later
|
|
45
|
-
- Rainforest EAGLE-
|
|
46
|
-
- The EAGLE-
|
|
53
|
+
- Rainforest EAGLE-3 on the same local network as your Homebridge host
|
|
54
|
+
- The EAGLE-3's **Cloud ID** and **Install Code** (printed on the label on the underside of the device)
|
|
47
55
|
|
|
48
56
|
---
|
|
49
57
|
|
|
@@ -100,17 +108,62 @@ With export meter enabled (for solar / net metering):
|
|
|
100
108
|
| Field | Type | Required | Default | Description |
|
|
101
109
|
|---|---|---|---|---|
|
|
102
110
|
| `platform` | string | yes | — | Must be `EAGLE` |
|
|
103
|
-
| `host` | string | no | `eagle-<cloudId>.local` | IP address or mDNS hostname of the EAGLE-
|
|
111
|
+
| `host` | string | no | `eagle-<cloudId>.local` | IP address or mDNS hostname of the EAGLE-3. Omit to use mDNS auto-discovery. |
|
|
104
112
|
| `cloudId` | string | yes | — | Cloud ID from the device label (6 hex characters, upper-left of label) |
|
|
105
113
|
| `installCode` | string | yes | — | Install Code from the device label (16 hex characters) |
|
|
106
114
|
| `pollInterval` | integer | no | `15` | Seconds between polls. Minimum enforced: `5` |
|
|
107
115
|
| `meterName` | string | no | `"Grid Meter"` | Display name for the import meter accessory. Defaults to `"Grid Meter - Import"` when `showExportMeter` is `true`. |
|
|
108
116
|
| `showExportMeter` | boolean | no | `false` | Register a second accessory showing power exported to the grid. |
|
|
109
117
|
| `exportMeterName` | string | no | `"Grid Meter - Export"` | Display name for the export meter accessory. |
|
|
118
|
+
| `matter` | boolean | no | `false` | Also publish the grid meter over Matter with live electrical measurements, so it shows watts on its tile in the Apple Home Energy view (see [Apple Home Energy & Matter](#apple-home-energy--matter)) |
|
|
119
|
+
| `evePowerUpdates` | string | no | `"throttled"` | How Eve Watts / Eve kWh are sent to HomeKit: `"throttled"`, `"pollOnly"` or `"live"` (see [HomeKit Updates](#homekit-updates)). |
|
|
120
|
+
| `minChangeWatts` | number | no | `25` | Throttled mode: minimum change in watts, since the last push, that pushes Eve Watts. |
|
|
121
|
+
| `minChangePercent` | number | no | `2` | Throttled mode: minimum change as a percentage of the last push. The larger of this and `minChangeWatts` applies. |
|
|
122
|
+
| `minChangeKwh` | number | no | `0.1` | Throttled mode: minimum change in kWh, since the last push, that pushes Eve kWh. |
|
|
123
|
+
| `maxIntervalSeconds` | number | no | `300` | Throttled mode: push anyway once this many seconds have passed since the last push. |
|
|
124
|
+
| `switchHoldSeconds` | number | no | `60` | How long a new On state must hold before it is reported. `0` disables the hold. |
|
|
125
|
+
|
|
126
|
+
### HomeKit Updates
|
|
127
|
+
|
|
128
|
+
The EAGLE is polled every `pollInterval` seconds and the readings differ slightly on nearly every poll. Pushing every value sends a HomeKit event per characteristic per poll, hundreds of events an hour, that every connected Home hub and device has to process. These settings reduce that traffic without breaking automations. They appear in the Homebridge UI under **HomeKit Updates**.
|
|
129
|
+
|
|
130
|
+
On startup the plugin polls right away and reports the current values immediately, in every mode.
|
|
131
|
+
|
|
132
|
+
#### Eve power and energy (`evePowerUpdates`)
|
|
133
|
+
|
|
134
|
+
Eve Watts and Eve kWh are Eve custom characteristics. Besides the Eve app showing them, **Eve and Home+ automations can trigger on or check these values** (for example "when power rises above 3 kW"). Choose a mode with that in mind:
|
|
135
|
+
|
|
136
|
+
| Mode | Traffic | Automations on these values |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| `throttled` (default) | Low | Keep working. Values are accurate to within the configured thresholds. |
|
|
139
|
+
| `pollOnly` | Lowest | **Triggers on these values stop working.** Use it only if no automation uses them. |
|
|
140
|
+
| `live` | High | Work, with every reading (the behavior before 1.2.0). |
|
|
141
|
+
|
|
142
|
+
- **throttled** pushes a value only when one of these is true:
|
|
143
|
+
- Eve Watts has changed by at least `max(minChangeWatts, minChangePercent% of the last value pushed)`, or has crossed to or from 0
|
|
144
|
+
- Eve kWh has changed by at least `minChangeKwh`
|
|
145
|
+
- `maxIntervalSeconds` (default 5 minutes) have passed since the last push for that value
|
|
146
|
+
- **pollOnly** removes notify support from these characteristics and never pushes them. The newest reading is still returned whenever an app reads the value, so the Eve app shows current figures when opened.
|
|
147
|
+
- **live** pushes every reading.
|
|
148
|
+
|
|
149
|
+
In every mode, reads return the newest reading, and Eve history (fakegato) still logs every poll.
|
|
150
|
+
|
|
151
|
+
#### On switches
|
|
152
|
+
|
|
153
|
+
The On characteristic of each meter is a standard HomeKit characteristic and is always pushed, so Home app automations keep working. To keep it from flapping on small or brief changes:
|
|
154
|
+
|
|
155
|
+
- **Deadband:** it turns on when power rises above **50 W** and off when it falls below **20 W**. Readings in between keep the current state.
|
|
156
|
+
- **Hold:** a new state must hold for `switchHoldSeconds` (default 60) before it is reported. A spike shorter than that never flips the switch. Set it to `0` to report changes on the next poll.
|
|
157
|
+
|
|
158
|
+
**Automations triggered by these switches can fire up to `switchHoldSeconds` (plus one poll interval) later than the underlying change.**
|
|
159
|
+
|
|
160
|
+
#### Logging
|
|
161
|
+
|
|
162
|
+
Suppressed Eve updates and held switch changes are logged at debug level. Unless `evePowerUpdates` is `live` and `switchHoldSeconds` is `0`, a one-line summary of sent vs. suppressed updates is logged every hour.
|
|
110
163
|
|
|
111
164
|
### Finding Your Credentials
|
|
112
165
|
|
|
113
|
-
Flip the EAGLE-
|
|
166
|
+
Flip the EAGLE-3 over and look at the label. You need:
|
|
114
167
|
|
|
115
168
|
- **Cloud ID** — 6-character hex string in the upper-left (e.g. `004792`)
|
|
116
169
|
- **Install Code** — 16-character hex string below the Cloud ID (e.g. `bfb0fc05f51a3932`)
|
|
@@ -125,7 +178,7 @@ The device is also reachable at `eagle-<cloudId>.local` via mDNS if you prefer n
|
|
|
125
178
|
|
|
126
179
|
| Characteristic | Source | Notes |
|
|
127
180
|
|---|---|---|
|
|
128
|
-
| On | `demand
|
|
181
|
+
| On | `demand` above 50 W / below 20 W | True when importing from the grid. Changes are held for `switchHoldSeconds`; see [On switches](#on-switches). |
|
|
129
182
|
| OutletInUse | Always `true` | Required by Eve Energy |
|
|
130
183
|
| Eve Watts | `max(0, demand) × 1000` | Import watts. Zero when net-exporting. |
|
|
131
184
|
| Eve kWh | `CurrentSummationDelivered` | Lifetime energy imported from grid |
|
|
@@ -134,7 +187,7 @@ The device is also reachable at `eagle-<cloudId>.local` via mDNS if you prefer n
|
|
|
134
187
|
|
|
135
188
|
| Characteristic | Source | Notes |
|
|
136
189
|
|---|---|---|
|
|
137
|
-
| On |
|
|
190
|
+
| On | export above 50 W / below 20 W | True when exporting to the grid. Changes are held for `switchHoldSeconds`; see [On switches](#on-switches). |
|
|
138
191
|
| OutletInUse | Always `true` | Required by Eve Energy |
|
|
139
192
|
| Eve Watts | `max(0, −demand) × 1000` | Export watts. Zero when not exporting. |
|
|
140
193
|
| Eve kWh | `CurrentSummationReceived` | Lifetime energy exported to grid. Shows `0` if the meter does not report this variable. |
|
|
@@ -145,12 +198,57 @@ The two accessories are mutually exclusive — at any given moment only one show
|
|
|
145
198
|
|
|
146
199
|
---
|
|
147
200
|
|
|
201
|
+
## Apple Home Energy & Matter
|
|
202
|
+
<table>
|
|
203
|
+
<td>
|
|
204
|
+
<img width="600" alt="MatterEnergy" src="https://github.com/user-attachments/assets/fcff5f12-54cb-4431-a944-8ac04c6e044f" />
|
|
205
|
+
<br><sub>Apple Energy view with other Energy accessories</sub>
|
|
206
|
+
</td>
|
|
207
|
+
</table>
|
|
208
|
+
|
|
209
|
+
Apple Home's native **Energy** view is driven by **Matter** electrical-measurement clusters, **not** by classic HomeKit/HAP characteristics. HAP has no power or energy characteristic at all, so the Eve characteristics above (which only Eve-class apps read) can never populate it — no matter how the HomeKit accessory is shaped.
|
|
210
|
+
|
|
211
|
+
With `"matter": true`, this plugin publishes a single **`ElectricalSensor`** Matter accessory named **"Grid"**, carrying live power and cumulative/periodic energy — no on/off, no controllable state, purely metering.
|
|
212
|
+
|
|
213
|
+
Power is sent in milliwatts, energy in milliwatt-hours, per the Matter spec. Matter's `activePower` sign convention is positive = the accessory is *drawing* power, negative = it's *supplying* power, which lines up directly with `InstantaneousDemand` — no sign flip needed.
|
|
214
|
+
|
|
215
|
+
**The grid meter is a single, bidirectional accessory on the Matter side**, even when `showExportMeter` splits Import and Export into two separate accessories in Eve/HomeKit — that split exists only because Eve's custom Energy characteristic can't represent a negative wattage. Matter's `activePower` attribute *is* signed, so power flips sign as the meter crosses between importing and exporting. Matter's cumulative/periodic *energy* attributes have no equivalent signed "net" value — Imported and Exported are always separate running totals per the Matter spec — so the Grid accessory reports both simultaneously.
|
|
216
|
+
|
|
217
|
+
Live power is updated on every poll. Energy is reported only when there is something new: the cumulative totals when they change (or every 15 minutes as a heartbeat), and periodic energy once per 15-minute period. When energy starts flowing again after an idle period, the periodic total is reported right away.
|
|
218
|
+
|
|
219
|
+
**Why a pure sensor and not an outlet:** this device type has no on/off cluster, so its tile in the Home app shows "Not Supported" as its headline status — Home's tile face wants a primary characteristic (on/off, a reading, etc.) to display, and a pure measurement cluster doesn't provide one. That tradeoff is accepted here: a fake on/off state isn't worth carrying for a tile headline, as long as the wattage still rolls into the Home aggregate and — via periodic energy — into the accessory's own Energy-view attribution, which it does either way.
|
|
220
|
+
|
|
221
|
+
### Enabling Matter
|
|
222
|
+
|
|
223
|
+
- **Homebridge 2.4.0+**
|
|
224
|
+
- **Matter enabled on this plugin's child bridge** — in the Homebridge UI: plugin settings → **Bridge Settings** → enable Matter, then pair the Matter bridge in the Home app
|
|
225
|
+
- **iOS/iPadOS 27+** on the device you use to view the Apple Home **Energy** view — earlier versions don't show it
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"platforms": [
|
|
230
|
+
{
|
|
231
|
+
"platform": "EAGLE",
|
|
232
|
+
"name": "EAGLE",
|
|
233
|
+
"cloudId": "004792",
|
|
234
|
+
"installCode": "bfb0fc05f51a3932",
|
|
235
|
+
"matter": true
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
If the Matter API isn't available (older Homebridge, or Matter not enabled), the plugin detects that, logs a single informational line, and continues to work exactly as before over HomeKit/Eve.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
148
245
|
## Error Handling
|
|
149
246
|
|
|
150
|
-
The plugin is designed to be resilient to transient EAGLE-
|
|
247
|
+
The plugin is designed to be resilient to transient EAGLE-3 failures:
|
|
151
248
|
|
|
152
249
|
- If the EAGLE is unreachable at startup, discovery retries every 30 seconds
|
|
153
|
-
-
|
|
250
|
+
- If the EAGLE responds but reports no electric meter device, discovery retries every 60 seconds
|
|
251
|
+
- Poll cycles are skipped (not fatal) on timeout, XML parse errors, HTTP 5xx responses, or when the meter's ZigBee connection status is not "connected"
|
|
154
252
|
- HTTP 401 triggers a 60-second backoff and an error log (check your credentials)
|
|
155
253
|
- The EAGLE's embedded HTTP server can be overwhelmed by frequent polling; the default 15-second interval is conservative by design
|
|
156
254
|
- HomeKit characteristics retain their last known-good values during outages
|
|
@@ -166,6 +264,12 @@ npm install
|
|
|
166
264
|
npm run build
|
|
167
265
|
```
|
|
168
266
|
|
|
267
|
+
To run the unit tests:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
npm test
|
|
271
|
+
```
|
|
272
|
+
|
|
169
273
|
To develop with live rebuilds:
|
|
170
274
|
|
|
171
275
|
```bash
|
package/config.schema.json
CHANGED
|
@@ -52,6 +52,58 @@
|
|
|
52
52
|
"type": "string",
|
|
53
53
|
"default": "Grid Meter - Export",
|
|
54
54
|
"description": "HomeKit display name for the export meter accessory. Only used when showExportMeter is true."
|
|
55
|
+
},
|
|
56
|
+
"matter": {
|
|
57
|
+
"title": "Show in the Apple Home Energy view (via Matter)",
|
|
58
|
+
"type": "boolean",
|
|
59
|
+
"default": false,
|
|
60
|
+
"description": "Also publish the grid meter over Matter as a single bidirectional electrical sensor with live power and cumulative/periodic energy, feeding your Apple Home Energy view (requires iOS/iPadOS 27+ to view). Requires Homebridge 2.4.0+ with Matter enabled on this plugin's child bridge; skipped safely otherwise."
|
|
61
|
+
},
|
|
62
|
+
"evePowerUpdates": {
|
|
63
|
+
"title": "Eve Power Updates",
|
|
64
|
+
"type": "string",
|
|
65
|
+
"default": "throttled",
|
|
66
|
+
"oneOf": [
|
|
67
|
+
{ "title": "Throttled — push meaningful changes (recommended)", "enum": ["throttled"] },
|
|
68
|
+
{ "title": "Poll only — never push (breaks Eve/Home+ triggers on these values)", "enum": ["pollOnly"] },
|
|
69
|
+
{ "title": "Live — push every poll (pre-1.2.0 behavior)", "enum": ["live"] }
|
|
70
|
+
],
|
|
71
|
+
"description": "How the Eve Watts and Eve kWh values are sent to HomeKit. Eve and Home+ automations can trigger on or check these values: Throttled keeps them working, accurate to within the thresholds below. Poll only gives the lowest traffic but automations triggered by these values will not fire, so use it only if no automation uses them."
|
|
72
|
+
},
|
|
73
|
+
"minChangeWatts": {
|
|
74
|
+
"title": "Minimum Change (W)",
|
|
75
|
+
"type": "number",
|
|
76
|
+
"default": 25,
|
|
77
|
+
"minimum": 0,
|
|
78
|
+
"description": "Throttled mode: push Eve Watts when power has changed by at least this many watts since the last push (or Minimum Change %, whichever is larger)."
|
|
79
|
+
},
|
|
80
|
+
"minChangePercent": {
|
|
81
|
+
"title": "Minimum Change (%)",
|
|
82
|
+
"type": "number",
|
|
83
|
+
"default": 2,
|
|
84
|
+
"minimum": 0,
|
|
85
|
+
"description": "Throttled mode: push Eve Watts when power has changed by at least this percentage of the last value pushed (or Minimum Change W, whichever is larger)."
|
|
86
|
+
},
|
|
87
|
+
"minChangeKwh": {
|
|
88
|
+
"title": "Minimum Change (kWh)",
|
|
89
|
+
"type": "number",
|
|
90
|
+
"default": 0.1,
|
|
91
|
+
"minimum": 0,
|
|
92
|
+
"description": "Throttled mode: push Eve kWh when the total has changed by at least this much since the last push."
|
|
93
|
+
},
|
|
94
|
+
"maxIntervalSeconds": {
|
|
95
|
+
"title": "Maximum Interval (seconds)",
|
|
96
|
+
"type": "number",
|
|
97
|
+
"default": 300,
|
|
98
|
+
"minimum": 0,
|
|
99
|
+
"description": "Throttled mode: push anyway once this long has passed since the last push, even if the change is small."
|
|
100
|
+
},
|
|
101
|
+
"switchHoldSeconds": {
|
|
102
|
+
"title": "On Switch Hold (seconds)",
|
|
103
|
+
"type": "number",
|
|
104
|
+
"default": 60,
|
|
105
|
+
"minimum": 0,
|
|
106
|
+
"description": "The meter's On switch (importing / exporting) changes only after the new state has held this long, so brief spikes don't flip it. Automations triggered by the switch can fire up to this long after the underlying change. 0 disables the hold."
|
|
55
107
|
}
|
|
56
108
|
},
|
|
57
109
|
"required": ["cloudId", "installCode"]
|
|
@@ -69,6 +121,32 @@
|
|
|
69
121
|
"condition": {
|
|
70
122
|
"functionBody": "return model.showExportMeter === true;"
|
|
71
123
|
}
|
|
124
|
+
},
|
|
125
|
+
{ "key": "matter" },
|
|
126
|
+
{
|
|
127
|
+
"type": "fieldset",
|
|
128
|
+
"title": "HomeKit Updates",
|
|
129
|
+
"expandable": true,
|
|
130
|
+
"items": [
|
|
131
|
+
{ "key": "evePowerUpdates" },
|
|
132
|
+
{
|
|
133
|
+
"key": "minChangeWatts",
|
|
134
|
+
"condition": { "functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';" }
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"key": "minChangePercent",
|
|
138
|
+
"condition": { "functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';" }
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"key": "minChangeKwh",
|
|
142
|
+
"condition": { "functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';" }
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"key": "maxIntervalSeconds",
|
|
146
|
+
"condition": { "functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';" }
|
|
147
|
+
},
|
|
148
|
+
{ "key": "switchHoldSeconds" }
|
|
149
|
+
]
|
|
72
150
|
}
|
|
73
151
|
]
|
|
74
152
|
}
|
|
@@ -11,4 +11,11 @@ export interface EveChars {
|
|
|
11
11
|
EveKWh: EveCharClass;
|
|
12
12
|
}
|
|
13
13
|
export declare function createEveCharacteristics(api: API): EveChars;
|
|
14
|
+
/**
|
|
15
|
+
* Adds or removes NOTIFY on an Eve characteristic. Applied to every instance,
|
|
16
|
+
* including ones restored from the accessory cache (which keep their cached
|
|
17
|
+
* props rather than the class defaults), so switching evePowerUpdates to or
|
|
18
|
+
* from pollOnly takes effect on restart.
|
|
19
|
+
*/
|
|
20
|
+
export declare function setEveNotify(characteristic: Characteristic, notify: boolean): void;
|
|
14
21
|
//# sourceMappingURL=eveCharacteristics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eveCharacteristics.d.ts","sourceRoot":"","sources":["../src/eveCharacteristics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,cAAc,EAAkB,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,uBAAuB,yCAAyC,CAAC;AAC9E,eAAO,MAAM,aAAa,yCAAyC,CAAC;AACpE,eAAO,MAAM,YAAY,yCAAyC,CAAC;AAGnE,MAAM,MAAM,YAAY,GAAG;IAAE,QAAO,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAuC3D"}
|
|
1
|
+
{"version":3,"file":"eveCharacteristics.d.ts","sourceRoot":"","sources":["../src/eveCharacteristics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,cAAc,EAAkB,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,uBAAuB,yCAAyC,CAAC;AAC9E,eAAO,MAAM,aAAa,yCAAyC,CAAC;AACpE,eAAO,MAAM,YAAY,yCAAyC,CAAC;AAGnE,MAAM,MAAM,YAAY,GAAG;IAAE,QAAO,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAuC3D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAIlF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EVE_KWH_UUID = exports.EVE_WATT_UUID = exports.EVE_ENERGY_SERVICE_UUID = void 0;
|
|
4
4
|
exports.createEveCharacteristics = createEveCharacteristics;
|
|
5
|
+
exports.setEveNotify = setEveNotify;
|
|
5
6
|
exports.EVE_ENERGY_SERVICE_UUID = 'E863F10A-079E-48FF-8F27-9C2605A29F52';
|
|
6
7
|
exports.EVE_WATT_UUID = 'E863F10D-079E-48FF-8F27-9C2605A29F52';
|
|
7
8
|
exports.EVE_KWH_UUID = 'E863F10C-079E-48FF-8F27-9C2605A29F52';
|
|
@@ -40,4 +41,15 @@ function createEveCharacteristics(api) {
|
|
|
40
41
|
EveKWh: EveKWh,
|
|
41
42
|
};
|
|
42
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Adds or removes NOTIFY on an Eve characteristic. Applied to every instance,
|
|
46
|
+
* including ones restored from the accessory cache (which keep their cached
|
|
47
|
+
* props rather than the class defaults), so switching evePowerUpdates to or
|
|
48
|
+
* from pollOnly takes effect on restart.
|
|
49
|
+
*/
|
|
50
|
+
function setEveNotify(characteristic, notify) {
|
|
51
|
+
characteristic.setProps({
|
|
52
|
+
perms: notify ? ["pr" /* Perms.PAIRED_READ */, "ev" /* Perms.NOTIFY */] : ["pr" /* Perms.PAIRED_READ */],
|
|
53
|
+
});
|
|
54
|
+
}
|
|
43
55
|
//# sourceMappingURL=eveCharacteristics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eveCharacteristics.js","sourceRoot":"","sources":["../src/eveCharacteristics.ts"],"names":[],"mappings":";;;AAcA,4DAuCC;
|
|
1
|
+
{"version":3,"file":"eveCharacteristics.js","sourceRoot":"","sources":["../src/eveCharacteristics.ts"],"names":[],"mappings":";;;AAcA,4DAuCC;AAQD,oCAIC;AA/DY,QAAA,uBAAuB,GAAG,sCAAsC,CAAC;AACjE,QAAA,aAAa,GAAG,sCAAsC,CAAC;AACvD,QAAA,YAAY,GAAG,sCAAsC,CAAC;AAUnE,SAAgB,wBAAwB,CAAC,GAAQ;IAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IAEpB,MAAM,QAAS,SAAQ,GAAG,CAAC,cAAc;QAGvC;YACE,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;gBAChC,MAAM,6BAAe;gBACrB,IAAI,EAAE,GAAa;gBACnB,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,GAAG;gBACZ,KAAK,EAAE,uDAAiC;aACzC,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACtC,CAAC;;IAZe,aAAI,GAAG,qBAAa,CAAC;IAevC,MAAM,MAAO,SAAQ,GAAG,CAAC,cAAc;QAGrC;YACE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE;gBAC5B,MAAM,6BAAe;gBACrB,IAAI,EAAE,KAAe;gBACrB,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,uDAAiC;aACzC,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACtC,CAAC;;IAZe,WAAI,GAAG,oBAAY,CAAC;IAetC,OAAO;QACL,QAAQ,EAAE,QAAmC;QAC7C,MAAM,EAAE,MAAiC;KAC1C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,cAA8B,EAAE,MAAe;IAC1E,cAAc,CAAC,QAAQ,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,uDAAiC,CAAC,CAAC,CAAC,8BAAmB;KACxE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -7,6 +7,8 @@ export declare class ExportMeterAccessory {
|
|
|
7
7
|
private readonly historyService;
|
|
8
8
|
private lastExportW;
|
|
9
9
|
private lastReceivedKwh;
|
|
10
|
+
private readonly key;
|
|
11
|
+
private readonly powerSwitch;
|
|
10
12
|
constructor(platform: EAGLEPlatform, accessory: PlatformAccessory, FakeGatoHistoryService: any, meterAddress: string);
|
|
11
13
|
updateValues(reading: MeterReading): void;
|
|
12
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exportMeterAccessory.d.ts","sourceRoot":"","sources":["../src/exportMeterAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"exportMeterAccessory.d.ts","sourceRoot":"","sources":["../src/exportMeterAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI7C,qBAAa,oBAAoB;IAW7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAV3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IAErC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAGvB,QAAQ,EAAE,aAAa,EACxC,SAAS,EAAE,iBAAiB,EAE5B,sBAAsB,EAAE,GAAG,EAC3B,YAAY,EAAE,MAAM;IAsDtB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;CAoB1C"}
|
|
@@ -11,6 +11,8 @@ class ExportMeterAccessory {
|
|
|
11
11
|
this.lastReceivedKwh = 0;
|
|
12
12
|
const { Characteristic, api } = platform;
|
|
13
13
|
const { EveWatts, EveKWh } = platform.eveChars;
|
|
14
|
+
this.key = `export:${accessory.displayName}`;
|
|
15
|
+
this.powerSwitch = platform.createPowerSwitch(this.key);
|
|
14
16
|
const infoService = accessory.getService(platform.Service.AccessoryInformation) ??
|
|
15
17
|
accessory.addService(platform.Service.AccessoryInformation);
|
|
16
18
|
infoService
|
|
@@ -25,12 +27,12 @@ class ExportMeterAccessory {
|
|
|
25
27
|
this.eveEnergyService = accessory.addService(new api.hap.Service(platform.exportMeterName, eveCharacteristics_1.EVE_ENERGY_SERVICE_UUID));
|
|
26
28
|
}
|
|
27
29
|
this.eveEnergyService.setCharacteristic(Characteristic.Name, platform.exportMeterName);
|
|
28
|
-
// On — true when the
|
|
30
|
+
// On — true when exporting to the grid (deadband + hold, see powerSwitch.ts)
|
|
29
31
|
this.eveEnergyService
|
|
30
32
|
.getCharacteristic(Characteristic.On)
|
|
31
|
-
.onGet(() => this.
|
|
33
|
+
.onGet(() => this.powerSwitch.state)
|
|
32
34
|
.onSet(async () => {
|
|
33
|
-
this.eveEnergyService.updateCharacteristic(Characteristic.On, this.
|
|
35
|
+
this.eveEnergyService.updateCharacteristic(Characteristic.On, this.powerSwitch.state);
|
|
34
36
|
});
|
|
35
37
|
this.eveEnergyService
|
|
36
38
|
.getCharacteristic(Characteristic.OutletInUse)
|
|
@@ -38,9 +40,11 @@ class ExportMeterAccessory {
|
|
|
38
40
|
this.eveEnergyService
|
|
39
41
|
.getCharacteristic(EveWatts)
|
|
40
42
|
.onGet(() => this.lastExportW);
|
|
43
|
+
(0, eveCharacteristics_1.setEveNotify)(this.eveEnergyService.getCharacteristic(EveWatts), platform.eveThrottle.notify);
|
|
41
44
|
this.eveEnergyService
|
|
42
45
|
.getCharacteristic(EveKWh)
|
|
43
46
|
.onGet(() => this.lastReceivedKwh);
|
|
47
|
+
(0, eveCharacteristics_1.setEveNotify)(this.eveEnergyService.getCharacteristic(EveKWh), platform.eveThrottle.notify);
|
|
44
48
|
this.historyService = new FakeGatoHistoryService('energy', accessory, {
|
|
45
49
|
storage: 'fs',
|
|
46
50
|
});
|
|
@@ -50,10 +54,13 @@ class ExportMeterAccessory {
|
|
|
50
54
|
const { EveWatts, EveKWh } = this.platform.eveChars;
|
|
51
55
|
this.lastExportW = Math.round(Math.max(0, -reading.demand_kw) * 1000 * 10) / 10;
|
|
52
56
|
this.lastReceivedKwh = reading.summation_received_kwh ?? 0;
|
|
53
|
-
this.
|
|
57
|
+
const on = this.powerSwitch.update(this.lastExportW);
|
|
58
|
+
if (on !== null) {
|
|
59
|
+
this.eveEnergyService.updateCharacteristic(Characteristic.On, on);
|
|
60
|
+
}
|
|
54
61
|
this.eveEnergyService.updateCharacteristic(Characteristic.OutletInUse, true);
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
62
|
+
this.platform.updateEve(this.eveEnergyService, EveWatts, `${this.key}:EveWatts`, this.lastExportW, 'W');
|
|
63
|
+
this.platform.updateEve(this.eveEnergyService, EveKWh, `${this.key}:EveKWh`, this.lastReceivedKwh, 'kWh');
|
|
57
64
|
this.historyService.addEntry({
|
|
58
65
|
time: Math.round(Date.now() / 1000),
|
|
59
66
|
power: this.lastExportW,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exportMeterAccessory.js","sourceRoot":"","sources":["../src/exportMeterAccessory.ts"],"names":[],"mappings":";;;AAGA,
|
|
1
|
+
{"version":3,"file":"exportMeterAccessory.js","sourceRoot":"","sources":["../src/exportMeterAccessory.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ export declare class GridMeterAccessory {
|
|
|
7
7
|
private readonly historyService;
|
|
8
8
|
private lastDemandW;
|
|
9
9
|
private lastDeliveredKwh;
|
|
10
|
+
private readonly key;
|
|
11
|
+
private readonly powerSwitch;
|
|
10
12
|
constructor(platform: EAGLEPlatform, accessory: PlatformAccessory, FakeGatoHistoryService: any, meterAddress: string);
|
|
11
13
|
updateValues(reading: MeterReading): void;
|
|
12
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridMeterAccessory.d.ts","sourceRoot":"","sources":["../src/gridMeterAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"gridMeterAccessory.d.ts","sourceRoot":"","sources":["../src/gridMeterAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI7C,qBAAa,kBAAkB;IAW3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAV3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IAErC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAGvB,QAAQ,EAAE,aAAa,EACxC,SAAS,EAAE,iBAAiB,EAE5B,sBAAsB,EAAE,GAAG,EAC3B,YAAY,EAAE,MAAM;IA8DtB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;CA2B1C"}
|
|
@@ -11,6 +11,8 @@ class GridMeterAccessory {
|
|
|
11
11
|
this.lastDeliveredKwh = 0;
|
|
12
12
|
const { Characteristic, api } = platform;
|
|
13
13
|
const { EveWatts, EveKWh } = platform.eveChars;
|
|
14
|
+
this.key = `import:${accessory.displayName}`;
|
|
15
|
+
this.powerSwitch = platform.createPowerSwitch(this.key);
|
|
14
16
|
// Accessory information service
|
|
15
17
|
const infoService = accessory.getService(platform.Service.AccessoryInformation) ??
|
|
16
18
|
accessory.addService(platform.Service.AccessoryInformation);
|
|
@@ -28,13 +30,13 @@ class GridMeterAccessory {
|
|
|
28
30
|
this.eveEnergyService = accessory.addService(new api.hap.Service(platform.meterName, eveCharacteristics_1.EVE_ENERGY_SERVICE_UUID));
|
|
29
31
|
}
|
|
30
32
|
this.eveEnergyService.setCharacteristic(Characteristic.Name, platform.meterName);
|
|
31
|
-
// On — true when grid
|
|
33
|
+
// On — true when importing from the grid (deadband + hold, see powerSwitch.ts)
|
|
32
34
|
this.eveEnergyService
|
|
33
35
|
.getCharacteristic(Characteristic.On)
|
|
34
|
-
.onGet(() => this.
|
|
36
|
+
.onGet(() => this.powerSwitch.state)
|
|
35
37
|
.onSet(async () => {
|
|
36
38
|
// Read-only: revert to polled state immediately
|
|
37
|
-
this.eveEnergyService.updateCharacteristic(Characteristic.On, this.
|
|
39
|
+
this.eveEnergyService.updateCharacteristic(Characteristic.On, this.powerSwitch.state);
|
|
38
40
|
});
|
|
39
41
|
// OutletInUse — always true (required by Eve Energy)
|
|
40
42
|
this.eveEnergyService
|
|
@@ -45,9 +47,11 @@ class GridMeterAccessory {
|
|
|
45
47
|
this.eveEnergyService
|
|
46
48
|
.getCharacteristic(EveWatts)
|
|
47
49
|
.onGet(() => this.lastDemandW);
|
|
50
|
+
(0, eveCharacteristics_1.setEveNotify)(this.eveEnergyService.getCharacteristic(EveWatts), platform.eveThrottle.notify);
|
|
48
51
|
this.eveEnergyService
|
|
49
52
|
.getCharacteristic(EveKWh)
|
|
50
53
|
.onGet(() => this.lastDeliveredKwh);
|
|
54
|
+
(0, eveCharacteristics_1.setEveNotify)(this.eveEnergyService.getCharacteristic(EveKWh), platform.eveThrottle.notify);
|
|
51
55
|
// fakegato-history: 'energy' type logs { time, power } in Watts
|
|
52
56
|
this.historyService = new FakeGatoHistoryService('energy', accessory, {
|
|
53
57
|
storage: 'fs',
|
|
@@ -58,10 +62,13 @@ class GridMeterAccessory {
|
|
|
58
62
|
const { EveWatts, EveKWh } = this.platform.eveChars;
|
|
59
63
|
this.lastDemandW = Math.round(Math.max(0, reading.demand_kw) * 1000 * 10) / 10;
|
|
60
64
|
this.lastDeliveredKwh = reading.summation_delivered_kwh;
|
|
61
|
-
this.
|
|
65
|
+
const on = this.powerSwitch.update(this.lastDemandW);
|
|
66
|
+
if (on !== null) {
|
|
67
|
+
this.eveEnergyService.updateCharacteristic(Characteristic.On, on);
|
|
68
|
+
}
|
|
62
69
|
this.eveEnergyService.updateCharacteristic(Characteristic.OutletInUse, true);
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
70
|
+
this.platform.updateEve(this.eveEnergyService, EveWatts, `${this.key}:EveWatts`, this.lastDemandW, 'W');
|
|
71
|
+
this.platform.updateEve(this.eveEnergyService, EveKWh, `${this.key}:EveKWh`, this.lastDeliveredKwh, 'kWh');
|
|
65
72
|
this.historyService.addEntry({
|
|
66
73
|
time: Math.round(Date.now() / 1000),
|
|
67
74
|
power: this.lastDemandW,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridMeterAccessory.js","sourceRoot":"","sources":["../src/gridMeterAccessory.ts"],"names":[],"mappings":";;;AAGA,
|
|
1
|
+
{"version":3,"file":"gridMeterAccessory.js","sourceRoot":"","sources":["../src/gridMeterAccessory.ts"],"names":[],"mappings":"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"}
|