homebridge-mynest 2.1.2 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/api/observe.d.ts +7 -0
- package/dist/api/observe.js +33 -6
- package/dist/api/transport.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented here. From the first release onward, [release-please](https://github.com/googleapis/release-please) owns this file — do not hand-edit version headings after `0.1.0` ships.
|
|
4
4
|
|
|
5
|
+
## [2.1.3](https://github.com/tbaur/homebridge-mynest/compare/v2.1.2...v2.1.3) (2026-10-26)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* log a Nest Observe stream reset at debug ([bc58dae](https://github.com/tbaur/homebridge-mynest/commit/bc58dae903350a101ea9372212199cb6965d80ff))
|
|
11
|
+
|
|
5
12
|
## [2.1.2](https://github.com/tbaur/homebridge-mynest/compare/v2.1.1...v2.1.2) (2026-10-26)
|
|
6
13
|
|
|
7
14
|
|
package/dist/api/observe.d.ts
CHANGED
|
@@ -30,12 +30,19 @@ export type ObserveEndReason =
|
|
|
30
30
|
| 'idle'
|
|
31
31
|
/** Nest closed the response. */
|
|
32
32
|
| 'ended'
|
|
33
|
+
/** Nest reset the HTTP/2 stream. Recover the same way as a clean close. */
|
|
34
|
+
| 'reset'
|
|
33
35
|
/** The caller asked to stop. */
|
|
34
36
|
| 'aborted';
|
|
35
37
|
export interface ObserveSessionResult {
|
|
36
38
|
readonly reason: ObserveEndReason;
|
|
37
39
|
readonly frameCount: number;
|
|
38
40
|
readonly durationMs: number;
|
|
41
|
+
/**
|
|
42
|
+
* nghttp2 code and request id, set only for {@link ObserveEndReason} `reset`.
|
|
43
|
+
* A clean close has no detail.
|
|
44
|
+
*/
|
|
45
|
+
readonly detail?: string;
|
|
39
46
|
}
|
|
40
47
|
/** Node's `http2.connect`, or a substitute supplied by tests. */
|
|
41
48
|
export type Http2Connect = typeof http2.connect;
|
package/dist/api/observe.js
CHANGED
|
@@ -39,6 +39,32 @@ const MAX_HANDLER_FAILURE_WARNINGS = 3;
|
|
|
39
39
|
const errors_1 = require("../errors");
|
|
40
40
|
const framing_1 = require("./framing");
|
|
41
41
|
const protobuf_1 = require("./protobuf");
|
|
42
|
+
/**
|
|
43
|
+
* Peer resets that mean this stream is over.
|
|
44
|
+
*
|
|
45
|
+
* Nest drains a live Observe stream with `RST_STREAM` `INTERNAL_ERROR`. Node
|
|
46
|
+
* reports that as "Stream closed with error code NGHTTP2_INTERNAL_ERROR".
|
|
47
|
+
* A stream that already delivered data clears the failure streak, so rejecting
|
|
48
|
+
* here made every recycle log "failed 1x in a row" at warning level. A clean
|
|
49
|
+
* `end` for the same recycle stays at debug. `NO_ERROR`, `CANCEL`,
|
|
50
|
+
* `REFUSED_STREAM`, and `STREAM_CLOSED` are the same kind of close. Protocol
|
|
51
|
+
* and flow-control errors still fail the session.
|
|
52
|
+
*/
|
|
53
|
+
const PEER_RESET = /(?:Stream|Session) closed with error code (NGHTTP2_(?:NO_ERROR|INTERNAL_ERROR|STREAM_CLOSED|REFUSED_STREAM|CANCEL))\b/;
|
|
54
|
+
/**
|
|
55
|
+
* Classify a socket error as a peer reset or a real stream failure.
|
|
56
|
+
*
|
|
57
|
+
* @see PEER_RESET
|
|
58
|
+
*/
|
|
59
|
+
function classifySocketError(error, requestId, label) {
|
|
60
|
+
const code = PEER_RESET.exec(error.message)?.[1];
|
|
61
|
+
if (code !== undefined) {
|
|
62
|
+
return { reason: 'reset', detail: `${code} [request-id ${requestId}]` };
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
error: new errors_1.ObserveStreamError(`${label} [request-id ${requestId}]: ${error.message}`, { cause: error }),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
42
68
|
/**
|
|
43
69
|
* Headers the Nest gateway requires on an Observe request.
|
|
44
70
|
*
|
|
@@ -95,9 +121,9 @@ function runObserveSession(options) {
|
|
|
95
121
|
const client = connect(options.endpoints.grpcOrigin, { maxOutstandingPings: 2 });
|
|
96
122
|
// Registered before anything can throw: an unhandled `error` on an
|
|
97
123
|
// Http2Session is a hard process crash.
|
|
98
|
-
client.on('error', (error) =>
|
|
99
|
-
error
|
|
100
|
-
})
|
|
124
|
+
client.on('error', (error) => {
|
|
125
|
+
settle(classifySocketError(error, requestId, 'Observe connection failed'));
|
|
126
|
+
});
|
|
101
127
|
let request;
|
|
102
128
|
try {
|
|
103
129
|
request = client.request(observeHeaders(options.session, options.endpoints, requestId));
|
|
@@ -160,6 +186,7 @@ function runObserveSession(options) {
|
|
|
160
186
|
reason: outcome.reason,
|
|
161
187
|
frameCount,
|
|
162
188
|
durationMs: Date.now() - startedAt,
|
|
189
|
+
...(outcome.detail !== undefined ? { detail: outcome.detail } : {}),
|
|
163
190
|
});
|
|
164
191
|
};
|
|
165
192
|
const onAbort = () => settle({ reason: 'aborted' });
|
|
@@ -272,9 +299,9 @@ function runObserveSession(options) {
|
|
|
272
299
|
}
|
|
273
300
|
});
|
|
274
301
|
request.on('end', () => settle({ reason: 'ended' }));
|
|
275
|
-
request.on('error', (error) =>
|
|
276
|
-
error
|
|
277
|
-
})
|
|
302
|
+
request.on('error', (error) => {
|
|
303
|
+
settle(classifySocketError(error, requestId, 'Observe stream failed'));
|
|
304
|
+
});
|
|
278
305
|
client.on('close', () => settle({ reason: 'ended' }));
|
|
279
306
|
resetIdleTimer();
|
|
280
307
|
request.end(traitsRequest);
|
package/dist/api/transport.js
CHANGED
|
@@ -540,7 +540,8 @@ class NestTransport {
|
|
|
540
540
|
else {
|
|
541
541
|
consecutiveFailures++;
|
|
542
542
|
}
|
|
543
|
-
|
|
543
|
+
const detail = result.detail === undefined ? '' : ` (${result.detail})`;
|
|
544
|
+
this.#options.log.debug(`Observe stream ended (${result.reason}) after ${result.frameCount} frame(s) in ${Math.round(result.durationMs / 1000)}s${detail}`);
|
|
544
545
|
}
|
|
545
546
|
catch (error) {
|
|
546
547
|
this.#observeSessionOpen = false;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-mynest",
|
|
3
3
|
"displayName": "Homebridge My Nest",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.3",
|
|
5
5
|
"description": "Homebridge plugin for Nest thermostats (with Eco Mode), Nest Protect, and Nest Temperature Sensors using a Nest Account access token",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|