homebridge-stream-triggers 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -5
- package/config.schema.json +14 -1
- package/lib/channels.d.ts +9 -0
- package/lib/channels.d.ts.map +1 -0
- package/lib/channels.js +26 -0
- package/lib/channels.js.map +1 -0
- package/lib/config.d.ts +2 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +4 -0
- package/lib/config.js.map +1 -1
- package/lib/platform.d.ts +14 -1
- package/lib/platform.d.ts.map +1 -1
- package/lib/platform.js +73 -10
- package/lib/platform.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,15 +30,30 @@ fire-and-forget in the background. Repeat flips while a launch is in flight are
|
|
|
30
30
|
|
|
31
31
|
## Configuration
|
|
32
32
|
|
|
33
|
+
Zero-config by default: the channel list is fetched from
|
|
34
|
+
[omni-notify](https://github.com/micthiesen/omni-notify)'s `/api/trigger-channels`
|
|
35
|
+
endpoint (one channel per monitored streamer, YouTube preferred over Twitch, Kick-only
|
|
36
|
+
streamers skipped), so adding a streamer there is all it takes.
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"platform": "StreamTriggers"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The list re-syncs hourly (`channelsRefreshInterval`), so new streamers appear without a
|
|
45
|
+
restart. If omni-notify is unreachable at startup, previously-known switches keep working
|
|
46
|
+
from the accessory cache (the channel is stored in each accessory's context) and fetching
|
|
47
|
+
retries every minute until it succeeds.
|
|
48
|
+
|
|
49
|
+
A static list can be set instead (mainly for testing; it disables fetching entirely):
|
|
50
|
+
|
|
33
51
|
```json
|
|
34
52
|
{
|
|
35
53
|
"platform": "StreamTriggers",
|
|
36
54
|
"channels": [
|
|
37
|
-
{ "key": "destiny",
|
|
38
|
-
{ "key": "
|
|
39
|
-
{ "key": "wilburgur", "type": "youtube", "url": "https://www.youtube.com/@Wilburgur/live" },
|
|
40
|
-
{ "key": "vinesauce", "type": "twitch" },
|
|
41
|
-
{ "key": "jerma", "type": "twitch" }
|
|
55
|
+
{ "key": "destiny", "type": "youtube", "url": "https://www.youtube.com/@destiny/live" },
|
|
56
|
+
{ "key": "jerma", "type": "twitch" }
|
|
42
57
|
]
|
|
43
58
|
}
|
|
44
59
|
```
|
|
@@ -56,6 +71,8 @@ fire-and-forget in the background. Repeat flips while a launch is in flight are
|
|
|
56
71
|
|
|
57
72
|
| Field | Default | Description |
|
|
58
73
|
| --- | --- | --- |
|
|
74
|
+
| `channelsUrl` | `http://omni.boris/api/trigger-channels` | Endpoint serving the channel list; used when `channels` is empty. |
|
|
75
|
+
| `channelsRefreshInterval` | `3600000` (1h) | How often (ms) to re-fetch the list and re-sync switches. `0` disables background refresh. |
|
|
59
76
|
| `credentialsDir` | `/var/lib/homebridge/appletv-enhanced` | Where homebridge-appletv-enhanced stores Apple TV pairings. |
|
|
60
77
|
| `appleTvId` | auto | Apple TV identifier. Auto-discovered as the single subdirectory of `credentialsDir` containing a `credentials.txt`; set explicitly if there are multiple. |
|
|
61
78
|
| `atvremotePath` | `<credentialsDir>/.venv/bin/atvremote` path | `atvremote` binary from appletv-enhanced's venv (that plugin keeps pyatv updated). |
|
package/config.schema.json
CHANGED
|
@@ -10,8 +10,21 @@
|
|
|
10
10
|
"type": "string",
|
|
11
11
|
"default": "Stream Triggers"
|
|
12
12
|
},
|
|
13
|
+
"channelsUrl": {
|
|
14
|
+
"title": "Channels URL",
|
|
15
|
+
"description": "Endpoint serving the channel list (omni-notify's /api/trigger-channels). Used when the static channel list below is empty.",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"default": "http://omni.boris/api/trigger-channels"
|
|
18
|
+
},
|
|
19
|
+
"channelsRefreshInterval": {
|
|
20
|
+
"title": "Channel Refresh Interval (ms)",
|
|
21
|
+
"description": "How often to re-fetch the channel list and re-sync switches. 0 disables background refresh.",
|
|
22
|
+
"type": "number",
|
|
23
|
+
"default": 3600000
|
|
24
|
+
},
|
|
13
25
|
"channels": {
|
|
14
|
-
"title": "Channels",
|
|
26
|
+
"title": "Channels (static override)",
|
|
27
|
+
"description": "Optional static channel list. When non-empty, the Channels URL is never fetched.",
|
|
15
28
|
"type": "array",
|
|
16
29
|
"items": {
|
|
17
30
|
"type": "object",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Logging } from "homebridge";
|
|
2
|
+
import { type ChannelConfig } from "./config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Fetch the channel list from omni-notify's /api/trigger-channels endpoint.
|
|
5
|
+
* Returns undefined on any failure (logged); callers fall back to the
|
|
6
|
+
* accessory cache so previously-known switches keep working.
|
|
7
|
+
*/
|
|
8
|
+
export declare function fetchChannels(url: string, log: Logging): Promise<ChannelConfig[] | undefined>;
|
|
9
|
+
//# sourceMappingURL=channels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,aAAa,CAAC;AAKhE;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,CAatC"}
|
package/lib/channels.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { tryCatch } from "@micthiesen/mitools/async";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { channelSchema } from "./config.js";
|
|
4
|
+
const responseSchema = z.object({ channels: z.array(channelSchema) });
|
|
5
|
+
const FETCH_TIMEOUT_MS = 10_000;
|
|
6
|
+
/**
|
|
7
|
+
* Fetch the channel list from omni-notify's /api/trigger-channels endpoint.
|
|
8
|
+
* Returns undefined on any failure (logged); callers fall back to the
|
|
9
|
+
* accessory cache so previously-known switches keep working.
|
|
10
|
+
*/
|
|
11
|
+
export async function fetchChannels(url, log) {
|
|
12
|
+
const result = await tryCatch(async () => {
|
|
13
|
+
const response = await fetch(url, {
|
|
14
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok)
|
|
17
|
+
throw new Error(`HTTP ${response.status}`);
|
|
18
|
+
return responseSchema.parse(await response.json());
|
|
19
|
+
});
|
|
20
|
+
if (!result.ok) {
|
|
21
|
+
log.error(`Failed to fetch channels from ${url}: ${result.error.message}`);
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return result.value.channels;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAsB,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AACtE,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,GAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,IAAI,EAAE;QACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC;SAC9C,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,cAAc,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,iCAAiC,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3E,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;AAC/B,CAAC"}
|
package/lib/config.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export declare const configSchema: z.ZodObject<{
|
|
|
19
19
|
}>;
|
|
20
20
|
url: z.ZodOptional<z.ZodString>;
|
|
21
21
|
}, z.core.$strip>>>;
|
|
22
|
+
channelsUrl: z.ZodDefault<z.ZodString>;
|
|
23
|
+
channelsRefreshInterval: z.ZodDefault<z.ZodNumber>;
|
|
22
24
|
credentialsDir: z.ZodDefault<z.ZodString>;
|
|
23
25
|
appleTvId: z.ZodOptional<z.ZodString>;
|
|
24
26
|
atvremotePath: z.ZodDefault<z.ZodString>;
|
package/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;;;;;iBAKxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;;;;;iBAKxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;iBAcvB,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAEhE,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAE9D;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAG7D"}
|
package/lib/config.js
CHANGED
|
@@ -6,7 +6,11 @@ export const channelSchema = z.object({
|
|
|
6
6
|
url: z.string().min(1).optional(),
|
|
7
7
|
});
|
|
8
8
|
export const configSchema = z.object({
|
|
9
|
+
/** Static override; when empty the list is fetched from channelsUrl. */
|
|
9
10
|
channels: z.array(channelSchema).default([]),
|
|
11
|
+
channelsUrl: z.string().default("http://omni.boris/api/trigger-channels"),
|
|
12
|
+
/** How often to re-fetch the channel list and re-sync switches. 0 disables. */
|
|
13
|
+
channelsRefreshInterval: z.number().int().nonnegative().default(3_600_000),
|
|
10
14
|
credentialsDir: z.string().default("/var/lib/homebridge/appletv-enhanced"),
|
|
11
15
|
appleTvId: z.string().optional(),
|
|
12
16
|
atvremotePath: z
|
package/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC;IAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,OAAO,CAAC,0DAA0D,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;IACtC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CACtD,CAAC,CAAC;AAIH,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,OAAO,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,OAAsB;IACnD,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,OAAO,CAAC,WAAW,CAAC;IACpD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,wEAAwE;IACxE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC;IACzE,+EAA+E;IAC/E,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;IAC1E,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC;IAC1E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,OAAO,CAAC,0DAA0D,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;IACtC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CACtD,CAAC,CAAC;AAIH,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,OAAO,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,OAAsB;IACnD,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,OAAO,CAAC,WAAW,CAAC;IACpD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
package/lib/platform.d.ts
CHANGED
|
@@ -10,10 +10,23 @@ export declare class StreamTriggersPlatform implements DynamicPlatformPlugin {
|
|
|
10
10
|
private readonly ytDlp;
|
|
11
11
|
private readonly launcher;
|
|
12
12
|
constructor(log: Logging, rawConfig: PlatformConfig, api: API);
|
|
13
|
+
private startup;
|
|
14
|
+
/**
|
|
15
|
+
* Background re-sync so channel changes in omni-notify appear without a
|
|
16
|
+
* Homebridge restart. Failures retry sooner (covers omni-notify still
|
|
17
|
+
* booting after a host reboot) but never touch the current accessories.
|
|
18
|
+
*/
|
|
19
|
+
private scheduleRefresh;
|
|
13
20
|
/** Called by Homebridge for each accessory restored from cache at startup. */
|
|
14
21
|
configureAccessory(accessory: PlatformAccessory): void;
|
|
15
|
-
/** Register switches for
|
|
22
|
+
/** Register switches for the given channels; unregister ones no longer present. */
|
|
16
23
|
private syncAccessories;
|
|
24
|
+
/**
|
|
25
|
+
* Fallback when the channel list is unreachable at startup: wire switches
|
|
26
|
+
* from the channel stored in each cached accessory's context, so everything
|
|
27
|
+
* previously known keeps working. Nothing is registered or unregistered.
|
|
28
|
+
*/
|
|
29
|
+
private wireCachedAccessories;
|
|
17
30
|
private setUpSwitch;
|
|
18
31
|
/** Fire-and-forget launch; never throws, never awaited by the set handler. */
|
|
19
32
|
private handleTrigger;
|
package/lib/platform.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,OAAO,EACP,iBAAiB,EACjB,cAAc,EACd,OAAO,EACR,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,OAAO,EACP,iBAAiB,EACjB,cAAc,EACd,OAAO,EACR,MAAM,YAAY,CAAC;AAgBpB,qBAAa,sBAAuB,YAAW,qBAAqB;aAWhD,GAAG,EAAE,OAAO;aAEZ,GAAG,EAAE,GAAG;IAZ1B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAC;IACxC,SAAgB,cAAc,EAAE,OAAO,cAAc,CAAC;IAEtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwC;IACpE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;gBAGxB,GAAG,EAAE,OAAO,EAC5B,SAAS,EAAE,cAAc,EACT,GAAG,EAAE,GAAG;YAuBZ,OAAO;IAuBrB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAkBvB,8EAA8E;IAC9E,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAKtD,mFAAmF;IACnF,OAAO,CAAC,eAAe;IAsCvB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,WAAW;IA2BnB,8EAA8E;IAC9E,OAAO,CAAC,aAAa;CAiBtB"}
|
package/lib/platform.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { AppleTv } from "./atv.js";
|
|
2
|
-
import {
|
|
2
|
+
import { fetchChannels } from "./channels.js";
|
|
3
|
+
import { channelSchema, configSchema, displayNameFor, } from "./config.js";
|
|
3
4
|
import { StreamLauncher } from "./launcher.js";
|
|
4
5
|
import { PLATFORM_NAME, PLUGIN_NAME } from "./settings.js";
|
|
5
6
|
import { YtDlp } from "./ytdlp.js";
|
|
7
|
+
const REFRESH_RETRY_MS = 60_000;
|
|
6
8
|
export class StreamTriggersPlatform {
|
|
7
9
|
log;
|
|
8
10
|
api;
|
|
@@ -29,25 +31,65 @@ export class StreamTriggersPlatform {
|
|
|
29
31
|
this.ytDlp = new YtDlp(log, api.user.storagePath(), this.config.ytDlpPath);
|
|
30
32
|
this.launcher = new StreamLauncher(log, new AppleTv(log, this.config), this.ytDlp);
|
|
31
33
|
api.on("didFinishLaunching", () => {
|
|
34
|
+
void this.startup();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async startup() {
|
|
38
|
+
try {
|
|
39
|
+
if (this.config.channels.length > 0) {
|
|
40
|
+
// Static config override (mainly for testing); no fetching involved.
|
|
41
|
+
this.syncAccessories(this.config.channels);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const channels = await fetchChannels(this.config.channelsUrl, this.log);
|
|
45
|
+
if (channels) {
|
|
46
|
+
this.syncAccessories(channels);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.wireCachedAccessories();
|
|
50
|
+
}
|
|
51
|
+
this.scheduleRefresh(channels ? this.config.channelsRefreshInterval : REFRESH_RETRY_MS);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
this.log.error(`Startup failed: ${String(error)}`);
|
|
56
|
+
}
|
|
57
|
+
// Non-blocking: download/refresh the managed yt-dlp binary in the background.
|
|
58
|
+
void this.ytDlp.ensureFresh();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Background re-sync so channel changes in omni-notify appear without a
|
|
62
|
+
* Homebridge restart. Failures retry sooner (covers omni-notify still
|
|
63
|
+
* booting after a host reboot) but never touch the current accessories.
|
|
64
|
+
*/
|
|
65
|
+
scheduleRefresh(delayMs) {
|
|
66
|
+
if (this.config.channelsRefreshInterval <= 0)
|
|
67
|
+
return;
|
|
68
|
+
const timer = setTimeout(async () => {
|
|
69
|
+
let nextDelayMs = REFRESH_RETRY_MS;
|
|
32
70
|
try {
|
|
33
|
-
this.
|
|
71
|
+
const channels = await fetchChannels(this.config.channelsUrl, this.log);
|
|
72
|
+
if (channels) {
|
|
73
|
+
this.syncAccessories(channels);
|
|
74
|
+
nextDelayMs = this.config.channelsRefreshInterval;
|
|
75
|
+
}
|
|
34
76
|
}
|
|
35
77
|
catch (error) {
|
|
36
|
-
this.log.error(`
|
|
78
|
+
this.log.error(`Channel refresh failed: ${String(error)}`);
|
|
37
79
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
80
|
+
this.scheduleRefresh(nextDelayMs);
|
|
81
|
+
}, delayMs);
|
|
82
|
+
timer.unref?.();
|
|
41
83
|
}
|
|
42
84
|
/** Called by Homebridge for each accessory restored from cache at startup. */
|
|
43
85
|
configureAccessory(accessory) {
|
|
44
86
|
this.log.info(`Restoring cached accessory: ${accessory.displayName}`);
|
|
45
87
|
this.accessories.set(accessory.UUID, accessory);
|
|
46
88
|
}
|
|
47
|
-
/** Register switches for
|
|
48
|
-
syncAccessories() {
|
|
89
|
+
/** Register switches for the given channels; unregister ones no longer present. */
|
|
90
|
+
syncAccessories(channels) {
|
|
49
91
|
const configuredUuids = new Set();
|
|
50
|
-
for (const channel of
|
|
92
|
+
for (const channel of channels) {
|
|
51
93
|
if (channel.type === "youtube" && !channel.url) {
|
|
52
94
|
this.log.error(`[${channel.key}] YouTube channel is missing "url"; skipping`);
|
|
53
95
|
continue;
|
|
@@ -58,12 +100,14 @@ export class StreamTriggersPlatform {
|
|
|
58
100
|
const existing = this.accessories.get(uuid);
|
|
59
101
|
if (existing) {
|
|
60
102
|
existing.displayName = name;
|
|
103
|
+
existing.context.channel = channel;
|
|
61
104
|
this.setUpSwitch(existing, channel, name);
|
|
62
105
|
this.api.updatePlatformAccessories([existing]);
|
|
63
|
-
this.log.
|
|
106
|
+
this.log.debug(`[${channel.key}] Updated switch "${name}"`);
|
|
64
107
|
}
|
|
65
108
|
else {
|
|
66
109
|
const accessory = new this.api.platformAccessory(name, uuid);
|
|
110
|
+
accessory.context.channel = channel;
|
|
67
111
|
this.setUpSwitch(accessory, channel, name);
|
|
68
112
|
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
69
113
|
this.accessories.set(uuid, accessory);
|
|
@@ -78,6 +122,25 @@ export class StreamTriggersPlatform {
|
|
|
78
122
|
this.log.info(`Unregistered switch "${accessory.displayName}" (channel removed)`);
|
|
79
123
|
}
|
|
80
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Fallback when the channel list is unreachable at startup: wire switches
|
|
127
|
+
* from the channel stored in each cached accessory's context, so everything
|
|
128
|
+
* previously known keeps working. Nothing is registered or unregistered.
|
|
129
|
+
*/
|
|
130
|
+
wireCachedAccessories() {
|
|
131
|
+
let wired = 0;
|
|
132
|
+
for (const accessory of this.accessories.values()) {
|
|
133
|
+
const channel = channelSchema.safeParse(accessory.context.channel);
|
|
134
|
+
if (!channel.success) {
|
|
135
|
+
this.log.warn(`Cached accessory "${accessory.displayName}" has no stored channel; ` +
|
|
136
|
+
`it stays inert until the channel list is reachable`);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
this.setUpSwitch(accessory, channel.data, accessory.displayName);
|
|
140
|
+
wired++;
|
|
141
|
+
}
|
|
142
|
+
this.log.warn(`Channel list unavailable; running with ${wired} cached switch(es)`);
|
|
143
|
+
}
|
|
81
144
|
setUpSwitch(accessory, channel, name) {
|
|
82
145
|
const service = accessory.getService(this.Service.Switch) ??
|
|
83
146
|
accessory.addService(this.Service.Switch);
|
package/lib/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAEL,YAAY,EACZ,cAAc,GAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,OAAO,sBAAsB;IAWf;IAEA;IAZF,OAAO,CAAiB;IACxB,cAAc,CAAwB;IAErC,MAAM,CAAuB;IAC7B,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;IACnD,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,CAAQ;IACb,QAAQ,CAAiB;IAE1C,YACkB,GAAY,EAC5B,SAAyB,EACT,GAAQ;QAFR,QAAG,GAAH,GAAG,CAAS;QAEZ,QAAG,GAAH,GAAG,CAAK;QAExB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC;QAE7C,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,CACZ,6CAA6C,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CACpE,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3E,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAEnF,GAAG,CAAC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAChC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-stream-triggers",
|
|
3
3
|
"displayName": "Homebridge Stream Triggers",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"description": "HomeKit switches that launch live streams (YouTube/Twitch) on an Apple TV via atvremote and yt-dlp.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"homebridge-plugin",
|