homebridge-rainforest-eagle3 1.0.0 → 1.1.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 +59 -13
- package/config.schema.json +8 -1
- package/dist/matterEnergy.d.ts +151 -0
- package/dist/matterEnergy.d.ts.map +1 -0
- package/dist/matterEnergy.js +262 -0
- package/dist/matterEnergy.js.map +1 -0
- package/dist/platform.d.ts +2 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +26 -0
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/package.json +5 -5
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,18 @@ 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)) |
|
|
110
119
|
|
|
111
120
|
### Finding Your Credentials
|
|
112
121
|
|
|
113
|
-
Flip the EAGLE-
|
|
122
|
+
Flip the EAGLE-3 over and look at the label. You need:
|
|
114
123
|
|
|
115
124
|
- **Cloud ID** — 6-character hex string in the upper-left (e.g. `004792`)
|
|
116
125
|
- **Install Code** — 16-character hex string below the Cloud ID (e.g. `bfb0fc05f51a3932`)
|
|
@@ -145,12 +154,49 @@ The two accessories are mutually exclusive — at any given moment only one show
|
|
|
145
154
|
|
|
146
155
|
---
|
|
147
156
|
|
|
157
|
+
## Apple Home Energy & Matter
|
|
158
|
+
|
|
159
|
+
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.
|
|
160
|
+
|
|
161
|
+
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.
|
|
162
|
+
|
|
163
|
+
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.
|
|
164
|
+
|
|
165
|
+
**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.
|
|
166
|
+
|
|
167
|
+
**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.
|
|
168
|
+
|
|
169
|
+
### Enabling Matter
|
|
170
|
+
|
|
171
|
+
- **Homebridge 2.4.0+**
|
|
172
|
+
- **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
|
|
173
|
+
- **iOS/iPadOS 27+** on the device you use to view the Apple Home **Energy** view — earlier versions don't show it
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"platforms": [
|
|
178
|
+
{
|
|
179
|
+
"platform": "EAGLE",
|
|
180
|
+
"name": "EAGLE",
|
|
181
|
+
"cloudId": "004792",
|
|
182
|
+
"installCode": "bfb0fc05f51a3932",
|
|
183
|
+
"matter": true
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
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.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
148
193
|
## Error Handling
|
|
149
194
|
|
|
150
|
-
The plugin is designed to be resilient to transient EAGLE-
|
|
195
|
+
The plugin is designed to be resilient to transient EAGLE-3 failures:
|
|
151
196
|
|
|
152
197
|
- If the EAGLE is unreachable at startup, discovery retries every 30 seconds
|
|
153
|
-
-
|
|
198
|
+
- If the EAGLE responds but reports no electric meter device, discovery retries every 60 seconds
|
|
199
|
+
- 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
200
|
- HTTP 401 triggers a 60-second backoff and an error log (check your credentials)
|
|
155
201
|
- The EAGLE's embedded HTTP server can be overwhelmed by frequent polling; the default 15-second interval is conservative by design
|
|
156
202
|
- HomeKit characteristics retain their last known-good values during outages
|
package/config.schema.json
CHANGED
|
@@ -52,6 +52,12 @@
|
|
|
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."
|
|
55
61
|
}
|
|
56
62
|
},
|
|
57
63
|
"required": ["cloudId", "installCode"]
|
|
@@ -69,6 +75,7 @@
|
|
|
69
75
|
"condition": {
|
|
70
76
|
"functionBody": "return model.showExportMeter === true;"
|
|
71
77
|
}
|
|
72
|
-
}
|
|
78
|
+
},
|
|
79
|
+
{ "key": "matter" }
|
|
73
80
|
]
|
|
74
81
|
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* matterEnergy.ts
|
|
3
|
+
*
|
|
4
|
+
* Publishes the EAGLE grid meter to Matter controllers as a single
|
|
5
|
+
* bidirectional ElectricalSensor reporting live power and cumulative /
|
|
6
|
+
* periodic energy, so it feeds the Apple Home Energy view (iOS 27+).
|
|
7
|
+
*
|
|
8
|
+
* Background
|
|
9
|
+
* ----------
|
|
10
|
+
* Apple Home's Energy view is driven by Matter electrical-measurement
|
|
11
|
+
* clusters, not by classic HomeKit/HAP characteristics. HAP has no native
|
|
12
|
+
* power/energy characteristic, so the Eve custom characteristics this plugin
|
|
13
|
+
* also exposes (see eveCharacteristics.ts) are only ever read by Eve-class
|
|
14
|
+
* apps and never populate the native Energy tile.
|
|
15
|
+
*
|
|
16
|
+
* Device type: ElectricalSensor, not OnOffOutlet
|
|
17
|
+
* -----------------------------------------------
|
|
18
|
+
* A pure metering device type like ElectricalSensor has no actionable
|
|
19
|
+
* primary cluster, so its tile in the Home app shows "Not Supported" as its
|
|
20
|
+
* headline status. That's an accepted tradeoff here: the meter is not
|
|
21
|
+
* actually controllable, and an on/off state would only ever be a workaround
|
|
22
|
+
* for the tile headline — the wattage still rolls into the Home aggregate
|
|
23
|
+
* and (via PeriodicEnergy, below) into this accessory's own Energy-view
|
|
24
|
+
* attribution either way.
|
|
25
|
+
*
|
|
26
|
+
* powerW -> electricalPowerMeasurement.activePower (mW, signed)
|
|
27
|
+
* energyKWh -> electricalEnergyMeasurement.cumulativeEnergyImported.energy (mWh)
|
|
28
|
+
* and .cumulativeEnergyExported.energy, since the grid meter is
|
|
29
|
+
* bidirectional (see EnergyDirection below).
|
|
30
|
+
*
|
|
31
|
+
* Matter expresses power in milliwatts and energy in milliwatt-hours, hence
|
|
32
|
+
* the x1000 / x1,000,000 conversions. cumulativeEnergyImported/Exported are
|
|
33
|
+
* themselves structs (EnergyMeasurementStruct — { energy, startTimestamp?,
|
|
34
|
+
* endTimestamp?, ... }), not plain numbers: Homebridge's updateAccessoryState()
|
|
35
|
+
* accepts and normalizes a flat number for convenience, but the *initial*
|
|
36
|
+
* state passed at registration goes straight to matter.js's struct-typed
|
|
37
|
+
* attribute and must already be an object, or registration fails with
|
|
38
|
+
* "Cannot manage number because it is not a struct".
|
|
39
|
+
*
|
|
40
|
+
* Homebridge derives the mandatory cluster attributes (powerMode, accuracy,
|
|
41
|
+
* numberOfMeasurementTypes) and the feature-gated ElectricalEnergyMeasurement
|
|
42
|
+
* features from the declared state — declaring `cumulativeEnergyImported`
|
|
43
|
+
* selects the ImportedEnergy + CumulativeEnergy features, `cumulativeEnergyExported`
|
|
44
|
+
* selects ExportedEnergy + CumulativeEnergy, and both together (for a
|
|
45
|
+
* bidirectional meter) select both pairs at once. No voltage/current data is
|
|
46
|
+
* available from the EAGLE's local API, so only activePower is declared;
|
|
47
|
+
* voltage/activeCurrent are optional per the Matter spec and are simply
|
|
48
|
+
* omitted.
|
|
49
|
+
*
|
|
50
|
+
* Imported vs. exported energy is always two separate attributes
|
|
51
|
+
* ------------------------------------------------------------
|
|
52
|
+
* `activePower` is a signed attribute (positive = importing, negative =
|
|
53
|
+
* exporting), so this single bidirectional meter can report live direction
|
|
54
|
+
* with one accessory. Cumulative/periodic *energy* has no equivalent signed
|
|
55
|
+
* "net" attribute, though: Imported and Exported are distinct lifetime
|
|
56
|
+
* running totals per the Matter spec (you don't want a day's export and
|
|
57
|
+
* import cancelling each other out), so the meter declares both
|
|
58
|
+
* `cumulativeEnergyImported` and `cumulativeEnergyExported` (and their
|
|
59
|
+
* periodic counterparts) together on the same cluster. This is how the grid
|
|
60
|
+
* meter is published as a single Matter accessory even though it remains two
|
|
61
|
+
* separate accessories in Eve/HomeKit (Grid Meter - Import / Grid Meter -
|
|
62
|
+
* Export) when `showExportMeter` is enabled, since that split is purely
|
|
63
|
+
* about Eve's inability to represent a negative watt value, not a Matter
|
|
64
|
+
* limitation.
|
|
65
|
+
*
|
|
66
|
+
* Cumulative vs. periodic energy
|
|
67
|
+
* ------------------------------
|
|
68
|
+
* Alongside the cumulative (lifetime) total, this module also declares the
|
|
69
|
+
* PeriodicEnergy feature (`periodicEnergyImported`/`periodicEnergyExported`)
|
|
70
|
+
* — a per-interval delta with its own start/end timestamps. Per prior art in
|
|
71
|
+
* homebridge-shelly-matter (github.com/keremerkan/homebridge-shelly-matter,
|
|
72
|
+
* shellyAccessory.ts), this is what drives Apple Home's per-device energy
|
|
73
|
+
* attribution in the Energy view, not the cumulative total alone. Matter
|
|
74
|
+
* features compose once at registration, so PeriodicEnergy must already be
|
|
75
|
+
* present in the *initial* cluster state passed to registerPlatformAccessories()
|
|
76
|
+
* — declaring it for the first time in a later updateAccessoryState() call
|
|
77
|
+
* would not retroactively add the feature. buildClusters() therefore seeds a
|
|
78
|
+
* zero-energy periodic fragment (no timestamps yet) on its very first call,
|
|
79
|
+
* which is always the one register() makes, before any real reading exists
|
|
80
|
+
* to diff against; every call after that computes a real delta against the
|
|
81
|
+
* last *periodic* baseline (not the last poll), throttled to at most once
|
|
82
|
+
* per MIN_PERIODIC_INTERVAL_S so a short poll interval (default 15s, minimum
|
|
83
|
+
* 5s) doesn't turn into excessive Matter event/state churn compared to a
|
|
84
|
+
* device that naturally reports once a minute. Imported and exported
|
|
85
|
+
* baselines are tracked independently, since either can advance while the
|
|
86
|
+
* other sits idle.
|
|
87
|
+
*
|
|
88
|
+
* Requirements
|
|
89
|
+
* ------------
|
|
90
|
+
* - Homebridge 2.4.0+
|
|
91
|
+
* - Matter enabled on this plugin's child bridge (Homebridge UI ->
|
|
92
|
+
* plugin settings -> Bridge Settings -> enable Matter)
|
|
93
|
+
* - iOS/iPadOS 27+ on the device used to view the Apple Home Energy view
|
|
94
|
+
*
|
|
95
|
+
* Everything here is feature-detected and guarded: on a Homebridge build
|
|
96
|
+
* without the Matter API, or with Matter disabled, isSupported() returns
|
|
97
|
+
* false and the plugin runs HAP/Eve-only exactly as before.
|
|
98
|
+
*/
|
|
99
|
+
import type { API, Logger } from 'homebridge';
|
|
100
|
+
export type EnergyDirection = 'imported' | 'exported' | 'bidirectional';
|
|
101
|
+
export interface EnergyReadings {
|
|
102
|
+
/** Signed for a 'bidirectional' meter (positive = importing, negative = exporting). */
|
|
103
|
+
powerW: number;
|
|
104
|
+
/** Required when direction is 'imported' or 'bidirectional'. */
|
|
105
|
+
importedEnergyKWh?: number;
|
|
106
|
+
/** Required when direction is 'exported' or 'bidirectional'. */
|
|
107
|
+
exportedEnergyKWh?: number;
|
|
108
|
+
}
|
|
109
|
+
export declare class MatterEnergyBridge {
|
|
110
|
+
private readonly log;
|
|
111
|
+
private readonly direction;
|
|
112
|
+
private static readonly MIN_PERIODIC_INTERVAL_S;
|
|
113
|
+
private readonly api;
|
|
114
|
+
private uuid;
|
|
115
|
+
private registered;
|
|
116
|
+
private warnedUpdate;
|
|
117
|
+
private periodicState;
|
|
118
|
+
constructor(api: API, log: Logger, direction: EnergyDirection);
|
|
119
|
+
/**
|
|
120
|
+
* Whether this Homebridge build exposes everything needed to publish this
|
|
121
|
+
* meter. Logs at debug level so unsupported builds stay quiet.
|
|
122
|
+
*/
|
|
123
|
+
isSupported(): boolean;
|
|
124
|
+
private buildClusters;
|
|
125
|
+
/**
|
|
126
|
+
* Compute (or, between periodic reports, just return the last computed)
|
|
127
|
+
* periodic-energy fragment for one energy kind. The very first call —
|
|
128
|
+
* always from register(), before any real reading exists — seeds a
|
|
129
|
+
* zero-energy fragment with no timestamps, purely so the PeriodicEnergy
|
|
130
|
+
* feature composes at registration. Every call after that reports a real
|
|
131
|
+
* delta against the last periodic baseline once MIN_PERIODIC_INTERVAL_S
|
|
132
|
+
* has elapsed.
|
|
133
|
+
*/
|
|
134
|
+
private computePeriodic;
|
|
135
|
+
/**
|
|
136
|
+
* Register this meter as a Matter electrical sensor.
|
|
137
|
+
*
|
|
138
|
+
* @param seedKey - unique per-meter key used to derive this accessory's
|
|
139
|
+
* Matter UUID, distinct from the HAP accessory's UUID
|
|
140
|
+
* @param displayName
|
|
141
|
+
* @param serialNumber
|
|
142
|
+
* @param readings - initial readings to seed the clusters with
|
|
143
|
+
*/
|
|
144
|
+
register(seedKey: string, displayName: string, serialNumber: string, readings: EnergyReadings): Promise<boolean>;
|
|
145
|
+
/**
|
|
146
|
+
* Push fresh readings to the registered Matter accessory. No-op until
|
|
147
|
+
* registration has succeeded.
|
|
148
|
+
*/
|
|
149
|
+
update(readings: EnergyReadings): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=matterEnergy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterEnergy.d.ts","sourceRoot":"","sources":["../src/matterEnergy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAkB9C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAmDD,qBAAa,kBAAkB;IAmB3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAnB5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAM;IAErD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAS;IAM7B,OAAO,CAAC,aAAa,CAGnB;gBAGA,GAAG,EAAE,GAAG,EACS,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,eAAe;IAK7C;;;OAGG;IACH,WAAW,IAAI,OAAO;IAiBtB,OAAO,CAAC,aAAa;IAkBrB;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BtH;;;OAGG;IACG,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAwBtD"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* matterEnergy.ts
|
|
4
|
+
*
|
|
5
|
+
* Publishes the EAGLE grid meter to Matter controllers as a single
|
|
6
|
+
* bidirectional ElectricalSensor reporting live power and cumulative /
|
|
7
|
+
* periodic energy, so it feeds the Apple Home Energy view (iOS 27+).
|
|
8
|
+
*
|
|
9
|
+
* Background
|
|
10
|
+
* ----------
|
|
11
|
+
* Apple Home's Energy view is driven by Matter electrical-measurement
|
|
12
|
+
* clusters, not by classic HomeKit/HAP characteristics. HAP has no native
|
|
13
|
+
* power/energy characteristic, so the Eve custom characteristics this plugin
|
|
14
|
+
* also exposes (see eveCharacteristics.ts) are only ever read by Eve-class
|
|
15
|
+
* apps and never populate the native Energy tile.
|
|
16
|
+
*
|
|
17
|
+
* Device type: ElectricalSensor, not OnOffOutlet
|
|
18
|
+
* -----------------------------------------------
|
|
19
|
+
* A pure metering device type like ElectricalSensor has no actionable
|
|
20
|
+
* primary cluster, so its tile in the Home app shows "Not Supported" as its
|
|
21
|
+
* headline status. That's an accepted tradeoff here: the meter is not
|
|
22
|
+
* actually controllable, and an on/off state would only ever be a workaround
|
|
23
|
+
* for the tile headline — the wattage still rolls into the Home aggregate
|
|
24
|
+
* and (via PeriodicEnergy, below) into this accessory's own Energy-view
|
|
25
|
+
* attribution either way.
|
|
26
|
+
*
|
|
27
|
+
* powerW -> electricalPowerMeasurement.activePower (mW, signed)
|
|
28
|
+
* energyKWh -> electricalEnergyMeasurement.cumulativeEnergyImported.energy (mWh)
|
|
29
|
+
* and .cumulativeEnergyExported.energy, since the grid meter is
|
|
30
|
+
* bidirectional (see EnergyDirection below).
|
|
31
|
+
*
|
|
32
|
+
* Matter expresses power in milliwatts and energy in milliwatt-hours, hence
|
|
33
|
+
* the x1000 / x1,000,000 conversions. cumulativeEnergyImported/Exported are
|
|
34
|
+
* themselves structs (EnergyMeasurementStruct — { energy, startTimestamp?,
|
|
35
|
+
* endTimestamp?, ... }), not plain numbers: Homebridge's updateAccessoryState()
|
|
36
|
+
* accepts and normalizes a flat number for convenience, but the *initial*
|
|
37
|
+
* state passed at registration goes straight to matter.js's struct-typed
|
|
38
|
+
* attribute and must already be an object, or registration fails with
|
|
39
|
+
* "Cannot manage number because it is not a struct".
|
|
40
|
+
*
|
|
41
|
+
* Homebridge derives the mandatory cluster attributes (powerMode, accuracy,
|
|
42
|
+
* numberOfMeasurementTypes) and the feature-gated ElectricalEnergyMeasurement
|
|
43
|
+
* features from the declared state — declaring `cumulativeEnergyImported`
|
|
44
|
+
* selects the ImportedEnergy + CumulativeEnergy features, `cumulativeEnergyExported`
|
|
45
|
+
* selects ExportedEnergy + CumulativeEnergy, and both together (for a
|
|
46
|
+
* bidirectional meter) select both pairs at once. No voltage/current data is
|
|
47
|
+
* available from the EAGLE's local API, so only activePower is declared;
|
|
48
|
+
* voltage/activeCurrent are optional per the Matter spec and are simply
|
|
49
|
+
* omitted.
|
|
50
|
+
*
|
|
51
|
+
* Imported vs. exported energy is always two separate attributes
|
|
52
|
+
* ------------------------------------------------------------
|
|
53
|
+
* `activePower` is a signed attribute (positive = importing, negative =
|
|
54
|
+
* exporting), so this single bidirectional meter can report live direction
|
|
55
|
+
* with one accessory. Cumulative/periodic *energy* has no equivalent signed
|
|
56
|
+
* "net" attribute, though: Imported and Exported are distinct lifetime
|
|
57
|
+
* running totals per the Matter spec (you don't want a day's export and
|
|
58
|
+
* import cancelling each other out), so the meter declares both
|
|
59
|
+
* `cumulativeEnergyImported` and `cumulativeEnergyExported` (and their
|
|
60
|
+
* periodic counterparts) together on the same cluster. This is how the grid
|
|
61
|
+
* meter is published as a single Matter accessory even though it remains two
|
|
62
|
+
* separate accessories in Eve/HomeKit (Grid Meter - Import / Grid Meter -
|
|
63
|
+
* Export) when `showExportMeter` is enabled, since that split is purely
|
|
64
|
+
* about Eve's inability to represent a negative watt value, not a Matter
|
|
65
|
+
* limitation.
|
|
66
|
+
*
|
|
67
|
+
* Cumulative vs. periodic energy
|
|
68
|
+
* ------------------------------
|
|
69
|
+
* Alongside the cumulative (lifetime) total, this module also declares the
|
|
70
|
+
* PeriodicEnergy feature (`periodicEnergyImported`/`periodicEnergyExported`)
|
|
71
|
+
* — a per-interval delta with its own start/end timestamps. Per prior art in
|
|
72
|
+
* homebridge-shelly-matter (github.com/keremerkan/homebridge-shelly-matter,
|
|
73
|
+
* shellyAccessory.ts), this is what drives Apple Home's per-device energy
|
|
74
|
+
* attribution in the Energy view, not the cumulative total alone. Matter
|
|
75
|
+
* features compose once at registration, so PeriodicEnergy must already be
|
|
76
|
+
* present in the *initial* cluster state passed to registerPlatformAccessories()
|
|
77
|
+
* — declaring it for the first time in a later updateAccessoryState() call
|
|
78
|
+
* would not retroactively add the feature. buildClusters() therefore seeds a
|
|
79
|
+
* zero-energy periodic fragment (no timestamps yet) on its very first call,
|
|
80
|
+
* which is always the one register() makes, before any real reading exists
|
|
81
|
+
* to diff against; every call after that computes a real delta against the
|
|
82
|
+
* last *periodic* baseline (not the last poll), throttled to at most once
|
|
83
|
+
* per MIN_PERIODIC_INTERVAL_S so a short poll interval (default 15s, minimum
|
|
84
|
+
* 5s) doesn't turn into excessive Matter event/state churn compared to a
|
|
85
|
+
* device that naturally reports once a minute. Imported and exported
|
|
86
|
+
* baselines are tracked independently, since either can advance while the
|
|
87
|
+
* other sits idle.
|
|
88
|
+
*
|
|
89
|
+
* Requirements
|
|
90
|
+
* ------------
|
|
91
|
+
* - Homebridge 2.4.0+
|
|
92
|
+
* - Matter enabled on this plugin's child bridge (Homebridge UI ->
|
|
93
|
+
* plugin settings -> Bridge Settings -> enable Matter)
|
|
94
|
+
* - iOS/iPadOS 27+ on the device used to view the Apple Home Energy view
|
|
95
|
+
*
|
|
96
|
+
* Everything here is feature-detected and guarded: on a Homebridge build
|
|
97
|
+
* without the Matter API, or with Matter disabled, isSupported() returns
|
|
98
|
+
* false and the plugin runs HAP/Eve-only exactly as before.
|
|
99
|
+
*/
|
|
100
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
101
|
+
exports.MatterEnergyBridge = void 0;
|
|
102
|
+
const settings_1 = require("./settings");
|
|
103
|
+
/** Matter expresses power in milliwatts. */
|
|
104
|
+
function wToMilliW(value) {
|
|
105
|
+
const n = Number(value);
|
|
106
|
+
return Number.isFinite(n) ? Math.round(n * 1000) : 0;
|
|
107
|
+
}
|
|
108
|
+
/** Matter expresses energy in milliwatt-hours; EAGLE readings are in kWh. */
|
|
109
|
+
function kWhToMilliWh(value) {
|
|
110
|
+
const n = Number(value);
|
|
111
|
+
return Number.isFinite(n) ? Math.round(Math.max(0, n) * 1000000) : 0;
|
|
112
|
+
}
|
|
113
|
+
class MatterEnergyBridge {
|
|
114
|
+
constructor(api, log, direction) {
|
|
115
|
+
this.log = log;
|
|
116
|
+
this.direction = direction;
|
|
117
|
+
this.uuid = null;
|
|
118
|
+
this.registered = false;
|
|
119
|
+
this.warnedUpdate = false;
|
|
120
|
+
// Periodic-energy bookkeeping — see the "Cumulative vs. periodic energy"
|
|
121
|
+
// note at the top of this file. Tracked per energy kind so the
|
|
122
|
+
// bidirectional meter can advance its imported and exported deltas
|
|
123
|
+
// independently.
|
|
124
|
+
this.periodicState = {
|
|
125
|
+
imported: { baselineKWh: null, timestampS: null, last: { energy: 0 } },
|
|
126
|
+
exported: { baselineKWh: null, timestampS: null, last: { energy: 0 } },
|
|
127
|
+
};
|
|
128
|
+
this.api = api;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Whether this Homebridge build exposes everything needed to publish this
|
|
132
|
+
* meter. Logs at debug level so unsupported builds stay quiet.
|
|
133
|
+
*/
|
|
134
|
+
isSupported() {
|
|
135
|
+
const matter = this.api.matter;
|
|
136
|
+
if (!matter) {
|
|
137
|
+
this.log.debug('[matter] api.matter unavailable — Matter energy export disabled. Requires Homebridge 2.4.0+ with Matter enabled on this plugin\'s child bridge.');
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (!matter.deviceTypes?.ElectricalSensor) {
|
|
141
|
+
this.log.debug('[matter] api.matter.deviceTypes.ElectricalSensor unavailable — Matter energy export disabled. Requires a newer Homebridge build.');
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (typeof matter.registerPlatformAccessories !== 'function' || typeof matter.updateAccessoryState !== 'function') {
|
|
145
|
+
this.log.debug('[matter] Matter registration/update API unavailable — Matter energy export disabled.');
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
buildClusters(r) {
|
|
151
|
+
const energyField = {};
|
|
152
|
+
if (this.direction === 'imported' || this.direction === 'bidirectional') {
|
|
153
|
+
energyField.cumulativeEnergyImported = { energy: kWhToMilliWh(r.importedEnergyKWh ?? 0) };
|
|
154
|
+
energyField.periodicEnergyImported = this.computePeriodic('imported', r.importedEnergyKWh ?? 0);
|
|
155
|
+
}
|
|
156
|
+
if (this.direction === 'exported' || this.direction === 'bidirectional') {
|
|
157
|
+
energyField.cumulativeEnergyExported = { energy: kWhToMilliWh(r.exportedEnergyKWh ?? 0) };
|
|
158
|
+
energyField.periodicEnergyExported = this.computePeriodic('exported', r.exportedEnergyKWh ?? 0);
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
electricalPowerMeasurement: { activePower: wToMilliW(r.powerW) },
|
|
162
|
+
electricalEnergyMeasurement: energyField,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Compute (or, between periodic reports, just return the last computed)
|
|
167
|
+
* periodic-energy fragment for one energy kind. The very first call —
|
|
168
|
+
* always from register(), before any real reading exists — seeds a
|
|
169
|
+
* zero-energy fragment with no timestamps, purely so the PeriodicEnergy
|
|
170
|
+
* feature composes at registration. Every call after that reports a real
|
|
171
|
+
* delta against the last periodic baseline once MIN_PERIODIC_INTERVAL_S
|
|
172
|
+
* has elapsed.
|
|
173
|
+
*/
|
|
174
|
+
computePeriodic(kind, energyKWh) {
|
|
175
|
+
const state = this.periodicState[kind];
|
|
176
|
+
const nowS = Math.floor(Date.now() / 1000);
|
|
177
|
+
if (state.baselineKWh === null || state.timestampS === null) {
|
|
178
|
+
state.baselineKWh = energyKWh;
|
|
179
|
+
state.timestampS = nowS;
|
|
180
|
+
return state.last;
|
|
181
|
+
}
|
|
182
|
+
if (nowS - state.timestampS >= MatterEnergyBridge.MIN_PERIODIC_INTERVAL_S) {
|
|
183
|
+
const deltaKWh = Math.max(0, energyKWh - state.baselineKWh);
|
|
184
|
+
state.last = {
|
|
185
|
+
energy: kWhToMilliWh(deltaKWh),
|
|
186
|
+
startTimestamp: state.timestampS,
|
|
187
|
+
endTimestamp: nowS,
|
|
188
|
+
};
|
|
189
|
+
state.baselineKWh = energyKWh;
|
|
190
|
+
state.timestampS = nowS;
|
|
191
|
+
}
|
|
192
|
+
return state.last;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Register this meter as a Matter electrical sensor.
|
|
196
|
+
*
|
|
197
|
+
* @param seedKey - unique per-meter key used to derive this accessory's
|
|
198
|
+
* Matter UUID, distinct from the HAP accessory's UUID
|
|
199
|
+
* @param displayName
|
|
200
|
+
* @param serialNumber
|
|
201
|
+
* @param readings - initial readings to seed the clusters with
|
|
202
|
+
*/
|
|
203
|
+
async register(seedKey, displayName, serialNumber, readings) {
|
|
204
|
+
if (!this.isSupported())
|
|
205
|
+
return false;
|
|
206
|
+
const matter = this.api.matter;
|
|
207
|
+
this.uuid = matter.uuid.generate(`${settings_1.PLUGIN_NAME}:matter:${seedKey}`);
|
|
208
|
+
const accessory = {
|
|
209
|
+
UUID: this.uuid,
|
|
210
|
+
displayName,
|
|
211
|
+
deviceType: matter.deviceTypes.ElectricalSensor,
|
|
212
|
+
serialNumber,
|
|
213
|
+
manufacturer: 'Rainforest Automation',
|
|
214
|
+
model: 'EAGLE-3',
|
|
215
|
+
clusters: this.buildClusters(readings),
|
|
216
|
+
};
|
|
217
|
+
try {
|
|
218
|
+
await matter.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
|
|
219
|
+
this.registered = true;
|
|
220
|
+
this.log.info(`[matter] Published "${displayName}" as a Matter electrical sensor — live power should feed the Apple Home Energy view.`);
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
this.log.warn(`[matter] Failed to register Matter accessory for "${displayName}" (${err instanceof Error ? err.message : err}). Continuing with HomeKit/Eve only.`);
|
|
225
|
+
this.registered = false;
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Push fresh readings to the registered Matter accessory. No-op until
|
|
231
|
+
* registration has succeeded.
|
|
232
|
+
*/
|
|
233
|
+
async update(readings) {
|
|
234
|
+
if (!this.registered || !this.uuid)
|
|
235
|
+
return;
|
|
236
|
+
const matter = this.api.matter;
|
|
237
|
+
if (!matter)
|
|
238
|
+
return;
|
|
239
|
+
const clusters = this.buildClusters(readings);
|
|
240
|
+
try {
|
|
241
|
+
await Promise.all([
|
|
242
|
+
matter.updateAccessoryState(this.uuid, 'electricalPowerMeasurement', clusters.electricalPowerMeasurement),
|
|
243
|
+
matter.updateAccessoryState(this.uuid, 'electricalEnergyMeasurement', clusters.electricalEnergyMeasurement),
|
|
244
|
+
]);
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
// Log the first failure at warn, the rest at debug, so a persistently
|
|
248
|
+
// unhappy Matter server can't flood the log on every poll.
|
|
249
|
+
const message = `[matter] Failed to update Matter state: ${err instanceof Error ? err.message : err}`;
|
|
250
|
+
if (!this.warnedUpdate) {
|
|
251
|
+
this.warnedUpdate = true;
|
|
252
|
+
this.log.warn(message);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.log.debug(message);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
exports.MatterEnergyBridge = MatterEnergyBridge;
|
|
261
|
+
MatterEnergyBridge.MIN_PERIODIC_INTERVAL_S = 60;
|
|
262
|
+
//# sourceMappingURL=matterEnergy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterEnergy.js","sourceRoot":"","sources":["../src/matterEnergy.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -10,10 +10,12 @@ export declare class EAGLEPlatform implements DynamicPlatformPlugin {
|
|
|
10
10
|
readonly meterName: string;
|
|
11
11
|
readonly showExportMeter: boolean;
|
|
12
12
|
readonly exportMeterName: string;
|
|
13
|
+
readonly matterEnabled: boolean;
|
|
13
14
|
private readonly client;
|
|
14
15
|
private readonly pollIntervalMs;
|
|
15
16
|
private gridMeterAccessory?;
|
|
16
17
|
private exportMeterAccessory?;
|
|
18
|
+
private gridMatterBridge?;
|
|
17
19
|
private pollTimer?;
|
|
18
20
|
private pollInFlight;
|
|
19
21
|
private backedOff;
|
package/dist/platform.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,OAAO,EACR,MAAM,YAAY,CAAC;AAMpB,OAAO,EAA4B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,OAAO,EACR,MAAM,YAAY,CAAC;AAMpB,OAAO,EAA4B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQ1E,qBAAa,aAAc,YAAW,qBAAqB;aA2BvC,GAAG,EAAE,MAAM;aAEX,GAAG,EAAE,GAAG;IA5B1B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAC;IACxC,SAAgB,cAAc,EAAE,OAAO,cAAc,CAAC;IAEtD,SAAgB,WAAW,EAAE,iBAAiB,EAAE,CAAM;IACtD,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,eAAe,EAAE,MAAM,CAAC;IACxC,SAAgB,aAAa,EAAE,OAAO,CAAC;IAEvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,oBAAoB,CAAC,CAAuB;IAMpD,OAAO,CAAC,gBAAgB,CAAC,CAAqB;IAC9C,OAAO,CAAC,SAAS,CAAC,CAAiC;IACnD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;gBAGR,GAAG,EAAE,MAAM,EAC3B,MAAM,EAAE,cAAc,EACN,GAAG,EAAE,GAAG;IA2D1B,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAKtD,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,0BAA0B;IAuElC,OAAO,CAAC,YAAY;IAkDpB,OAAO,CAAC,YAAY;CAOrB"}
|
package/dist/platform.js
CHANGED
|
@@ -6,6 +6,7 @@ const eagleClient_1 = require("./eagleClient");
|
|
|
6
6
|
const gridMeterAccessory_1 = require("./gridMeterAccessory");
|
|
7
7
|
const exportMeterAccessory_1 = require("./exportMeterAccessory");
|
|
8
8
|
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
9
|
+
const matterEnergy_1 = require("./matterEnergy");
|
|
9
10
|
const MIN_POLL_INTERVAL = 5;
|
|
10
11
|
const DISCOVER_RETRY_MS = 30000;
|
|
11
12
|
const NO_METER_RETRY_MS = 60000;
|
|
@@ -29,6 +30,7 @@ class EAGLEPlatform {
|
|
|
29
30
|
this.showExportMeter = false;
|
|
30
31
|
this.meterName = 'Grid Meter';
|
|
31
32
|
this.exportMeterName = 'Grid Meter - Export';
|
|
33
|
+
this.matterEnabled = false;
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
36
|
const host = eagleConfig.host || `eagle-${eagleConfig.cloudId}.local`;
|
|
@@ -44,6 +46,7 @@ class EAGLEPlatform {
|
|
|
44
46
|
this.showExportMeter = eagleConfig.showExportMeter ?? false;
|
|
45
47
|
this.exportMeterName = eagleConfig.exportMeterName ?? 'Grid Meter - Export';
|
|
46
48
|
this.meterName = eagleConfig.meterName ?? (this.showExportMeter ? 'Grid Meter - Import' : 'Grid Meter');
|
|
49
|
+
this.matterEnabled = eagleConfig.matter === true;
|
|
47
50
|
this.client = new eagleClient_1.EagleClient(host, eagleConfig.cloudId, eagleConfig.installCode, log);
|
|
48
51
|
this.log.info('Finished initializing platform:', config.name ?? settings_1.PLATFORM_NAME);
|
|
49
52
|
this.api.on('didFinishLaunching', () => {
|
|
@@ -117,6 +120,24 @@ class EAGLEPlatform {
|
|
|
117
120
|
this.log.info('Removing stale export meter accessory');
|
|
118
121
|
this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [existingExport]);
|
|
119
122
|
}
|
|
123
|
+
// --- Matter (optional) ---
|
|
124
|
+
// Independent of showExportMeter: the grid meter is bidirectional on the
|
|
125
|
+
// Matter side regardless of whether Import/Export are split into two
|
|
126
|
+
// HomeKit/Eve accessories.
|
|
127
|
+
if (this.matterEnabled) {
|
|
128
|
+
const bridge = new matterEnergy_1.MatterEnergyBridge(this.api, this.log, 'bidirectional');
|
|
129
|
+
if (bridge.isSupported()) {
|
|
130
|
+
this.gridMatterBridge = bridge;
|
|
131
|
+
bridge.register(`${meterAddress}-grid-net`, 'Grid', meterAddress.replace(/^0x/i, ''), {
|
|
132
|
+
powerW: 0,
|
|
133
|
+
importedEnergyKWh: 0,
|
|
134
|
+
exportedEnergyKWh: 0,
|
|
135
|
+
}).catch(() => { });
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
this.log.info('[matter] Config option "matter" is enabled, but the Matter API is unavailable. It needs a Homebridge build with the ElectricalSensor device type, with Matter enabled on this plugin\'s child bridge. Continuing with HomeKit/Eve only.');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
120
141
|
}
|
|
121
142
|
startPolling(meterAddress) {
|
|
122
143
|
this.pollTimer = setInterval(async () => {
|
|
@@ -133,6 +154,11 @@ class EAGLEPlatform {
|
|
|
133
154
|
const reading = await this.client.queryMeter(meterAddress);
|
|
134
155
|
this.gridMeterAccessory?.updateValues(reading);
|
|
135
156
|
this.exportMeterAccessory?.updateValues(reading);
|
|
157
|
+
this.gridMatterBridge?.update({
|
|
158
|
+
powerW: reading.demand_kw * 1000,
|
|
159
|
+
importedEnergyKWh: reading.summation_delivered_kwh,
|
|
160
|
+
exportedEnergyKWh: reading.summation_received_kwh ?? 0,
|
|
161
|
+
}).catch(() => { });
|
|
136
162
|
}
|
|
137
163
|
catch (err) {
|
|
138
164
|
if (err instanceof eagleClient_1.HttpError) {
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":";;;AAUA,yCAAqE;AACrE,+CAAuD;AACvD,6DAA0D;AAC1D,iEAA8D;AAC9D,6DAA0E;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/dist/settings.d.ts
CHANGED
package/dist/settings.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,aAAa,UAAU,CAAC;AACrC,eAAO,MAAM,WAAW,iCAAiC,CAAC;AAE1D,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,aAAa,UAAU,CAAC;AACrC,eAAO,MAAM,WAAW,iCAAiC,CAAC;AAE1D,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-rainforest-eagle3",
|
|
3
3
|
"displayName": "Eagle 3",
|
|
4
|
-
"version": "1.
|
|
5
|
-
"description": "Homebridge plugin for Rainforest EAGLE-
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"description": "Homebridge plugin for Rainforest EAGLE-3 smart meter — Eve Energy accessory with fakegato history.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "David Carson",
|
|
8
8
|
"email": "dacarson@gmail.com",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=18.0.0",
|
|
21
|
-
"homebridge": ">=
|
|
21
|
+
"homebridge": ">=2.0.0"
|
|
22
22
|
},
|
|
23
23
|
"main": "dist/index.js",
|
|
24
24
|
"files": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"energy"
|
|
41
41
|
],
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"homebridge": ">=
|
|
43
|
+
"homebridge": ">=2.0.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"fakegato-history": "^0.6.7",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
53
53
|
"@typescript-eslint/parser": "^7.0.0",
|
|
54
54
|
"eslint": "^8.57.0",
|
|
55
|
-
"homebridge": "^
|
|
55
|
+
"homebridge": "^2.0.0",
|
|
56
56
|
"nodemon": "^3.0.0",
|
|
57
57
|
"rimraf": "^5.0.0",
|
|
58
58
|
"typescript": "^5.4.0"
|