homebridge-pvs6 1.4.0 → 1.5.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 +56 -4
- package/config.schema.json +91 -1
- package/dist/gridExportAccessory.d.ts +1 -0
- package/dist/gridExportAccessory.d.ts.map +1 -1
- package/dist/gridExportAccessory.js +4 -23
- package/dist/gridExportAccessory.js.map +1 -1
- package/dist/gridImportAccessory.d.ts +1 -0
- package/dist/gridImportAccessory.d.ts.map +1 -1
- package/dist/gridImportAccessory.js +4 -23
- package/dist/gridImportAccessory.js.map +1 -1
- package/dist/homeConsumptionAccessory.d.ts +1 -0
- package/dist/homeConsumptionAccessory.d.ts.map +1 -1
- package/dist/homeConsumptionAccessory.js +4 -23
- package/dist/homeConsumptionAccessory.js.map +1 -1
- package/dist/meterCharacteristics.d.ts +15 -0
- package/dist/meterCharacteristics.d.ts.map +1 -0
- package/dist/meterCharacteristics.js +71 -0
- package/dist/meterCharacteristics.js.map +1 -0
- package/dist/platform.d.ts +7 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +89 -60
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +5 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/solarAccessory.d.ts +1 -0
- package/dist/solarAccessory.d.ts.map +1 -1
- package/dist/solarAccessory.js +4 -26
- package/dist/solarAccessory.js.map +1 -1
- package/dist/throttle.d.ts +53 -0
- package/dist/throttle.d.ts.map +1 -0
- package/dist/throttle.js +163 -0
- package/dist/throttle.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -136,6 +136,11 @@ Uncheck **Auto Discover** and supply the host and serial number directly. This s
|
|
|
136
136
|
"serialNumber": "ZT231385000549A1234",
|
|
137
137
|
"pollInterval": 10,
|
|
138
138
|
"matter": true,
|
|
139
|
+
"evePowerUpdates": "throttled",
|
|
140
|
+
"minChangeWatts": 25,
|
|
141
|
+
"minChangePercent": 2,
|
|
142
|
+
"minChangeKwh": 0.1,
|
|
143
|
+
"switchHoldSeconds": 60,
|
|
139
144
|
"accessories": {
|
|
140
145
|
"grid": true,
|
|
141
146
|
"homeConsumption": true
|
|
@@ -159,6 +164,11 @@ Uncheck **Auto Discover** and supply the host and serial number directly. This s
|
|
|
159
164
|
| `serialNumber` | string | no* | — | Full PVS6 serial number. The last 5 characters are used as the API password. Used only when `autoDiscover` is `false` |
|
|
160
165
|
| `pollInterval` | integer | no | `10` | Seconds between polls. Minimum enforced: `5` |
|
|
161
166
|
| `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)) |
|
|
167
|
+
| `evePowerUpdates` | string | no | `"throttled"` | How Eve Watts and Eve kWh are sent to HomeKit: `"throttled"`, `"pollOnly"` or `"live"`. See [HomeKit Updates & Automations](#homekit-updates--automations) |
|
|
168
|
+
| `minChangeWatts` | number | no | `25` | Throttled mode: push Eve Watts once it has changed by this many watts, or by `minChangePercent` if that is larger |
|
|
169
|
+
| `minChangePercent` | number | no | `2` | Throttled mode: push Eve Watts once it has changed by this percentage of the last value pushed |
|
|
170
|
+
| `minChangeKwh` | number | no | `0.1` | Throttled mode: push Eve kWh once it has changed by this much |
|
|
171
|
+
| `switchHoldSeconds` | integer | no | `60` | A power-derived On switch only changes once the new state has held this long. `0` disables the hold |
|
|
162
172
|
| `accessories.grid` | boolean | no | `true` | Enable the Grid Import + Grid Export accessory pair. Set `false` to disable both |
|
|
163
173
|
| `accessories.homeConsumption` | boolean | no | `false` | Enable the Home Consumption accessory. Opt-in; off by default |
|
|
164
174
|
| `solarName` | string | no | `"Solar Production"` | HomeKit display name for the Solar Production accessory |
|
|
@@ -168,6 +178,35 @@ Uncheck **Auto Discover** and supply the host and serial number directly. This s
|
|
|
168
178
|
|
|
169
179
|
\* Required when `autoDiscover` is `false`.
|
|
170
180
|
|
|
181
|
+
### HomeKit Updates & Automations
|
|
182
|
+
|
|
183
|
+
The PVS6 is polled every ~10 seconds, and each reading differs from the last by a few watts. If every reading were pushed to HomeKit, each accessory's Eve Watts and Eve kWh values would send an event on every poll, adding up to about 1,000 events per hour. The settings below reduce that without breaking your automations.
|
|
184
|
+
|
|
185
|
+
#### Eve power and energy values (`evePowerUpdates`)
|
|
186
|
+
|
|
187
|
+
Eve Watts and Eve kWh are Eve custom characteristics. The Home app doesn't show them, but **Eve and Home+ automations can trigger on them** ("when power rises above 3 kW") **or check them as conditions**. Choose a mode with that in mind:
|
|
188
|
+
|
|
189
|
+
| Mode | What is pushed | Effect on automations |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| `throttled` (default) | Eve Watts when it changes by at least `max(minChangeWatts, minChangePercent%)` (defaults 25 W / 2%, so 25 W below 1,250 W and 2% above). Eve kWh when it changes by at least `minChangeKwh` (default 0.1 kWh). Either value is also pushed every 5 minutes, even if it hasn't changed much | Triggers and conditions keep working. Values are accurate to within the configured thresholds |
|
|
192
|
+
| `pollOnly` | Nothing. Event notifications are removed from these characteristics, and apps get the newest reading when they read the accessory | Lowest traffic, but **triggers on these values stop firing**. Use it only if no automation uses them |
|
|
193
|
+
| `live` | Every reading, on every poll | Original behaviour; highest traffic |
|
|
194
|
+
|
|
195
|
+
In every mode, reading an accessory returns the latest value, and the current values are reported as soon as the plugin starts.
|
|
196
|
+
|
|
197
|
+
#### On switches
|
|
198
|
+
|
|
199
|
+
Each accessory's **On** switch is a standard HomeKit characteristic. It always sends events, so Home app automations that use it keep working. To keep the switches from flickering at sunrise, at sunset, or when a cloud passes, each one is derived from power with:
|
|
200
|
+
|
|
201
|
+
- **a deadband:** it turns on above 50 W and off below 20 W
|
|
202
|
+
- **a hold:** a new state must last `switchHoldSeconds` (default 60) before it's reported. If power goes back first, the change is dropped. Set it to `0` to report changes on the next poll
|
|
203
|
+
|
|
204
|
+
Because of the hold, **automations triggered by these switches can fire up to `switchHoldSeconds` later** than the underlying change in power.
|
|
205
|
+
|
|
206
|
+
#### Logging
|
|
207
|
+
|
|
208
|
+
At debug level, each suppressed Eve update and each held or cancelled switch change is logged. Once an hour a single debug line reports how many updates were sent and how many were suppressed.
|
|
209
|
+
|
|
171
210
|
### Finding Your Serial Number
|
|
172
211
|
|
|
173
212
|
The serial number is printed on the label on the PVS6 unit (format: `ZT...`). It is also visible in the SunStrong Connect app and is broadcast by the PVS6 itself via mDNS (which is how Auto Discover retrieves it). The last 5 characters are used as the local API login password — no separate password configuration is required.
|
|
@@ -180,7 +219,7 @@ The serial number is printed on the label on the PVS6 unit (format: `ZT...`). It
|
|
|
180
219
|
|
|
181
220
|
| Characteristic | Source | Notes |
|
|
182
221
|
|---|---|---|
|
|
183
|
-
| On | `pv_p
|
|
222
|
+
| On | `pv_p` | True when panels are generating: on above 50 W, off below 20 W, after the state has held for `switchHoldSeconds` |
|
|
184
223
|
| OutletInUse | Always `true` | Required by Eve Energy |
|
|
185
224
|
| Eve Watts | `pv_p × 1000` | Real-time solar output in Watts |
|
|
186
225
|
| Eve kWh | `pv_en` | Lifetime generation in kWh |
|
|
@@ -189,7 +228,7 @@ The serial number is printed on the label on the PVS6 unit (format: `ZT...`). It
|
|
|
189
228
|
|
|
190
229
|
| Characteristic | Source | Notes |
|
|
191
230
|
|---|---|---|
|
|
192
|
-
| On | `net_p
|
|
231
|
+
| On | `max(0, net_p)` | True when importing from the grid: on above 50 W, off below 20 W, after the state has held for `switchHoldSeconds` |
|
|
193
232
|
| OutletInUse | Always `true` | Required by Eve Energy |
|
|
194
233
|
| Eve Watts | `max(0, net_p) × 1000` | Import watts; zero when net-exporting |
|
|
195
234
|
| Eve kWh | `posLtea3phsumKwh` | Lifetime imported energy from consumption CT meter |
|
|
@@ -198,7 +237,7 @@ The serial number is printed on the label on the PVS6 unit (format: `ZT...`). It
|
|
|
198
237
|
|
|
199
238
|
| Characteristic | Source | Notes |
|
|
200
239
|
|---|---|---|
|
|
201
|
-
| On | `net_p
|
|
240
|
+
| On | `max(0, −net_p)` | True when net-exporting to the grid: on above 50 W, off below 20 W, after the state has held for `switchHoldSeconds` |
|
|
202
241
|
| OutletInUse | Always `true` | Required by Eve Energy |
|
|
203
242
|
| Eve Watts | `max(0, −net_p) × 1000` | Export watts; zero when importing |
|
|
204
243
|
| Eve kWh | `negLtea3phsumKwh` | Lifetime exported energy from consumption CT meter |
|
|
@@ -209,7 +248,7 @@ Shows the total real-time load of the home and a derived lifetime consumption fi
|
|
|
209
248
|
|
|
210
249
|
| Characteristic | Source | Notes |
|
|
211
250
|
|---|---|---|
|
|
212
|
-
| On | `site_load_p
|
|
251
|
+
| On | `site_load_p` | True when the house is drawing power (on above 50 W, off below 20 W, after the state has held for `switchHoldSeconds`; always on in practice) |
|
|
213
252
|
| OutletInUse | Always `true` | Required by Eve Energy |
|
|
214
253
|
| Eve Watts | `site_load_p × 1000` | Real-time site load in Watts |
|
|
215
254
|
| Eve kWh | `pv_en + posLtea3phsumKwh − negLtea3phsumKwh` | Derived lifetime consumption — all solar generated, plus grid imported, minus grid exported |
|
|
@@ -220,6 +259,13 @@ The derived kWh formula is exact without a battery: solar energy either goes to
|
|
|
220
259
|
|
|
221
260
|
## Apple Home Energy & Matter
|
|
222
261
|
|
|
262
|
+
<table>
|
|
263
|
+
<td>
|
|
264
|
+
<img width="600" alt="MatterEnergy" src="https://github.com/user-attachments/assets/fcff5f12-54cb-4431-a944-8ac04c6e044f" />
|
|
265
|
+
<br><sub>Apple Energy view with other Energy accessories</sub>
|
|
266
|
+
</td>
|
|
267
|
+
</table>
|
|
268
|
+
|
|
223
269
|
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
270
|
|
|
225
271
|
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:
|
|
@@ -276,6 +322,12 @@ npm install
|
|
|
276
322
|
npm run build
|
|
277
323
|
```
|
|
278
324
|
|
|
325
|
+
To run the unit tests:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
npm test
|
|
329
|
+
```
|
|
330
|
+
|
|
279
331
|
To develop with live rebuilds:
|
|
280
332
|
|
|
281
333
|
```bash
|
package/config.schema.json
CHANGED
|
@@ -41,6 +41,69 @@
|
|
|
41
41
|
"default": false,
|
|
42
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
43
|
},
|
|
44
|
+
"evePowerUpdates": {
|
|
45
|
+
"title": "Eve power/energy updates",
|
|
46
|
+
"type": "string",
|
|
47
|
+
"default": "throttled",
|
|
48
|
+
"oneOf": [
|
|
49
|
+
{
|
|
50
|
+
"title": "Throttled \u2014 push on meaningful change or every 5 minutes (recommended)",
|
|
51
|
+
"enum": [
|
|
52
|
+
"throttled"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"title": "Poll only \u2014 never push; lowest traffic, breaks Eve/Home+ triggers on these values",
|
|
57
|
+
"enum": [
|
|
58
|
+
"pollOnly"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"title": "Live \u2014 push every poll (original behaviour)",
|
|
63
|
+
"enum": [
|
|
64
|
+
"live"
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"description": "How Eve Watts and Eve kWh values are sent to HomeKit. Eve and Home+ automations can trigger on or check these values. Throttled keeps those automations working with values accurate to within the thresholds below. Poll only gives the lowest traffic, but automations triggered by these values stop firing; use it only if no automation uses them."
|
|
69
|
+
},
|
|
70
|
+
"minChangeWatts": {
|
|
71
|
+
"title": "Minimum power change (W)",
|
|
72
|
+
"type": "number",
|
|
73
|
+
"default": 25,
|
|
74
|
+
"minimum": 0,
|
|
75
|
+
"description": "Throttled: push Eve Watts when it has changed by at least this many watts, or by the percentage below if that is larger.",
|
|
76
|
+
"condition": {
|
|
77
|
+
"functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"minChangePercent": {
|
|
81
|
+
"title": "Minimum power change (%)",
|
|
82
|
+
"type": "number",
|
|
83
|
+
"default": 2,
|
|
84
|
+
"minimum": 0,
|
|
85
|
+
"description": "Throttled: push Eve Watts when it has changed by at least this percentage of the last value pushed, or by the watts above if that is larger.",
|
|
86
|
+
"condition": {
|
|
87
|
+
"functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"minChangeKwh": {
|
|
91
|
+
"title": "Minimum energy change (kWh)",
|
|
92
|
+
"type": "number",
|
|
93
|
+
"default": 0.1,
|
|
94
|
+
"minimum": 0,
|
|
95
|
+
"description": "Throttled: push Eve kWh when it has changed by at least this much.",
|
|
96
|
+
"condition": {
|
|
97
|
+
"functionBody": "return !model.evePowerUpdates || model.evePowerUpdates === 'throttled';"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"switchHoldSeconds": {
|
|
101
|
+
"title": "Switch hold (seconds)",
|
|
102
|
+
"type": "integer",
|
|
103
|
+
"default": 60,
|
|
104
|
+
"minimum": 0,
|
|
105
|
+
"description": "The On switches derived from power (on above 50 W, off below 20 W) only change once the new state has held for this long. Automations triggered by these switches can fire up to this much later than the underlying change. 0 disables the hold."
|
|
106
|
+
},
|
|
44
107
|
"accessories": {
|
|
45
108
|
"title": "Accessories",
|
|
46
109
|
"type": "object",
|
|
@@ -84,5 +147,32 @@
|
|
|
84
147
|
}
|
|
85
148
|
},
|
|
86
149
|
"required": []
|
|
87
|
-
}
|
|
150
|
+
},
|
|
151
|
+
"layout": [
|
|
152
|
+
"name",
|
|
153
|
+
"autoDiscover",
|
|
154
|
+
"host",
|
|
155
|
+
"serialNumber",
|
|
156
|
+
"pollInterval",
|
|
157
|
+
"matter",
|
|
158
|
+
{
|
|
159
|
+
"type": "fieldset",
|
|
160
|
+
"title": "HomeKit Updates",
|
|
161
|
+
"expandable": true,
|
|
162
|
+
"expanded": false,
|
|
163
|
+
"description": "Control how often power readings are sent to HomeKit.",
|
|
164
|
+
"items": [
|
|
165
|
+
"evePowerUpdates",
|
|
166
|
+
"minChangeWatts",
|
|
167
|
+
"minChangePercent",
|
|
168
|
+
"minChangeKwh",
|
|
169
|
+
"switchHoldSeconds"
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"accessories",
|
|
173
|
+
"solarName",
|
|
174
|
+
"gridName",
|
|
175
|
+
"gridExportName",
|
|
176
|
+
"homeConsumptionName"
|
|
177
|
+
]
|
|
88
178
|
}
|
|
@@ -7,6 +7,7 @@ export declare class GridExportAccessory {
|
|
|
7
7
|
private readonly historyService;
|
|
8
8
|
private lastPowerW;
|
|
9
9
|
private lastEnergyKWh;
|
|
10
|
+
private readonly meter;
|
|
10
11
|
constructor(platform: PVS6Platform, accessory: PlatformAccessory, FakeGatoHistoryService: any, displayName: string, serialNumber: string);
|
|
11
12
|
updateValues(reading: PVS6Reading): void;
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridExportAccessory.d.ts","sourceRoot":"","sources":["../src/gridExportAccessory.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":"gridExportAccessory.d.ts","sourceRoot":"","sources":["../src/gridExportAccessory.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,mBAAmB;IAU5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IAErC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;gBAG1B,QAAQ,EAAE,YAAY,EACvC,SAAS,EAAE,iBAAiB,EAE5B,sBAAsB,EAAE,GAAG,EAC3B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;IAyBtB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;CAczC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GridExportAccessory = void 0;
|
|
4
4
|
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
5
|
+
const meterCharacteristics_1 = require("./meterCharacteristics");
|
|
5
6
|
class GridExportAccessory {
|
|
6
7
|
constructor(platform, accessory,
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -10,7 +11,6 @@ class GridExportAccessory {
|
|
|
10
11
|
this.lastPowerW = 0;
|
|
11
12
|
this.lastEnergyKWh = 0;
|
|
12
13
|
const { Characteristic } = platform;
|
|
13
|
-
const { EveWatts, EveKWh } = platform.eveChars;
|
|
14
14
|
const infoService = accessory.getService(platform.Service.AccessoryInformation) ??
|
|
15
15
|
accessory.addService(platform.Service.AccessoryInformation);
|
|
16
16
|
infoService
|
|
@@ -21,34 +21,15 @@ class GridExportAccessory {
|
|
|
21
21
|
this.service = existingService ??
|
|
22
22
|
accessory.addService(new platform.api.hap.Service(displayName, eveCharacteristics_1.EVE_ENERGY_SERVICE_UUID));
|
|
23
23
|
this.service.setCharacteristic(Characteristic.Name, displayName);
|
|
24
|
-
// On
|
|
25
|
-
this.service
|
|
26
|
-
.getCharacteristic(Characteristic.On)
|
|
27
|
-
.onGet(() => this.lastPowerW > 0)
|
|
28
|
-
.onSet(async () => {
|
|
29
|
-
this.service.updateCharacteristic(Characteristic.On, this.lastPowerW > 0);
|
|
30
|
-
});
|
|
31
|
-
this.service
|
|
32
|
-
.getCharacteristic(Characteristic.OutletInUse)
|
|
33
|
-
.onGet(() => true);
|
|
34
|
-
this.service
|
|
35
|
-
.getCharacteristic(EveWatts)
|
|
36
|
-
.onGet(() => this.lastPowerW);
|
|
37
|
-
this.service
|
|
38
|
-
.getCharacteristic(EveKWh)
|
|
39
|
-
.onGet(() => this.lastEnergyKWh);
|
|
24
|
+
// On (power-derived, with deadband + hold), OutletInUse, Eve Watts, Eve kWh.
|
|
25
|
+
this.meter = new meterCharacteristics_1.MeterCharacteristics(platform, accessory, this.service, 'grid-export', displayName);
|
|
40
26
|
this.historyService = new FakeGatoHistoryService('energy', accessory, { storage: 'fs' });
|
|
41
27
|
}
|
|
42
28
|
updateValues(reading) {
|
|
43
|
-
const { Characteristic } = this.platform;
|
|
44
|
-
const { EveWatts, EveKWh } = this.platform.eveChars;
|
|
45
29
|
// Non-negative: positive when net-exporting, zero when importing.
|
|
46
30
|
this.lastPowerW = Math.max(0, -reading.netPowerW);
|
|
47
31
|
this.lastEnergyKWh = reading.gridExportKWh;
|
|
48
|
-
this.
|
|
49
|
-
this.service.updateCharacteristic(Characteristic.OutletInUse, true);
|
|
50
|
-
this.service.updateCharacteristic(EveWatts, this.lastPowerW);
|
|
51
|
-
this.service.updateCharacteristic(EveKWh, this.lastEnergyKWh);
|
|
32
|
+
this.meter.update(this.lastPowerW, this.lastEnergyKWh);
|
|
52
33
|
this.historyService.addEntry({
|
|
53
34
|
time: Math.round(Date.now() / 1000),
|
|
54
35
|
power: this.lastPowerW,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridExportAccessory.js","sourceRoot":"","sources":["../src/gridExportAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;
|
|
1
|
+
{"version":3,"file":"gridExportAccessory.js","sourceRoot":"","sources":["../src/gridExportAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;AAC/D,iEAA8D;AAE9D,MAAa,mBAAmB;IAS9B,YACmB,QAAsB,EACvC,SAA4B;IAC5B,8DAA8D;IAC9D,sBAA2B,EAC3B,WAAmB,EACnB,YAAoB;QALH,aAAQ,GAAR,QAAQ,CAAc;QALjC,eAAU,GAAG,CAAC,CAAC;QACf,kBAAa,GAAG,CAAC,CAAC;QAWxB,MAAM,EAAE,cAAc,EAAE,GAAG,QAAQ,CAAC;QAEpC,MAAM,WAAW,GACf,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC;YAC3D,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAE9D,WAAW;aACR,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC;aAC3D,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC;aAC/C,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,GAAG,YAAY,cAAc,CAAC,CAAC;QAEjF,MAAM,eAAe,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,4CAAuB,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,GAAG,eAAe;YAC5B,SAAS,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,4CAAuB,CAAC,CAAC,CAAC;QAE3F,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAEjE,6EAA6E;QAC7E,IAAI,CAAC,KAAK,GAAG,IAAI,2CAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAErG,IAAI,CAAC,cAAc,GAAG,IAAI,sBAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,YAAY,CAAC,OAAoB;QAC/B,kEAAkE;QAClE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAE3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEvD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;YAC3B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YACnC,KAAK,EAAE,IAAI,CAAC,UAAU;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;IACxF,CAAC;CACF;AAtDD,kDAsDC"}
|
|
@@ -7,6 +7,7 @@ export declare class GridImportAccessory {
|
|
|
7
7
|
private readonly historyService;
|
|
8
8
|
private lastPowerW;
|
|
9
9
|
private lastEnergyKWh;
|
|
10
|
+
private readonly meter;
|
|
10
11
|
constructor(platform: PVS6Platform, accessory: PlatformAccessory, FakeGatoHistoryService: any, displayName: string, serialNumber: string);
|
|
11
12
|
updateValues(reading: PVS6Reading): void;
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridImportAccessory.d.ts","sourceRoot":"","sources":["../src/gridImportAccessory.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":"gridImportAccessory.d.ts","sourceRoot":"","sources":["../src/gridImportAccessory.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,mBAAmB;IAU5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IAErC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;gBAG1B,QAAQ,EAAE,YAAY,EACvC,SAAS,EAAE,iBAAiB,EAE5B,sBAAsB,EAAE,GAAG,EAC3B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;IAyBtB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;CAczC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GridImportAccessory = void 0;
|
|
4
4
|
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
5
|
+
const meterCharacteristics_1 = require("./meterCharacteristics");
|
|
5
6
|
class GridImportAccessory {
|
|
6
7
|
constructor(platform, accessory,
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -10,7 +11,6 @@ class GridImportAccessory {
|
|
|
10
11
|
this.lastPowerW = 0;
|
|
11
12
|
this.lastEnergyKWh = 0;
|
|
12
13
|
const { Characteristic } = platform;
|
|
13
|
-
const { EveWatts, EveKWh } = platform.eveChars;
|
|
14
14
|
const infoService = accessory.getService(platform.Service.AccessoryInformation) ??
|
|
15
15
|
accessory.addService(platform.Service.AccessoryInformation);
|
|
16
16
|
infoService
|
|
@@ -21,34 +21,15 @@ class GridImportAccessory {
|
|
|
21
21
|
this.service = existingService ??
|
|
22
22
|
accessory.addService(new platform.api.hap.Service(displayName, eveCharacteristics_1.EVE_ENERGY_SERVICE_UUID));
|
|
23
23
|
this.service.setCharacteristic(Characteristic.Name, displayName);
|
|
24
|
-
// On
|
|
25
|
-
this.service
|
|
26
|
-
.getCharacteristic(Characteristic.On)
|
|
27
|
-
.onGet(() => this.lastPowerW > 0)
|
|
28
|
-
.onSet(async () => {
|
|
29
|
-
this.service.updateCharacteristic(Characteristic.On, this.lastPowerW > 0);
|
|
30
|
-
});
|
|
31
|
-
this.service
|
|
32
|
-
.getCharacteristic(Characteristic.OutletInUse)
|
|
33
|
-
.onGet(() => true);
|
|
34
|
-
this.service
|
|
35
|
-
.getCharacteristic(EveWatts)
|
|
36
|
-
.onGet(() => this.lastPowerW);
|
|
37
|
-
this.service
|
|
38
|
-
.getCharacteristic(EveKWh)
|
|
39
|
-
.onGet(() => this.lastEnergyKWh);
|
|
24
|
+
// On (power-derived, with deadband + hold), OutletInUse, Eve Watts, Eve kWh.
|
|
25
|
+
this.meter = new meterCharacteristics_1.MeterCharacteristics(platform, accessory, this.service, 'grid-import', displayName);
|
|
40
26
|
this.historyService = new FakeGatoHistoryService('energy', accessory, { storage: 'fs' });
|
|
41
27
|
}
|
|
42
28
|
updateValues(reading) {
|
|
43
|
-
const { Characteristic } = this.platform;
|
|
44
|
-
const { EveWatts, EveKWh } = this.platform.eveChars;
|
|
45
29
|
// Non-negative: zero when net-exporting, positive when importing.
|
|
46
30
|
this.lastPowerW = Math.max(0, reading.netPowerW);
|
|
47
31
|
this.lastEnergyKWh = reading.gridImportKWh;
|
|
48
|
-
this.
|
|
49
|
-
this.service.updateCharacteristic(Characteristic.OutletInUse, true);
|
|
50
|
-
this.service.updateCharacteristic(EveWatts, this.lastPowerW);
|
|
51
|
-
this.service.updateCharacteristic(EveKWh, this.lastEnergyKWh);
|
|
32
|
+
this.meter.update(this.lastPowerW, this.lastEnergyKWh);
|
|
52
33
|
this.historyService.addEntry({
|
|
53
34
|
time: Math.round(Date.now() / 1000),
|
|
54
35
|
power: this.lastPowerW,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridImportAccessory.js","sourceRoot":"","sources":["../src/gridImportAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;
|
|
1
|
+
{"version":3,"file":"gridImportAccessory.js","sourceRoot":"","sources":["../src/gridImportAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;AAC/D,iEAA8D;AAE9D,MAAa,mBAAmB;IAS9B,YACmB,QAAsB,EACvC,SAA4B;IAC5B,8DAA8D;IAC9D,sBAA2B,EAC3B,WAAmB,EACnB,YAAoB;QALH,aAAQ,GAAR,QAAQ,CAAc;QALjC,eAAU,GAAG,CAAC,CAAC;QACf,kBAAa,GAAG,CAAC,CAAC;QAWxB,MAAM,EAAE,cAAc,EAAE,GAAG,QAAQ,CAAC;QAEpC,MAAM,WAAW,GACf,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC;YAC3D,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAE9D,WAAW;aACR,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC;aAC3D,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC;aAC/C,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,GAAG,YAAY,OAAO,CAAC,CAAC;QAE1E,MAAM,eAAe,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,4CAAuB,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,GAAG,eAAe;YAC5B,SAAS,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,4CAAuB,CAAC,CAAC,CAAC;QAE3F,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAEjE,6EAA6E;QAC7E,IAAI,CAAC,KAAK,GAAG,IAAI,2CAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QAErG,IAAI,CAAC,cAAc,GAAG,IAAI,sBAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,YAAY,CAAC,OAAoB;QAC/B,kEAAkE;QAClE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAE3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEvD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;YAC3B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YACnC,KAAK,EAAE,IAAI,CAAC,UAAU;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;IACxF,CAAC;CACF;AAtDD,kDAsDC"}
|
|
@@ -7,6 +7,7 @@ export declare class HomeConsumptionAccessory {
|
|
|
7
7
|
private readonly historyService;
|
|
8
8
|
private lastPowerW;
|
|
9
9
|
private lastEnergyKWh;
|
|
10
|
+
private readonly meter;
|
|
10
11
|
constructor(platform: PVS6Platform, accessory: PlatformAccessory, FakeGatoHistoryService: any, displayName: string, serialNumber: string);
|
|
11
12
|
updateValues(reading: PVS6Reading): void;
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homeConsumptionAccessory.d.ts","sourceRoot":"","sources":["../src/homeConsumptionAccessory.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":"homeConsumptionAccessory.d.ts","sourceRoot":"","sources":["../src/homeConsumptionAccessory.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,wBAAwB;IAUjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;IAErC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;gBAG1B,QAAQ,EAAE,YAAY,EACvC,SAAS,EAAE,iBAAiB,EAE5B,sBAAsB,EAAE,GAAG,EAC3B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;IAyBtB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;CAazC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HomeConsumptionAccessory = void 0;
|
|
4
4
|
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
5
|
+
const meterCharacteristics_1 = require("./meterCharacteristics");
|
|
5
6
|
class HomeConsumptionAccessory {
|
|
6
7
|
constructor(platform, accessory,
|
|
7
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -10,7 +11,6 @@ class HomeConsumptionAccessory {
|
|
|
10
11
|
this.lastPowerW = 0;
|
|
11
12
|
this.lastEnergyKWh = 0;
|
|
12
13
|
const { Characteristic } = platform;
|
|
13
|
-
const { EveWatts, EveKWh } = platform.eveChars;
|
|
14
14
|
const infoService = accessory.getService(platform.Service.AccessoryInformation) ??
|
|
15
15
|
accessory.addService(platform.Service.AccessoryInformation);
|
|
16
16
|
infoService
|
|
@@ -21,33 +21,14 @@ class HomeConsumptionAccessory {
|
|
|
21
21
|
this.service = existingService ??
|
|
22
22
|
accessory.addService(new platform.api.hap.Service(displayName, eveCharacteristics_1.EVE_ENERGY_SERVICE_UUID));
|
|
23
23
|
this.service.setCharacteristic(Characteristic.Name, displayName);
|
|
24
|
-
// On
|
|
25
|
-
this.service
|
|
26
|
-
.getCharacteristic(Characteristic.On)
|
|
27
|
-
.onGet(() => this.lastPowerW > 0)
|
|
28
|
-
.onSet(async () => {
|
|
29
|
-
this.service.updateCharacteristic(Characteristic.On, this.lastPowerW > 0);
|
|
30
|
-
});
|
|
31
|
-
this.service
|
|
32
|
-
.getCharacteristic(Characteristic.OutletInUse)
|
|
33
|
-
.onGet(() => true);
|
|
34
|
-
this.service
|
|
35
|
-
.getCharacteristic(EveWatts)
|
|
36
|
-
.onGet(() => this.lastPowerW);
|
|
37
|
-
this.service
|
|
38
|
-
.getCharacteristic(EveKWh)
|
|
39
|
-
.onGet(() => this.lastEnergyKWh);
|
|
24
|
+
// On (power-derived, with deadband + hold), OutletInUse, Eve Watts, Eve kWh.
|
|
25
|
+
this.meter = new meterCharacteristics_1.MeterCharacteristics(platform, accessory, this.service, 'home', displayName);
|
|
40
26
|
this.historyService = new FakeGatoHistoryService('energy', accessory, { storage: 'fs' });
|
|
41
27
|
}
|
|
42
28
|
updateValues(reading) {
|
|
43
|
-
const { Characteristic } = this.platform;
|
|
44
|
-
const { EveWatts, EveKWh } = this.platform.eveChars;
|
|
45
29
|
this.lastPowerW = reading.siteLoadPowerW;
|
|
46
30
|
this.lastEnergyKWh = reading.homeConsumptionKWh;
|
|
47
|
-
this.
|
|
48
|
-
this.service.updateCharacteristic(Characteristic.OutletInUse, true);
|
|
49
|
-
this.service.updateCharacteristic(EveWatts, this.lastPowerW);
|
|
50
|
-
this.service.updateCharacteristic(EveKWh, this.lastEnergyKWh);
|
|
31
|
+
this.meter.update(this.lastPowerW, this.lastEnergyKWh);
|
|
51
32
|
this.historyService.addEntry({
|
|
52
33
|
time: Math.round(Date.now() / 1000),
|
|
53
34
|
power: this.lastPowerW,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"homeConsumptionAccessory.js","sourceRoot":"","sources":["../src/homeConsumptionAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;
|
|
1
|
+
{"version":3,"file":"homeConsumptionAccessory.js","sourceRoot":"","sources":["../src/homeConsumptionAccessory.ts"],"names":[],"mappings":";;;AAGA,6DAA+D;AAC/D,iEAA8D;AAE9D,MAAa,wBAAwB;IASnC,YACmB,QAAsB,EACvC,SAA4B;IAC5B,8DAA8D;IAC9D,sBAA2B,EAC3B,WAAmB,EACnB,YAAoB;QALH,aAAQ,GAAR,QAAQ,CAAc;QALjC,eAAU,GAAG,CAAC,CAAC;QACf,kBAAa,GAAG,CAAC,CAAC;QAWxB,MAAM,EAAE,cAAc,EAAE,GAAG,QAAQ,CAAC;QAEpC,MAAM,WAAW,GACf,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC;YAC3D,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAE9D,WAAW;aACR,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC;aAC3D,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC;aAC/C,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,GAAG,YAAY,OAAO,CAAC,CAAC;QAE1E,MAAM,eAAe,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,4CAAuB,CAAC,CAAC;QACzF,IAAI,CAAC,OAAO,GAAG,eAAe;YAC5B,SAAS,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,4CAAuB,CAAC,CAAC,CAAC;QAE3F,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAEjE,6EAA6E;QAC7E,IAAI,CAAC,KAAK,GAAG,IAAI,2CAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAE9F,IAAI,CAAC,cAAc,GAAG,IAAI,sBAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,YAAY,CAAC,OAAoB;QAC/B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;QACzC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;QAEhD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEvD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC;YAC3B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YACnC,KAAK,EAAE,IAAI,CAAC,UAAU;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxG,CAAC;CACF;AArDD,4DAqDC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PlatformAccessory, Service } from 'homebridge';
|
|
2
|
+
import type { PVS6Platform } from './platform';
|
|
3
|
+
export declare function applyEvePerms(accessory: PlatformAccessory, notify: boolean): void;
|
|
4
|
+
export declare class MeterCharacteristics {
|
|
5
|
+
private readonly platform;
|
|
6
|
+
private readonly service;
|
|
7
|
+
private readonly key;
|
|
8
|
+
private powerW;
|
|
9
|
+
private energyKWh;
|
|
10
|
+
private readonly onSwitch;
|
|
11
|
+
constructor(platform: PVS6Platform, accessory: PlatformAccessory, service: Service, key: string, label: string);
|
|
12
|
+
get isOn(): boolean;
|
|
13
|
+
update(powerW: number, energyKWh: number): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=meterCharacteristics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meterCharacteristics.d.ts","sourceRoot":"","sources":["../src/meterCharacteristics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,iBAAiB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,wBAAgB,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAQjF;AAMD,qBAAa,oBAAoB;IAM7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG;IARtB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;gBAGpB,QAAQ,EAAE,YAAY,EACvC,SAAS,EAAE,iBAAiB,EACX,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EAC5B,KAAK,EAAE,MAAM;IA2Bf,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAmBhD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MeterCharacteristics = void 0;
|
|
4
|
+
exports.applyEvePerms = applyEvePerms;
|
|
5
|
+
const eveCharacteristics_1 = require("./eveCharacteristics");
|
|
6
|
+
// Sets NOTIFY on the Eve power/energy characteristics according to the
|
|
7
|
+
// evePowerUpdates mode (removed for pollOnly, present otherwise). Called from
|
|
8
|
+
// configureAccessory() for cached accessories, so the perms are right before
|
|
9
|
+
// the bridge is published, and again when an accessory is set up.
|
|
10
|
+
function applyEvePerms(accessory, notify) {
|
|
11
|
+
const perms = notify ? ["pr" /* Perms.PAIRED_READ */, "ev" /* Perms.NOTIFY */] : ["pr" /* Perms.PAIRED_READ */];
|
|
12
|
+
const service = accessory.services.find(s => s.UUID === eveCharacteristics_1.EVE_ENERGY_SERVICE_UUID);
|
|
13
|
+
for (const c of service?.characteristics ?? []) {
|
|
14
|
+
if (c.UUID === eveCharacteristics_1.EVE_WATT_UUID || c.UUID === eveCharacteristics_1.EVE_KWH_UUID) {
|
|
15
|
+
c.setProps({ perms });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// The On / OutletInUse / Eve Watts / Eve kWh characteristics shared by every
|
|
20
|
+
// meter accessory. Holds the newest reading (served by onGet in every mode)
|
|
21
|
+
// and decides what to push via the platform's EveUpdatePolicy and a
|
|
22
|
+
// per-accessory PowerSwitch.
|
|
23
|
+
class MeterCharacteristics {
|
|
24
|
+
constructor(platform, accessory, service, key, label) {
|
|
25
|
+
this.platform = platform;
|
|
26
|
+
this.service = service;
|
|
27
|
+
this.key = key;
|
|
28
|
+
this.powerW = 0;
|
|
29
|
+
this.energyKWh = 0;
|
|
30
|
+
const { Characteristic: C } = platform;
|
|
31
|
+
const { EveWatts, EveKWh } = platform.eveChars;
|
|
32
|
+
this.onSwitch = platform.createPowerSwitch(label);
|
|
33
|
+
// On is read/write in HAP; the setter reverts to the reported state immediately.
|
|
34
|
+
service
|
|
35
|
+
.getCharacteristic(C.On)
|
|
36
|
+
.onGet(() => this.onSwitch.isOn)
|
|
37
|
+
.onSet(async () => {
|
|
38
|
+
service.updateCharacteristic(C.On, this.onSwitch.isOn);
|
|
39
|
+
});
|
|
40
|
+
// OutletInUse is required for Eve Energy to render correctly
|
|
41
|
+
service
|
|
42
|
+
.getCharacteristic(C.OutletInUse)
|
|
43
|
+
.onGet(() => true);
|
|
44
|
+
// Eve custom characteristics — getCharacteristic() is idempotent across restarts.
|
|
45
|
+
// Reads always return the newest reading, whatever was last pushed.
|
|
46
|
+
service.getCharacteristic(EveWatts).onGet(() => this.powerW);
|
|
47
|
+
service.getCharacteristic(EveKWh).onGet(() => this.energyKWh);
|
|
48
|
+
applyEvePerms(accessory, platform.evePolicy.notify);
|
|
49
|
+
}
|
|
50
|
+
get isOn() {
|
|
51
|
+
return this.onSwitch.isOn;
|
|
52
|
+
}
|
|
53
|
+
update(powerW, energyKWh) {
|
|
54
|
+
const { Characteristic: C } = this.platform;
|
|
55
|
+
const { EveWatts, EveKWh } = this.platform.eveChars;
|
|
56
|
+
const policy = this.platform.evePolicy;
|
|
57
|
+
this.powerW = powerW;
|
|
58
|
+
this.energyKWh = energyKWh;
|
|
59
|
+
// Standard characteristics stay evented (HAP only sends an event when the value changes).
|
|
60
|
+
this.service.updateCharacteristic(C.On, this.onSwitch.update(powerW));
|
|
61
|
+
this.service.updateCharacteristic(C.OutletInUse, true);
|
|
62
|
+
if (policy.shouldPush(`${this.key}.watts`, 'watts', powerW)) {
|
|
63
|
+
this.service.updateCharacteristic(EveWatts, powerW);
|
|
64
|
+
}
|
|
65
|
+
if (policy.shouldPush(`${this.key}.kwh`, 'kwh', energyKWh)) {
|
|
66
|
+
this.service.updateCharacteristic(EveKWh, energyKWh);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.MeterCharacteristics = MeterCharacteristics;
|
|
71
|
+
//# sourceMappingURL=meterCharacteristics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meterCharacteristics.js","sourceRoot":"","sources":["../src/meterCharacteristics.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { API, Characteristic, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service } from 'homebridge';
|
|
2
2
|
import { EveChars } from './eveCharacteristics';
|
|
3
|
+
import { EveUpdatePolicy, PowerSwitch } from './throttle';
|
|
3
4
|
export declare class PVS6Platform implements DynamicPlatformPlugin {
|
|
4
5
|
readonly Service: typeof Service;
|
|
5
6
|
readonly Characteristic: typeof Characteristic;
|
|
6
7
|
readonly api: API;
|
|
7
8
|
readonly eveChars: EveChars;
|
|
8
9
|
readonly log: Logger;
|
|
10
|
+
readonly evePolicy: EveUpdatePolicy;
|
|
11
|
+
private readonly updateConfig;
|
|
12
|
+
private readonly updateStats;
|
|
9
13
|
readonly accessories: PlatformAccessory[];
|
|
10
14
|
private client;
|
|
11
15
|
private readonly config;
|
|
@@ -16,6 +20,7 @@ export declare class PVS6Platform implements DynamicPlatformPlugin {
|
|
|
16
20
|
private homeConsumptionAccessory?;
|
|
17
21
|
private gridMatterBridge;
|
|
18
22
|
private pollTimer?;
|
|
23
|
+
private updateStatsTimer?;
|
|
19
24
|
private pollInFlight;
|
|
20
25
|
private backedOff;
|
|
21
26
|
private consecutiveNetworkErrors;
|
|
@@ -28,6 +33,7 @@ export declare class PVS6Platform implements DynamicPlatformPlugin {
|
|
|
28
33
|
private resolveConfig;
|
|
29
34
|
private discoverWithCache;
|
|
30
35
|
private setupAccessories;
|
|
36
|
+
createPowerSwitch(name: string): PowerSwitch;
|
|
31
37
|
private getOrCreateAccessory;
|
|
32
38
|
private get discoveryEnabled();
|
|
33
39
|
private checkRediscovery;
|
|
@@ -35,6 +41,7 @@ export declare class PVS6Platform implements DynamicPlatformPlugin {
|
|
|
35
41
|
private stopPolling;
|
|
36
42
|
private startAuthAndPolling;
|
|
37
43
|
private startPolling;
|
|
44
|
+
private pollOnce;
|
|
38
45
|
private triggerReauth;
|
|
39
46
|
private enterBackoff;
|
|
40
47
|
}
|
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;AAI1E,OAAO,EAAE,eAAe,EAAE,WAAW,EAAkD,MAAM,YAAY,CAAC;AAW1G,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,SAAS,EAAE,eAAe,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD,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,gBAAgB,CAAC,CAAiC;IAC1D,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;IA6DV,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;YAkBxC,aAAa;YA0Bb,iBAAiB;IAW/B,OAAO,CAAC,gBAAgB;IAuExB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAI5C,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;YAMN,QAAQ;IA+DtB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,YAAY;CASrB"}
|