homebridge-pvs6 1.2.0 → 1.4.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 +40 -2
- package/config.schema.json +6 -0
- package/dist/matterEnergy.d.ts +152 -0
- package/dist/matterEnergy.d.ts.map +1 -0
- package/dist/matterEnergy.js +263 -0
- package/dist/matterEnergy.js.map +1 -0
- package/dist/platform.d.ts +5 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +82 -15
- package/dist/platform.js.map +1 -1
- package/dist/pvs6DiscoveryCache.d.ts +5 -0
- package/dist/pvs6DiscoveryCache.d.ts.map +1 -0
- package/dist/pvs6DiscoveryCache.js +73 -0
- package/dist/pvs6DiscoveryCache.js.map +1 -0
- package/dist/settings.d.ts +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/solarAccessory.d.ts +2 -1
- package/dist/solarAccessory.d.ts.map +1 -1
- package/dist/solarAccessory.js +24 -1
- package/dist/solarAccessory.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# homebridge-pvs6
|
|
2
|
+
[](LICENSE)
|
|
3
|
+
[](https://github.com/dacarson/homebridge-pvs6/releases)
|
|
4
|
+
[](https://www.npmjs.com/package/homebridge-pvs6)
|
|
2
5
|
|
|
3
6
|
A [Homebridge](https://homebridge.io) plugin for the [SunStrong PVS6](https://sunstrong.com) solar monitoring system. Exposes solar production and grid metering as **Eve Energy** accessories in Apple HomeKit, with real-time power, cumulative energy, and native Eve app history.
|
|
4
7
|
|
|
@@ -26,7 +29,7 @@ A [Homebridge](https://homebridge.io) plugin for the [SunStrong PVS6](https://su
|
|
|
26
29
|
- Polls the PVS6 **local** FCGI API — no SunStrong Connect, no cloud dependency
|
|
27
30
|
- **Auto-discovers** the PVS6 on your local network via mDNS — no IP address or serial number required in config
|
|
28
31
|
- Automatically identifies production and consumption CT meters from the PVS6 device list
|
|
29
|
-
-
|
|
32
|
+
- Optional: live watts in the Apple Home **Energy** view via Matter (see [Apple Home Energy & Matter](#apple-home-energy--matter))
|
|
30
33
|
|
|
31
34
|
---
|
|
32
35
|
|
|
@@ -62,7 +65,7 @@ Grid Import and Grid Export are always registered together — enabling `accesso
|
|
|
62
65
|
|
|
63
66
|
## Requirements
|
|
64
67
|
|
|
65
|
-
- [Homebridge](https://homebridge.io) v2.0 or later
|
|
68
|
+
- [Homebridge](https://homebridge.io) v2.0 or later (v2.3.0+ if you want the optional Apple Home Energy view via Matter)
|
|
66
69
|
- Node.js 18 or later
|
|
67
70
|
- SunStrong PVS6 on the same local network as your Homebridge host
|
|
68
71
|
|
|
@@ -132,6 +135,7 @@ Uncheck **Auto Discover** and supply the host and serial number directly. This s
|
|
|
132
135
|
"host": "pvs.local",
|
|
133
136
|
"serialNumber": "ZT231385000549A1234",
|
|
134
137
|
"pollInterval": 10,
|
|
138
|
+
"matter": true,
|
|
135
139
|
"accessories": {
|
|
136
140
|
"grid": true,
|
|
137
141
|
"homeConsumption": true
|
|
@@ -154,6 +158,7 @@ Uncheck **Auto Discover** and supply the host and serial number directly. This s
|
|
|
154
158
|
| `host` | string | no* | — | IP address or hostname of the PVS6. Used only when `autoDiscover` is `false` |
|
|
155
159
|
| `serialNumber` | string | no* | — | Full PVS6 serial number. The last 5 characters are used as the API password. Used only when `autoDiscover` is `false` |
|
|
156
160
|
| `pollInterval` | integer | no | `10` | Seconds between polls. Minimum enforced: `5` |
|
|
161
|
+
| `matter` | boolean | no | `false` | Also publish each enabled 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)) |
|
|
157
162
|
| `accessories.grid` | boolean | no | `true` | Enable the Grid Import + Grid Export accessory pair. Set `false` to disable both |
|
|
158
163
|
| `accessories.homeConsumption` | boolean | no | `false` | Enable the Home Consumption accessory. Opt-in; off by default |
|
|
159
164
|
| `solarName` | string | no | `"Solar Production"` | HomeKit display name for the Solar Production accessory |
|
|
@@ -213,6 +218,39 @@ The derived kWh formula is exact without a battery: solar energy either goes to
|
|
|
213
218
|
|
|
214
219
|
---
|
|
215
220
|
|
|
221
|
+
## Apple Home Energy & Matter
|
|
222
|
+
|
|
223
|
+
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.
|
|
224
|
+
|
|
225
|
+
With `"matter": true`, this plugin publishes an **`ElectricalSensor`** Matter accessory for Solar Production and Grid, carrying live power and cumulative/periodic energy — no on/off, no controllable state, purely metering:
|
|
226
|
+
|
|
227
|
+
| Meter | Matter accessory | Matter power attribute | Matter energy attributes |
|
|
228
|
+
|---|---|---|---|
|
|
229
|
+
| Solar Production | "Solar Production" | `electricalPowerMeasurement.activePower` (always negative — see below) | `electricalEnergyMeasurement.cumulativeEnergyExported` |
|
|
230
|
+
| Grid | "Grid" | `electricalPowerMeasurement.activePower` (signed: positive = importing, negative = exporting) | `electricalEnergyMeasurement.cumulativeEnergyImported` **and** `cumulativeEnergyExported`, together |
|
|
231
|
+
|
|
232
|
+
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 — Solar Production only ever supplies (so its wattage is negated before being sent), and Grid does both depending on live direction.
|
|
233
|
+
|
|
234
|
+
**Home Consumption is intentionally not published over Matter.** Its energy is mathematically derived from the other two (`homeConsumptionKWh = pvEnergyKWh + gridImportKWh − gridExportKWh`, see [How It Works](#how-it-works)) rather than an independent measurement, so exposing all three to Apple Home's own aggregate power total risked double-counting rather than isolating grid draw. Home Consumption still works exactly as before in Eve/HomeKit.
|
|
235
|
+
|
|
236
|
+
**Grid Import and Grid Export stay two separate accessories in Eve/HomeKit** (see [HomeKit Accessories](#homekit-accessories) below) — that split exists only because Eve's custom Energy characteristic can't represent a negative wattage. Matter's `activePower` attribute *is* signed, so on the Matter side the grid meter is published as a single **"Grid"** accessory instead, with power flipping 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 on the one accessory rather than needing two.
|
|
237
|
+
|
|
238
|
+
**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. An earlier version of this feature used Matter's `OnOffOutlet` device type specifically to get a tile headline (the same approach [homebridge-chargepoint](https://github.com/dacarson/homebridge-chargepoint) uses), at the cost of declaring a fake on/off state that couldn't actually be switched. That tradeoff was reversed: the tile headline isn't worth carrying dead on/off state for, as long as the wattage still rolls into the Home aggregate and — via periodic energy, below — into each accessory's own Energy-view attribution, which it does either way.
|
|
239
|
+
|
|
240
|
+
**Cumulative and periodic energy:** each meter reports both the lifetime total (`cumulativeEnergyImported`/`Exported`) and a periodic delta (`periodicEnergyImported`/`Exported`, at most once a minute) with its own start/end timestamps. The periodic figure is what drives Apple Home's per-device energy attribution in the Energy view, not the cumulative total alone.
|
|
241
|
+
|
|
242
|
+
Requirements:
|
|
243
|
+
|
|
244
|
+
- **Homebridge 2.3.0 or later**
|
|
245
|
+
- **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
|
|
246
|
+
- An Apple Home setup on **iOS/tvOS 26 or later** for the Energy view itself
|
|
247
|
+
|
|
248
|
+
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.
|
|
249
|
+
|
|
250
|
+
**Upgrading from an earlier version:** since this changes the Matter device type (and merges Grid Import/Export into one accessory), Apple Home will likely need the old Matter tiles removed and the Matter bridge re-paired to pick up the new endpoints cleanly.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
216
254
|
## Error Handling
|
|
217
255
|
|
|
218
256
|
The plugin is designed to be resilient to transient PVS6 failures:
|
package/config.schema.json
CHANGED
|
@@ -35,6 +35,12 @@
|
|
|
35
35
|
"minimum": 5,
|
|
36
36
|
"description": "How often to poll the PVS6 for new data. Minimum 5 seconds."
|
|
37
37
|
},
|
|
38
|
+
"matter": {
|
|
39
|
+
"title": "Show in the Apple Home Energy view (via Matter)",
|
|
40
|
+
"type": "boolean",
|
|
41
|
+
"default": false,
|
|
42
|
+
"description": "Also publish Solar and Grid (import/export combined) over Matter as electrical sensors with live power and cumulative/periodic energy, feeding your Apple Home Energy view. Home Consumption is not published over Matter, since its energy is derived from Solar + Grid rather than an independent measurement. Requires Homebridge 2.3.0+ with Matter enabled on this plugin's child bridge; skipped safely otherwise."
|
|
43
|
+
},
|
|
38
44
|
"accessories": {
|
|
39
45
|
"title": "Accessories",
|
|
40
46
|
"type": "object",
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* matterEnergy.ts
|
|
3
|
+
*
|
|
4
|
+
* Publishes a PVS6 meter (solar, grid, home consumption) to Matter
|
|
5
|
+
* controllers as an ElectricalSensor reporting live power and cumulative /
|
|
6
|
+
* periodic energy, so it feeds the Apple Home Energy view (iOS 26+).
|
|
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
|
+
* An earlier version of this feature declared these accessories as
|
|
19
|
+
* OnOffOutlet so their tile would show a headline status (a pure metering
|
|
20
|
+
* device type like ElectricalSensor has no actionable primary cluster, and
|
|
21
|
+
* its tile showed "Not Supported" as a result — confirmed live). That's
|
|
22
|
+
* reverted here: none of these meters are actually controllable, the on/off
|
|
23
|
+
* state was only ever a workaround for the tile headline, and the "Not
|
|
24
|
+
* Supported" tile is an accepted tradeoff as long as the wattage still rolls
|
|
25
|
+
* into the Home aggregate and (via PeriodicEnergy, below) into this
|
|
26
|
+
* accessory's own Energy-view attribution — which it does.
|
|
27
|
+
*
|
|
28
|
+
* powerW -> electricalPowerMeasurement.activePower (mW, signed)
|
|
29
|
+
* energyKWh -> electricalEnergyMeasurement.cumulativeEnergyImported.energy (mWh)
|
|
30
|
+
* and/or .cumulativeEnergyExported.energy, depending on this
|
|
31
|
+
* meter's direction (see EnergyDirection below).
|
|
32
|
+
*
|
|
33
|
+
* Matter expresses power in milliwatts and energy in milliwatt-hours, hence
|
|
34
|
+
* the x1000 / x1,000,000 conversions. cumulativeEnergyImported/Exported are
|
|
35
|
+
* themselves structs (EnergyMeasurementStruct — { energy, startTimestamp?,
|
|
36
|
+
* endTimestamp?, ... }), not plain numbers: Homebridge's updateAccessoryState()
|
|
37
|
+
* accepts and normalizes a flat number for convenience, but the *initial*
|
|
38
|
+
* state passed at registration goes straight to matter.js's struct-typed
|
|
39
|
+
* attribute and must already be an object, or registration fails with
|
|
40
|
+
* "Cannot manage number because it is not a struct".
|
|
41
|
+
*
|
|
42
|
+
* Homebridge derives the mandatory cluster attributes (powerMode, accuracy,
|
|
43
|
+
* numberOfMeasurementTypes) and the feature-gated ElectricalEnergyMeasurement
|
|
44
|
+
* features from the declared state — declaring `cumulativeEnergyImported`
|
|
45
|
+
* selects the ImportedEnergy + CumulativeEnergy features, `cumulativeEnergyExported`
|
|
46
|
+
* selects ExportedEnergy + CumulativeEnergy, and both together (for a
|
|
47
|
+
* bidirectional meter) select both pairs at once. No voltage/current data is
|
|
48
|
+
* available from the PVS6 varserver reliably enough to publish, so only
|
|
49
|
+
* activePower is declared; voltage/activeCurrent are optional per the
|
|
50
|
+
* Matter spec and are simply omitted.
|
|
51
|
+
*
|
|
52
|
+
* Imported vs. exported energy is always two separate attributes
|
|
53
|
+
* ------------------------------------------------------------
|
|
54
|
+
* `activePower` is a signed attribute (positive = importing, negative =
|
|
55
|
+
* exporting), so a single bidirectional meter — the grid meter — can report
|
|
56
|
+
* live direction with one accessory. Cumulative/periodic *energy* has no
|
|
57
|
+
* equivalent signed "net" attribute, though: Imported and Exported are
|
|
58
|
+
* distinct lifetime running totals per the Matter spec (you don't want a
|
|
59
|
+
* day's production and consumption cancelling each other out), so a
|
|
60
|
+
* bidirectional meter still declares both `cumulativeEnergyImported` and
|
|
61
|
+
* `cumulativeEnergyExported` (and their periodic counterparts) together on
|
|
62
|
+
* the same cluster. See EnergyDirection's 'bidirectional' case below — this
|
|
63
|
+
* is how the grid meter is published as a single Matter accessory even
|
|
64
|
+
* though it remains two separate accessories in Eve/HomeKit (Grid Import /
|
|
65
|
+
* Grid Export), since that split is purely about Eve's inability to
|
|
66
|
+
* represent a negative watt value, not a Matter limitation.
|
|
67
|
+
*
|
|
68
|
+
* Cumulative vs. periodic energy
|
|
69
|
+
* ------------------------------
|
|
70
|
+
* Alongside the cumulative (lifetime) total, this module also declares the
|
|
71
|
+
* PeriodicEnergy feature (`periodicEnergyImported`/`periodicEnergyExported`)
|
|
72
|
+
* — a per-interval delta with its own start/end timestamps. Per prior art in
|
|
73
|
+
* homebridge-shelly-matter (github.com/keremerkan/homebridge-shelly-matter,
|
|
74
|
+
* shellyAccessory.ts), this is what drives Apple Home's per-device energy
|
|
75
|
+
* attribution in the Energy view, not the cumulative total alone. Matter
|
|
76
|
+
* features compose once at registration, so PeriodicEnergy must already be
|
|
77
|
+
* present in the *initial* cluster state passed to registerPlatformAccessories()
|
|
78
|
+
* — declaring it for the first time in a later updateAccessoryState() call
|
|
79
|
+
* would not retroactively add the feature. buildClusters() therefore seeds a
|
|
80
|
+
* zero-energy periodic fragment (no timestamps yet) on its very first call,
|
|
81
|
+
* which is always the one register() makes, before any real reading exists
|
|
82
|
+
* to diff against; every call after that computes a real delta against the
|
|
83
|
+
* last *periodic* baseline (not the last poll), throttled to at most once
|
|
84
|
+
* per MIN_PERIODIC_INTERVAL_S so a short poll interval (default 10s, minimum
|
|
85
|
+
* 5s) doesn't turn into excessive Matter event/state churn compared to a
|
|
86
|
+
* device that naturally reports once a minute. A bidirectional meter tracks
|
|
87
|
+
* imported and exported baselines independently, since either can advance
|
|
88
|
+
* while the other sits idle.
|
|
89
|
+
*
|
|
90
|
+
* Requirements
|
|
91
|
+
* ------------
|
|
92
|
+
* - Homebridge 2.3.0+
|
|
93
|
+
* - Matter enabled on this plugin's child bridge (Homebridge UI ->
|
|
94
|
+
* plugin settings -> Bridge Settings -> enable Matter)
|
|
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
|
+
import type { API, Logger } from 'homebridge';
|
|
101
|
+
export type EnergyDirection = 'imported' | 'exported' | 'bidirectional';
|
|
102
|
+
export interface EnergyReadings {
|
|
103
|
+
/** Signed for a 'bidirectional' meter (positive = importing, negative = exporting). */
|
|
104
|
+
powerW: number;
|
|
105
|
+
/** Required when direction is 'imported' or 'bidirectional'. */
|
|
106
|
+
importedEnergyKWh?: number;
|
|
107
|
+
/** Required when direction is 'exported' or 'bidirectional'. */
|
|
108
|
+
exportedEnergyKWh?: number;
|
|
109
|
+
}
|
|
110
|
+
export declare class MatterEnergyBridge {
|
|
111
|
+
private readonly log;
|
|
112
|
+
private readonly direction;
|
|
113
|
+
private static readonly MIN_PERIODIC_INTERVAL_S;
|
|
114
|
+
private readonly api;
|
|
115
|
+
private uuid;
|
|
116
|
+
private registered;
|
|
117
|
+
private warnedUpdate;
|
|
118
|
+
private periodicState;
|
|
119
|
+
constructor(api: API, log: Logger, direction: EnergyDirection);
|
|
120
|
+
/**
|
|
121
|
+
* Whether this Homebridge build exposes everything needed to publish this
|
|
122
|
+
* meter. Logs at debug level so unsupported builds stay quiet.
|
|
123
|
+
*/
|
|
124
|
+
isSupported(): boolean;
|
|
125
|
+
private buildClusters;
|
|
126
|
+
/**
|
|
127
|
+
* Compute (or, between periodic reports, just return the last computed)
|
|
128
|
+
* periodic-energy fragment for one energy kind. The very first call —
|
|
129
|
+
* always from register(), before any real reading exists — seeds a
|
|
130
|
+
* zero-energy fragment with no timestamps, purely so the PeriodicEnergy
|
|
131
|
+
* feature composes at registration. Every call after that reports a real
|
|
132
|
+
* delta against the last periodic baseline once MIN_PERIODIC_INTERVAL_S
|
|
133
|
+
* has elapsed.
|
|
134
|
+
*/
|
|
135
|
+
private computePeriodic;
|
|
136
|
+
/**
|
|
137
|
+
* Register this meter as a Matter electrical sensor.
|
|
138
|
+
*
|
|
139
|
+
* @param seedKey - unique per-meter key used to derive this accessory's
|
|
140
|
+
* Matter UUID, distinct from the HAP accessory's UUID
|
|
141
|
+
* @param displayName
|
|
142
|
+
* @param serialNumber
|
|
143
|
+
* @param readings - initial readings to seed the clusters with
|
|
144
|
+
*/
|
|
145
|
+
register(seedKey: string, displayName: string, serialNumber: string, readings: EnergyReadings): Promise<boolean>;
|
|
146
|
+
/**
|
|
147
|
+
* Push fresh readings to the registered Matter accessory. No-op until
|
|
148
|
+
* registration has succeeded.
|
|
149
|
+
*/
|
|
150
|
+
update(readings: EnergyReadings): Promise<void>;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=matterEnergy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matterEnergy.d.ts","sourceRoot":"","sources":["../src/matterEnergy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAqB9C,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;IAkB3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAlB5B,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;IAK7B,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,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* matterEnergy.ts
|
|
4
|
+
*
|
|
5
|
+
* Publishes a PVS6 meter (solar, grid, home consumption) to Matter
|
|
6
|
+
* controllers as an ElectricalSensor reporting live power and cumulative /
|
|
7
|
+
* periodic energy, so it feeds the Apple Home Energy view (iOS 26+).
|
|
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
|
+
* An earlier version of this feature declared these accessories as
|
|
20
|
+
* OnOffOutlet so their tile would show a headline status (a pure metering
|
|
21
|
+
* device type like ElectricalSensor has no actionable primary cluster, and
|
|
22
|
+
* its tile showed "Not Supported" as a result — confirmed live). That's
|
|
23
|
+
* reverted here: none of these meters are actually controllable, the on/off
|
|
24
|
+
* state was only ever a workaround for the tile headline, and the "Not
|
|
25
|
+
* Supported" tile is an accepted tradeoff as long as the wattage still rolls
|
|
26
|
+
* into the Home aggregate and (via PeriodicEnergy, below) into this
|
|
27
|
+
* accessory's own Energy-view attribution — which it does.
|
|
28
|
+
*
|
|
29
|
+
* powerW -> electricalPowerMeasurement.activePower (mW, signed)
|
|
30
|
+
* energyKWh -> electricalEnergyMeasurement.cumulativeEnergyImported.energy (mWh)
|
|
31
|
+
* and/or .cumulativeEnergyExported.energy, depending on this
|
|
32
|
+
* meter's direction (see EnergyDirection below).
|
|
33
|
+
*
|
|
34
|
+
* Matter expresses power in milliwatts and energy in milliwatt-hours, hence
|
|
35
|
+
* the x1000 / x1,000,000 conversions. cumulativeEnergyImported/Exported are
|
|
36
|
+
* themselves structs (EnergyMeasurementStruct — { energy, startTimestamp?,
|
|
37
|
+
* endTimestamp?, ... }), not plain numbers: Homebridge's updateAccessoryState()
|
|
38
|
+
* accepts and normalizes a flat number for convenience, but the *initial*
|
|
39
|
+
* state passed at registration goes straight to matter.js's struct-typed
|
|
40
|
+
* attribute and must already be an object, or registration fails with
|
|
41
|
+
* "Cannot manage number because it is not a struct".
|
|
42
|
+
*
|
|
43
|
+
* Homebridge derives the mandatory cluster attributes (powerMode, accuracy,
|
|
44
|
+
* numberOfMeasurementTypes) and the feature-gated ElectricalEnergyMeasurement
|
|
45
|
+
* features from the declared state — declaring `cumulativeEnergyImported`
|
|
46
|
+
* selects the ImportedEnergy + CumulativeEnergy features, `cumulativeEnergyExported`
|
|
47
|
+
* selects ExportedEnergy + CumulativeEnergy, and both together (for a
|
|
48
|
+
* bidirectional meter) select both pairs at once. No voltage/current data is
|
|
49
|
+
* available from the PVS6 varserver reliably enough to publish, so only
|
|
50
|
+
* activePower is declared; voltage/activeCurrent are optional per the
|
|
51
|
+
* Matter spec and are simply omitted.
|
|
52
|
+
*
|
|
53
|
+
* Imported vs. exported energy is always two separate attributes
|
|
54
|
+
* ------------------------------------------------------------
|
|
55
|
+
* `activePower` is a signed attribute (positive = importing, negative =
|
|
56
|
+
* exporting), so a single bidirectional meter — the grid meter — can report
|
|
57
|
+
* live direction with one accessory. Cumulative/periodic *energy* has no
|
|
58
|
+
* equivalent signed "net" attribute, though: Imported and Exported are
|
|
59
|
+
* distinct lifetime running totals per the Matter spec (you don't want a
|
|
60
|
+
* day's production and consumption cancelling each other out), so a
|
|
61
|
+
* bidirectional meter still declares both `cumulativeEnergyImported` and
|
|
62
|
+
* `cumulativeEnergyExported` (and their periodic counterparts) together on
|
|
63
|
+
* the same cluster. See EnergyDirection's 'bidirectional' case below — this
|
|
64
|
+
* is how the grid meter is published as a single Matter accessory even
|
|
65
|
+
* though it remains two separate accessories in Eve/HomeKit (Grid Import /
|
|
66
|
+
* Grid Export), since that split is purely about Eve's inability to
|
|
67
|
+
* represent a negative watt value, not a Matter limitation.
|
|
68
|
+
*
|
|
69
|
+
* Cumulative vs. periodic energy
|
|
70
|
+
* ------------------------------
|
|
71
|
+
* Alongside the cumulative (lifetime) total, this module also declares the
|
|
72
|
+
* PeriodicEnergy feature (`periodicEnergyImported`/`periodicEnergyExported`)
|
|
73
|
+
* — a per-interval delta with its own start/end timestamps. Per prior art in
|
|
74
|
+
* homebridge-shelly-matter (github.com/keremerkan/homebridge-shelly-matter,
|
|
75
|
+
* shellyAccessory.ts), this is what drives Apple Home's per-device energy
|
|
76
|
+
* attribution in the Energy view, not the cumulative total alone. Matter
|
|
77
|
+
* features compose once at registration, so PeriodicEnergy must already be
|
|
78
|
+
* present in the *initial* cluster state passed to registerPlatformAccessories()
|
|
79
|
+
* — declaring it for the first time in a later updateAccessoryState() call
|
|
80
|
+
* would not retroactively add the feature. buildClusters() therefore seeds a
|
|
81
|
+
* zero-energy periodic fragment (no timestamps yet) on its very first call,
|
|
82
|
+
* which is always the one register() makes, before any real reading exists
|
|
83
|
+
* to diff against; every call after that computes a real delta against the
|
|
84
|
+
* last *periodic* baseline (not the last poll), throttled to at most once
|
|
85
|
+
* per MIN_PERIODIC_INTERVAL_S so a short poll interval (default 10s, minimum
|
|
86
|
+
* 5s) doesn't turn into excessive Matter event/state churn compared to a
|
|
87
|
+
* device that naturally reports once a minute. A bidirectional meter tracks
|
|
88
|
+
* imported and exported baselines independently, since either can advance
|
|
89
|
+
* while the other sits idle.
|
|
90
|
+
*
|
|
91
|
+
* Requirements
|
|
92
|
+
* ------------
|
|
93
|
+
* - Homebridge 2.3.0+
|
|
94
|
+
* - Matter enabled on this plugin's child bridge (Homebridge UI ->
|
|
95
|
+
* plugin settings -> Bridge Settings -> enable Matter)
|
|
96
|
+
*
|
|
97
|
+
* Everything here is feature-detected and guarded: on a Homebridge build
|
|
98
|
+
* without the Matter API, or with Matter disabled, isSupported() returns
|
|
99
|
+
* false and the plugin runs HAP/Eve-only exactly as before.
|
|
100
|
+
*/
|
|
101
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
102
|
+
exports.MatterEnergyBridge = void 0;
|
|
103
|
+
const PLUGIN_NAME = 'homebridge-pvs6';
|
|
104
|
+
const PLATFORM_NAME = 'PVS6';
|
|
105
|
+
/** Matter expresses power in milliwatts. */
|
|
106
|
+
function wToMilliW(value) {
|
|
107
|
+
const n = Number(value);
|
|
108
|
+
return Number.isFinite(n) ? Math.round(n * 1000) : 0;
|
|
109
|
+
}
|
|
110
|
+
/** Matter expresses energy in milliwatt-hours; PVS6 readings are in kWh. */
|
|
111
|
+
function kWhToMilliWh(value) {
|
|
112
|
+
const n = Number(value);
|
|
113
|
+
return Number.isFinite(n) ? Math.round(Math.max(0, n) * 1000000) : 0;
|
|
114
|
+
}
|
|
115
|
+
class MatterEnergyBridge {
|
|
116
|
+
constructor(api, log, direction) {
|
|
117
|
+
this.log = log;
|
|
118
|
+
this.direction = direction;
|
|
119
|
+
this.uuid = null;
|
|
120
|
+
this.registered = false;
|
|
121
|
+
this.warnedUpdate = false;
|
|
122
|
+
// Periodic-energy bookkeeping — see the "Cumulative vs. periodic energy"
|
|
123
|
+
// note at the top of this file. Tracked per energy kind so a bidirectional
|
|
124
|
+
// meter can advance its imported and exported deltas independently.
|
|
125
|
+
this.periodicState = {
|
|
126
|
+
imported: { baselineKWh: null, timestampS: null, last: { energy: 0 } },
|
|
127
|
+
exported: { baselineKWh: null, timestampS: null, last: { energy: 0 } },
|
|
128
|
+
};
|
|
129
|
+
this.api = api;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Whether this Homebridge build exposes everything needed to publish this
|
|
133
|
+
* meter. Logs at debug level so unsupported builds stay quiet.
|
|
134
|
+
*/
|
|
135
|
+
isSupported() {
|
|
136
|
+
const matter = this.api.matter;
|
|
137
|
+
if (!matter) {
|
|
138
|
+
this.log.debug('[matter] api.matter unavailable — Matter energy export disabled. Requires Homebridge 2.3.0+ with Matter enabled on this plugin\'s child bridge.');
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
if (!matter.deviceTypes?.ElectricalSensor) {
|
|
142
|
+
this.log.debug('[matter] api.matter.deviceTypes.ElectricalSensor unavailable — Matter energy export disabled. Requires a newer Homebridge build.');
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
if (typeof matter.registerPlatformAccessories !== 'function' || typeof matter.updateAccessoryState !== 'function') {
|
|
146
|
+
this.log.debug('[matter] Matter registration/update API unavailable — Matter energy export disabled.');
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
buildClusters(r) {
|
|
152
|
+
const energyField = {};
|
|
153
|
+
if (this.direction === 'imported' || this.direction === 'bidirectional') {
|
|
154
|
+
energyField.cumulativeEnergyImported = { energy: kWhToMilliWh(r.importedEnergyKWh ?? 0) };
|
|
155
|
+
energyField.periodicEnergyImported = this.computePeriodic('imported', r.importedEnergyKWh ?? 0);
|
|
156
|
+
}
|
|
157
|
+
if (this.direction === 'exported' || this.direction === 'bidirectional') {
|
|
158
|
+
energyField.cumulativeEnergyExported = { energy: kWhToMilliWh(r.exportedEnergyKWh ?? 0) };
|
|
159
|
+
energyField.periodicEnergyExported = this.computePeriodic('exported', r.exportedEnergyKWh ?? 0);
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
electricalPowerMeasurement: { activePower: wToMilliW(r.powerW) },
|
|
163
|
+
electricalEnergyMeasurement: energyField,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Compute (or, between periodic reports, just return the last computed)
|
|
168
|
+
* periodic-energy fragment for one energy kind. The very first call —
|
|
169
|
+
* always from register(), before any real reading exists — seeds a
|
|
170
|
+
* zero-energy fragment with no timestamps, purely so the PeriodicEnergy
|
|
171
|
+
* feature composes at registration. Every call after that reports a real
|
|
172
|
+
* delta against the last periodic baseline once MIN_PERIODIC_INTERVAL_S
|
|
173
|
+
* has elapsed.
|
|
174
|
+
*/
|
|
175
|
+
computePeriodic(kind, energyKWh) {
|
|
176
|
+
const state = this.periodicState[kind];
|
|
177
|
+
const nowS = Math.floor(Date.now() / 1000);
|
|
178
|
+
if (state.baselineKWh === null || state.timestampS === null) {
|
|
179
|
+
state.baselineKWh = energyKWh;
|
|
180
|
+
state.timestampS = nowS;
|
|
181
|
+
return state.last;
|
|
182
|
+
}
|
|
183
|
+
if (nowS - state.timestampS >= MatterEnergyBridge.MIN_PERIODIC_INTERVAL_S) {
|
|
184
|
+
const deltaKWh = Math.max(0, energyKWh - state.baselineKWh);
|
|
185
|
+
state.last = {
|
|
186
|
+
energy: kWhToMilliWh(deltaKWh),
|
|
187
|
+
startTimestamp: state.timestampS,
|
|
188
|
+
endTimestamp: nowS,
|
|
189
|
+
};
|
|
190
|
+
state.baselineKWh = energyKWh;
|
|
191
|
+
state.timestampS = nowS;
|
|
192
|
+
}
|
|
193
|
+
return state.last;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Register this meter as a Matter electrical sensor.
|
|
197
|
+
*
|
|
198
|
+
* @param seedKey - unique per-meter key used to derive this accessory's
|
|
199
|
+
* Matter UUID, distinct from the HAP accessory's UUID
|
|
200
|
+
* @param displayName
|
|
201
|
+
* @param serialNumber
|
|
202
|
+
* @param readings - initial readings to seed the clusters with
|
|
203
|
+
*/
|
|
204
|
+
async register(seedKey, displayName, serialNumber, readings) {
|
|
205
|
+
if (!this.isSupported())
|
|
206
|
+
return false;
|
|
207
|
+
const matter = this.api.matter;
|
|
208
|
+
this.uuid = matter.uuid.generate(`${PLUGIN_NAME}:matter:${seedKey}`);
|
|
209
|
+
const accessory = {
|
|
210
|
+
UUID: this.uuid,
|
|
211
|
+
displayName,
|
|
212
|
+
deviceType: matter.deviceTypes.ElectricalSensor,
|
|
213
|
+
serialNumber,
|
|
214
|
+
manufacturer: 'SunStrong',
|
|
215
|
+
model: 'PVS6',
|
|
216
|
+
clusters: this.buildClusters(readings),
|
|
217
|
+
};
|
|
218
|
+
try {
|
|
219
|
+
await matter.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
220
|
+
this.registered = true;
|
|
221
|
+
this.log.info(`[matter] Published "${displayName}" as a Matter electrical sensor — live power should feed the Apple Home Energy view.`);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
this.log.warn(`[matter] Failed to register Matter accessory for "${displayName}" (${err instanceof Error ? err.message : err}). Continuing with HomeKit/Eve only.`);
|
|
226
|
+
this.registered = false;
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Push fresh readings to the registered Matter accessory. No-op until
|
|
232
|
+
* registration has succeeded.
|
|
233
|
+
*/
|
|
234
|
+
async update(readings) {
|
|
235
|
+
if (!this.registered || !this.uuid)
|
|
236
|
+
return;
|
|
237
|
+
const matter = this.api.matter;
|
|
238
|
+
if (!matter)
|
|
239
|
+
return;
|
|
240
|
+
const clusters = this.buildClusters(readings);
|
|
241
|
+
try {
|
|
242
|
+
await Promise.all([
|
|
243
|
+
matter.updateAccessoryState(this.uuid, 'electricalPowerMeasurement', clusters.electricalPowerMeasurement),
|
|
244
|
+
matter.updateAccessoryState(this.uuid, 'electricalEnergyMeasurement', clusters.electricalEnergyMeasurement),
|
|
245
|
+
]);
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
// Log the first failure at warn, the rest at debug, so a persistently
|
|
249
|
+
// unhappy Matter server can't flood the log on every poll.
|
|
250
|
+
const message = `[matter] Failed to update Matter state: ${err instanceof Error ? err.message : err}`;
|
|
251
|
+
if (!this.warnedUpdate) {
|
|
252
|
+
this.warnedUpdate = true;
|
|
253
|
+
this.log.warn(message);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
this.log.debug(message);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
exports.MatterEnergyBridge = MatterEnergyBridge;
|
|
262
|
+
MatterEnergyBridge.MIN_PERIODIC_INTERVAL_S = 60;
|
|
263
|
+
//# 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
|
@@ -14,15 +14,19 @@ export declare class PVS6Platform implements DynamicPlatformPlugin {
|
|
|
14
14
|
private gridImportAccessory?;
|
|
15
15
|
private gridExportAccessory?;
|
|
16
16
|
private homeConsumptionAccessory?;
|
|
17
|
+
private gridMatterBridge;
|
|
17
18
|
private pollTimer?;
|
|
18
19
|
private pollInFlight;
|
|
19
20
|
private backedOff;
|
|
21
|
+
private consecutiveNetworkErrors;
|
|
22
|
+
private lastNetworkErrorLogTime;
|
|
20
23
|
private authGeneration;
|
|
21
24
|
private lastSuccessfulPollTime;
|
|
22
25
|
private rediscovering;
|
|
23
26
|
constructor(log: Logger, config: PlatformConfig, api: API);
|
|
24
27
|
configureAccessory(accessory: PlatformAccessory): void;
|
|
25
28
|
private resolveConfig;
|
|
29
|
+
private discoverWithCache;
|
|
26
30
|
private setupAccessories;
|
|
27
31
|
private getOrCreateAccessory;
|
|
28
32
|
private get discoveryEnabled();
|
|
@@ -31,6 +35,7 @@ export declare class PVS6Platform implements DynamicPlatformPlugin {
|
|
|
31
35
|
private stopPolling;
|
|
32
36
|
private startAuthAndPolling;
|
|
33
37
|
private startPolling;
|
|
38
|
+
private triggerReauth;
|
|
34
39
|
private enterBackoff;
|
|
35
40
|
}
|
|
36
41
|
//# sourceMappingURL=platform.d.ts.map
|
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;AAQpB,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;AAQpB,OAAO,EAA4B,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAY1E,qBAAa,YAAa,YAAW,qBAAqB;IACxD,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAC;IACxC,SAAgB,cAAc,EAAE,OAAO,cAAc,CAAC;IACtD,SAAgB,GAAG,EAAE,GAAG,CAAC;IACzB,SAAgB,QAAQ,EAAE,QAAQ,CAAC;IACnC,SAAgB,GAAG,EAAE,MAAM,CAAC;IAE5B,SAAgB,WAAW,EAAE,iBAAiB,EAAE,CAAM;IAGtD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,wBAAwB,CAAC,CAA2B;IAO5D,OAAO,CAAC,gBAAgB,CAAmC;IAE3D,OAAO,CAAC,SAAS,CAAC,CAAiC;IACnD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,wBAAwB,CAAK;IACrC,OAAO,CAAC,uBAAuB,CAAK;IAGpC,OAAO,CAAC,cAAc,CAAK;IAG3B,OAAO,CAAC,sBAAsB,CAAc;IAC5C,OAAO,CAAC,aAAa,CAAS;gBAG5B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG;IA2CV,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;YAexC,aAAa;YA0Bb,iBAAiB;IAW/B,OAAO,CAAC,gBAAgB;IAsExB,OAAO,CAAC,oBAAoB;IAiB5B,OAAO,KAAK,gBAAgB,GAE3B;IAID,OAAO,CAAC,gBAAgB;YAQV,kBAAkB;IA0BhC,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,YAAY;IAiEpB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,YAAY;CASrB"}
|
package/dist/platform.js
CHANGED
|
@@ -8,17 +8,28 @@ const gridImportAccessory_1 = require("./gridImportAccessory");
|
|
|
8
8
|
const gridExportAccessory_1 = require("./gridExportAccessory");
|
|
9
9
|
const homeConsumptionAccessory_1 = require("./homeConsumptionAccessory");
|
|
10
10
|
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
11
|
+
const matterEnergy_1 = require("./matterEnergy");
|
|
11
12
|
const pvs6Discovery_1 = require("./pvs6Discovery");
|
|
13
|
+
const pvs6DiscoveryCache_1 = require("./pvs6DiscoveryCache");
|
|
12
14
|
const MIN_POLL_INTERVAL = 5;
|
|
13
15
|
const AUTH_RETRY_MS = 30000;
|
|
14
16
|
const AUTH_BACKOFF_MS = 60000;
|
|
15
17
|
const OVERLOAD_BACKOFF_MS = 15000;
|
|
16
18
|
const REDISCOVERY_THRESHOLD_MS = 2 * 60 * 60 * 1000; // 2 hours
|
|
19
|
+
const NETWORK_ERROR_LOG_INTERVAL_MS = 5 * 60 * 1000; // suppress repeat network error logs within 5 min
|
|
17
20
|
class PVS6Platform {
|
|
18
21
|
constructor(log, config, api) {
|
|
19
22
|
this.accessories = [];
|
|
23
|
+
// Optional: publishes the grid meter over Matter as a single bidirectional
|
|
24
|
+
// accessory (signed activePower, both imported/exported energy on one
|
|
25
|
+
// cluster) — see matterEnergy.ts. Grid Import/Export stay separate
|
|
26
|
+
// accessories in Eve/HomeKit only, since that split is purely for Eve's
|
|
27
|
+
// characteristic limitation, not a Matter one.
|
|
28
|
+
this.gridMatterBridge = null;
|
|
20
29
|
this.pollInFlight = false;
|
|
21
30
|
this.backedOff = false;
|
|
31
|
+
this.consecutiveNetworkErrors = 0;
|
|
32
|
+
this.lastNetworkErrorLogTime = 0;
|
|
22
33
|
// Incremented when re-discovery fires so stale auth-retry timeouts know to abort.
|
|
23
34
|
this.authGeneration = 0;
|
|
24
35
|
// Tracks when the last successful poll data was received, for re-discovery gating.
|
|
@@ -68,6 +79,11 @@ class PVS6Platform {
|
|
|
68
79
|
// autoDiscover: true → always run mDNS discovery; host/serialNumber in config are ignored.
|
|
69
80
|
// autoDiscover: false → must supply both host and serialNumber manually; no mDNS.
|
|
70
81
|
// autoDiscover: unset → use config values if both are present, otherwise discover what's missing.
|
|
82
|
+
//
|
|
83
|
+
// Discovery results are cached to disk: once mDNS finds the PVS6, subsequent startups reuse
|
|
84
|
+
// the cached host/serialNumber and skip mDNS entirely. If the cached IP turns out to be stale
|
|
85
|
+
// (device unreachable), the existing re-discovery flow (checkRediscovery/triggerRediscovery)
|
|
86
|
+
// takes over and refreshes the cache once mDNS finds it again.
|
|
71
87
|
async resolveConfig() {
|
|
72
88
|
const { host, serialNumber, autoDiscover } = this.config;
|
|
73
89
|
if (autoDiscover === false) {
|
|
@@ -77,25 +93,37 @@ class PVS6Platform {
|
|
|
77
93
|
return { host, serialNumber };
|
|
78
94
|
}
|
|
79
95
|
if (autoDiscover === true) {
|
|
80
|
-
return
|
|
96
|
+
return this.discoverWithCache();
|
|
81
97
|
}
|
|
82
98
|
// autoDiscover not set: use config if complete, otherwise discover what's missing.
|
|
83
99
|
if (host && serialNumber) {
|
|
84
100
|
return { host, serialNumber };
|
|
85
101
|
}
|
|
86
|
-
const discovered = await
|
|
102
|
+
const discovered = await this.discoverWithCache();
|
|
87
103
|
return {
|
|
88
104
|
host: host ?? discovered.host,
|
|
89
105
|
serialNumber: serialNumber ?? discovered.serialNumber,
|
|
90
106
|
};
|
|
91
107
|
}
|
|
108
|
+
// Returns the cached discovery result if one exists, otherwise runs mDNS discovery and caches it.
|
|
109
|
+
async discoverWithCache() {
|
|
110
|
+
const cached = (0, pvs6DiscoveryCache_1.loadDiscoveryCache)(this.api, this.log);
|
|
111
|
+
if (cached) {
|
|
112
|
+
this.log.info(`Using cached PVS6 location: ${cached.host} (serial: ${cached.serialNumber}) — skipping mDNS discovery`);
|
|
113
|
+
return cached;
|
|
114
|
+
}
|
|
115
|
+
const discovered = await (0, pvs6Discovery_1.discoverPVS6)(this.log);
|
|
116
|
+
(0, pvs6DiscoveryCache_1.saveDiscoveryCache)(this.api, this.log, discovered);
|
|
117
|
+
return discovered;
|
|
118
|
+
}
|
|
92
119
|
setupAccessories(
|
|
93
120
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
94
121
|
FakeGatoHistoryService, serialNumber) {
|
|
122
|
+
const matterEnabled = this.config.matter === true;
|
|
95
123
|
// Solar Production is always registered.
|
|
96
124
|
const solarName = this.config.solarName ?? 'Solar Production';
|
|
97
125
|
const solarUuid = this.api.hap.uuid.generate(`${serialNumber}-solar`);
|
|
98
|
-
this.solarAccessory = new solarAccessory_1.SolarAccessory(this, this.getOrCreateAccessory(solarUuid, solarName), FakeGatoHistoryService, solarName, serialNumber);
|
|
126
|
+
this.solarAccessory = new solarAccessory_1.SolarAccessory(this, this.getOrCreateAccessory(solarUuid, solarName), FakeGatoHistoryService, solarName, serialNumber, matterEnabled);
|
|
99
127
|
// Grid Import + Grid Export are registered together as an optional pair (default: enabled).
|
|
100
128
|
if (this.config.accessories?.grid !== false) {
|
|
101
129
|
const importName = this.config.gridName ?? 'Grid Meter - Import';
|
|
@@ -104,6 +132,20 @@ class PVS6Platform {
|
|
|
104
132
|
const exportName = this.config.gridExportName ?? 'Grid Meter - Export';
|
|
105
133
|
const exportUuid = this.api.hap.uuid.generate(`${serialNumber}-grid-export`);
|
|
106
134
|
this.gridExportAccessory = new gridExportAccessory_1.GridExportAccessory(this, this.getOrCreateAccessory(exportUuid, exportName), FakeGatoHistoryService, exportName, serialNumber);
|
|
135
|
+
if (matterEnabled) {
|
|
136
|
+
const bridge = new matterEnergy_1.MatterEnergyBridge(this.api, this.log, 'bidirectional');
|
|
137
|
+
if (bridge.isSupported()) {
|
|
138
|
+
this.gridMatterBridge = bridge;
|
|
139
|
+
bridge.register(`${serialNumber}-grid-net`, 'Grid', `${serialNumber}-grid`, {
|
|
140
|
+
powerW: 0,
|
|
141
|
+
importedEnergyKWh: 0,
|
|
142
|
+
exportedEnergyKWh: 0,
|
|
143
|
+
}).catch(() => { });
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
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.');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
107
149
|
}
|
|
108
150
|
// Home Consumption is optional (default: disabled).
|
|
109
151
|
if (this.config.accessories?.homeConsumption === true) {
|
|
@@ -149,6 +191,8 @@ class PVS6Platform {
|
|
|
149
191
|
try {
|
|
150
192
|
const { host, serialNumber } = await (0, pvs6Discovery_1.discoverPVS6)(this.log);
|
|
151
193
|
this.log.info(`Re-discovery found PVS6 at ${host} (serial: ${serialNumber}) — reconnecting`);
|
|
194
|
+
// Refresh the cache so the next startup picks up the new address directly.
|
|
195
|
+
(0, pvs6DiscoveryCache_1.saveDiscoveryCache)(this.api, this.log, { host, serialNumber });
|
|
152
196
|
// Increment generation to cancel any pending auth-retry timeouts.
|
|
153
197
|
this.authGeneration++;
|
|
154
198
|
this.stopPolling();
|
|
@@ -213,27 +257,27 @@ class PVS6Platform {
|
|
|
213
257
|
try {
|
|
214
258
|
const reading = await this.client.poll();
|
|
215
259
|
this.lastSuccessfulPollTime = Date.now();
|
|
260
|
+
this.consecutiveNetworkErrors = 0;
|
|
216
261
|
this.solarAccessory?.updateValues(reading);
|
|
217
262
|
this.gridImportAccessory?.updateValues(reading);
|
|
218
263
|
this.gridExportAccessory?.updateValues(reading);
|
|
219
264
|
this.homeConsumptionAccessory?.updateValues(reading);
|
|
265
|
+
this.gridMatterBridge?.update({
|
|
266
|
+
powerW: reading.netPowerW,
|
|
267
|
+
importedEnergyKWh: reading.gridImportKWh,
|
|
268
|
+
exportedEnergyKWh: reading.gridExportKWh,
|
|
269
|
+
}).catch(() => { });
|
|
220
270
|
}
|
|
221
271
|
catch (err) {
|
|
222
272
|
if (err instanceof pvs6Client_1.HttpError) {
|
|
223
273
|
if (err.statusCode === 401) {
|
|
224
274
|
this.log.warn('HTTP 401 — session expired, re-authenticating...');
|
|
225
|
-
this.
|
|
226
|
-
this.
|
|
227
|
-
.then(() => {
|
|
228
|
-
this.log.info('Re-authenticated — resuming polls');
|
|
229
|
-
this.backedOff = false;
|
|
230
|
-
})
|
|
231
|
-
.catch((authErr) => {
|
|
232
|
-
this.log.error(`Re-auth failed: ${authErr.message}. Backing off ${AUTH_BACKOFF_MS / 1000}s`);
|
|
233
|
-
});
|
|
275
|
+
this.consecutiveNetworkErrors = 0;
|
|
276
|
+
this.triggerReauth();
|
|
234
277
|
}
|
|
235
278
|
else if (err.statusCode >= 500) {
|
|
236
279
|
this.log.warn(`HTTP ${err.statusCode} from PVS6 — device may be overloaded. Backing off ${OVERLOAD_BACKOFF_MS / 1000}s`);
|
|
280
|
+
this.consecutiveNetworkErrors = 0;
|
|
237
281
|
this.enterBackoff(OVERLOAD_BACKOFF_MS);
|
|
238
282
|
}
|
|
239
283
|
else {
|
|
@@ -241,8 +285,18 @@ class PVS6Platform {
|
|
|
241
285
|
}
|
|
242
286
|
}
|
|
243
287
|
else if (err instanceof Error) {
|
|
244
|
-
if (err.message.includes('timeout')) {
|
|
245
|
-
this.
|
|
288
|
+
if (err.message.includes('timeout') || err.message.includes('socket hang up') || err.message.includes('ECONNRESET')) {
|
|
289
|
+
this.consecutiveNetworkErrors++;
|
|
290
|
+
const now = Date.now();
|
|
291
|
+
if (now - this.lastNetworkErrorLogTime > NETWORK_ERROR_LOG_INTERVAL_MS) {
|
|
292
|
+
this.log.warn(`Poll network error: ${err.message}`);
|
|
293
|
+
this.lastNetworkErrorLogTime = now;
|
|
294
|
+
}
|
|
295
|
+
if (this.consecutiveNetworkErrors >= 3) {
|
|
296
|
+
this.log.warn(`${this.consecutiveNetworkErrors} consecutive network errors — re-authenticating...`);
|
|
297
|
+
this.consecutiveNetworkErrors = 0;
|
|
298
|
+
this.triggerReauth();
|
|
299
|
+
}
|
|
246
300
|
}
|
|
247
301
|
else if (err.message.includes('JSON parse')) {
|
|
248
302
|
this.log.warn(`${err.message}`);
|
|
@@ -257,11 +311,24 @@ class PVS6Platform {
|
|
|
257
311
|
}
|
|
258
312
|
}, this.pollIntervalMs);
|
|
259
313
|
}
|
|
314
|
+
triggerReauth() {
|
|
315
|
+
this.enterBackoff(AUTH_BACKOFF_MS);
|
|
316
|
+
this.client.authenticate()
|
|
317
|
+
.then(() => {
|
|
318
|
+
this.log.info('Re-authenticated — resuming polls');
|
|
319
|
+
this.backedOff = false;
|
|
320
|
+
})
|
|
321
|
+
.catch((authErr) => {
|
|
322
|
+
this.log.error(`Re-auth failed: ${authErr.message}. Backing off ${AUTH_BACKOFF_MS / 1000}s`);
|
|
323
|
+
});
|
|
324
|
+
}
|
|
260
325
|
enterBackoff(durationMs) {
|
|
261
326
|
this.backedOff = true;
|
|
262
327
|
setTimeout(() => {
|
|
328
|
+
if (this.backedOff) {
|
|
329
|
+
this.log.info('Backoff period ended — resuming polls');
|
|
330
|
+
}
|
|
263
331
|
this.backedOff = false;
|
|
264
|
-
this.log.info('Backoff period ended — resuming polls');
|
|
265
332
|
}, durationMs);
|
|
266
333
|
}
|
|
267
334
|
}
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { API, Logger } from 'homebridge';
|
|
2
|
+
import { PVS6DiscoveryResult } from './pvs6Discovery';
|
|
3
|
+
export declare function loadDiscoveryCache(api: API, log: Logger): PVS6DiscoveryResult | undefined;
|
|
4
|
+
export declare function saveDiscoveryCache(api: API, log: Logger, result: PVS6DiscoveryResult): void;
|
|
5
|
+
//# sourceMappingURL=pvs6DiscoveryCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pvs6DiscoveryCache.d.ts","sourceRoot":"","sources":["../src/pvs6DiscoveryCache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAUtD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAezF;AAGD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAO3F"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadDiscoveryCache = loadDiscoveryCache;
|
|
37
|
+
exports.saveDiscoveryCache = saveDiscoveryCache;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const CACHE_FILE_NAME = '.pvs6-discovery-cache.json';
|
|
41
|
+
function cachePath(api) {
|
|
42
|
+
return path.join(api.user.storagePath(), CACHE_FILE_NAME);
|
|
43
|
+
}
|
|
44
|
+
// Reads a previously-cached mDNS discovery result, if any.
|
|
45
|
+
// Returns undefined on first run (no cache yet) or if the cache file is unreadable/malformed.
|
|
46
|
+
function loadDiscoveryCache(api, log) {
|
|
47
|
+
try {
|
|
48
|
+
const raw = fs.readFileSync(cachePath(api), 'utf8');
|
|
49
|
+
const data = JSON.parse(raw);
|
|
50
|
+
if (data.host && data.serialNumber) {
|
|
51
|
+
return { host: data.host, serialNumber: data.serialNumber };
|
|
52
|
+
}
|
|
53
|
+
log.debug('Discovery cache file is malformed — ignoring');
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
// ENOENT just means there's no cache yet (first run); anything else is worth a debug log.
|
|
57
|
+
if (err.code !== 'ENOENT') {
|
|
58
|
+
log.debug(`Failed to read discovery cache: ${err}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
// Persists a successful mDNS discovery so subsequent startups can skip discovery entirely.
|
|
64
|
+
function saveDiscoveryCache(api, log, result) {
|
|
65
|
+
try {
|
|
66
|
+
fs.writeFileSync(cachePath(api), JSON.stringify(result), 'utf8');
|
|
67
|
+
log.debug(`Cached PVS6 location: ${result.host} (serial: ${result.serialNumber})`);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
log.warn(`Failed to write discovery cache: ${err}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=pvs6DiscoveryCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pvs6DiscoveryCache.js","sourceRoot":"","sources":["../src/pvs6DiscoveryCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,gDAeC;AAGD,gDAOC;AAtCD,uCAAyB;AACzB,2CAA6B;AAI7B,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAErD,SAAS,SAAS,CAAC,GAAQ;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,CAAC;AAC5D,CAAC;AAED,2DAA2D;AAC3D,8FAA8F;AAC9F,SAAgB,kBAAkB,CAAC,GAAQ,EAAE,GAAW;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiC,CAAC;QAC7D,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACnC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;QAC9D,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0FAA0F;QAC1F,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,GAAG,CAAC,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,2FAA2F;AAC3F,SAAgB,kBAAkB,CAAC,GAAQ,EAAE,GAAW,EAAE,MAA2B;IACnF,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QACjE,GAAG,CAAC,KAAK,CAAC,yBAAyB,MAAM,CAAC,IAAI,aAAa,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC;IACrF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,oCAAoC,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
|
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,SAAS,CAAC;AACpC,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAE7C,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
|
|
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,SAAS,CAAC;AACpC,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAE7C,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
|
package/dist/solarAccessory.d.ts
CHANGED
|
@@ -7,7 +7,8 @@ export declare class SolarAccessory {
|
|
|
7
7
|
private readonly historyService;
|
|
8
8
|
private lastPowerW;
|
|
9
9
|
private lastEnergyKWh;
|
|
10
|
-
|
|
10
|
+
private matter;
|
|
11
|
+
constructor(platform: PVS6Platform, accessory: PlatformAccessory, FakeGatoHistoryService: any, displayName: string, serialNumber: string, matterEnabled?: boolean);
|
|
11
12
|
updateValues(reading: PVS6Reading): void;
|
|
12
13
|
}
|
|
13
14
|
//# sourceMappingURL=solarAccessory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solarAccessory.d.ts","sourceRoot":"","sources":["../src/solarAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"solarAccessory.d.ts","sourceRoot":"","sources":["../src/solarAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAW,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAI3C,qBAAa,cAAc;IAcvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAb3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IAErC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAK1B,OAAO,CAAC,MAAM,CAAmC;gBAG9B,QAAQ,EAAE,YAAY,EACvC,SAAS,EAAE,iBAAiB,EAE5B,sBAAsB,EAAE,GAAG,EAC3B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,aAAa,UAAQ;IAgEvB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;CAqBzC"}
|
package/dist/solarAccessory.js
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SolarAccessory = void 0;
|
|
4
4
|
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
5
|
+
const matterEnergy_1 = require("./matterEnergy");
|
|
5
6
|
class SolarAccessory {
|
|
6
7
|
constructor(platform, accessory,
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
-
FakeGatoHistoryService, displayName, serialNumber) {
|
|
9
|
+
FakeGatoHistoryService, displayName, serialNumber, matterEnabled = false) {
|
|
9
10
|
this.platform = platform;
|
|
10
11
|
this.lastPowerW = 0;
|
|
11
12
|
this.lastEnergyKWh = 0;
|
|
13
|
+
// Optional: publishes this meter over Matter for the Apple Home Energy
|
|
14
|
+
// view. Null when the "matter" config option is off; also cleared when the
|
|
15
|
+
// Homebridge build doesn't support it. See matterEnergy.ts.
|
|
16
|
+
this.matter = null;
|
|
12
17
|
const { Characteristic } = platform;
|
|
13
18
|
const { EveWatts, EveKWh } = platform.eveChars;
|
|
14
19
|
const infoService = accessory.getService(platform.Service.AccessoryInformation) ??
|
|
@@ -42,6 +47,23 @@ class SolarAccessory {
|
|
|
42
47
|
.onGet(() => this.lastEnergyKWh);
|
|
43
48
|
// fakegato history — 'energy' type records { time, power } in Watts
|
|
44
49
|
this.historyService = new FakeGatoHistoryService('energy', accessory, { storage: 'fs' });
|
|
50
|
+
if (matterEnabled) {
|
|
51
|
+
// Solar production flows out of the meter — reported as exported energy.
|
|
52
|
+
// Matter's activePower sign convention is positive = drawing power,
|
|
53
|
+
// negative = supplying it, so a generation-only meter like this one
|
|
54
|
+
// must negate its (always non-negative) wattage for Matter.
|
|
55
|
+
const bridge = new matterEnergy_1.MatterEnergyBridge(platform.api, platform.log, 'exported');
|
|
56
|
+
if (bridge.isSupported()) {
|
|
57
|
+
this.matter = bridge;
|
|
58
|
+
bridge.register(`${serialNumber}-solar`, displayName, `${serialNumber}-solar`, {
|
|
59
|
+
powerW: -this.lastPowerW,
|
|
60
|
+
exportedEnergyKWh: this.lastEnergyKWh,
|
|
61
|
+
}).catch(() => { });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
platform.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.');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
45
67
|
}
|
|
46
68
|
updateValues(reading) {
|
|
47
69
|
const { Characteristic } = this.platform;
|
|
@@ -56,6 +78,7 @@ class SolarAccessory {
|
|
|
56
78
|
time: Math.round(Date.now() / 1000),
|
|
57
79
|
power: this.lastPowerW,
|
|
58
80
|
});
|
|
81
|
+
this.matter?.update({ powerW: -this.lastPowerW, exportedEnergyKWh: this.lastEnergyKWh }).catch(() => { });
|
|
59
82
|
this.platform.log.debug(`Solar: ${this.lastPowerW}W ${this.lastEnergyKWh}kWh`);
|
|
60
83
|
}
|
|
61
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solarAccessory.js","sourceRoot":"","sources":["../src/solarAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;
|
|
1
|
+
{"version":3,"file":"solarAccessory.js","sourceRoot":"","sources":["../src/solarAccessory.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-pvs6",
|
|
3
3
|
"displayName": "PVS6 Solar",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"description": "Homebridge plugin for SunStrong PVS6 solar monitoring — Eve Energy accessories with fakegato history.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "David Carson",
|