@ecopoesis/homebridge-dmx 0.5.0 → 0.5.1
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 +1 -1
- package/config.schema.json +8 -0
- package/dist/color/hsvcct.d.ts.map +1 -1
- package/dist/color/hsvcct.js +42 -0
- package/dist/color/hsvcct.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/ethergate.d.ts +5 -0
- package/dist/ethergate.d.ts.map +1 -0
- package/dist/ethergate.js +50 -0
- package/dist/ethergate.js.map +1 -0
- package/dist/platform.d.ts +8 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +60 -1
- package/dist/platform.js.map +1 -1
- package/dist/sacn.d.ts +4 -0
- package/dist/sacn.d.ts.map +1 -1
- package/dist/sacn.js +5 -0
- package/dist/sacn.js.map +1 -1
- package/examples/dmx.yaml +3 -1
- package/package.json +1 -1
- package/src/color/hsvcct.ts +36 -0
- package/src/config.ts +7 -0
- package/src/ethergate.ts +51 -0
- package/src/platform.ts +60 -2
- package/src/sacn.ts +5 -0
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ If you, like me, bought a Stick-DE3 based on the assumption that it was competen
|
|
|
41
41
|
| Multiple controllers in one patch | ✅ (`sACN` and `StickDE3` types) |
|
|
42
42
|
| Universe B on the Stick | 🚧 plumbed but the wire encoding is unknown (works on `sACN`) |
|
|
43
43
|
| Stick-DE3 password / "Cloud Access" auth | 🚧 not implemented |
|
|
44
|
-
| State read-back |
|
|
44
|
+
| State read-back | ✅ on sACN + Ethergate Mk2 (seeds HomeKit from the gateway's live buffers at startup; optional `statePollSeconds`); 🚧 elsewhere |
|
|
45
45
|
|
|
46
46
|
## How it works
|
|
47
47
|
|
package/config.schema.json
CHANGED
|
@@ -67,6 +67,14 @@
|
|
|
67
67
|
"minimum": 0,
|
|
68
68
|
"maximum": 200,
|
|
69
69
|
"description": "E1.31 source priority. Only matters if a second sACN source targets the same universe."
|
|
70
|
+
},
|
|
71
|
+
"statePollSeconds": {
|
|
72
|
+
"title": "State read-back poll (sACN/Ethergate only)",
|
|
73
|
+
"type": "integer",
|
|
74
|
+
"required": false,
|
|
75
|
+
"default": 0,
|
|
76
|
+
"minimum": 0,
|
|
77
|
+
"description": "Re-read the gateway's live DMX buffers every N seconds so HomeKit tracks changes made by other senders. 0 = read once at startup only. Requires an ENTTEC Ethergate Mk2 (uses its web API)."
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hsvcct.d.ts","sourceRoot":"","sources":["../../src/color/hsvcct.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,UAAU,EAOX,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"hsvcct.d.ts","sourceRoot":"","sources":["../../src/color/hsvcct.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,UAAU,EAOX,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,MAAM,EAAE,UAsEpB,CAAC"}
|
package/dist/color/hsvcct.js
CHANGED
|
@@ -48,5 +48,47 @@ export const hsvcct = {
|
|
|
48
48
|
}
|
|
49
49
|
return out;
|
|
50
50
|
},
|
|
51
|
+
/** Inverse of render, for state read-back from a live universe buffer.
|
|
52
|
+
* A dark fixture parses as on:false with brightness 100 so the next
|
|
53
|
+
* HomeKit "on" restores full rather than 0%. */
|
|
54
|
+
parse(bytes, channels) {
|
|
55
|
+
const state = { on: false, brightness: 100 };
|
|
56
|
+
let i = 0;
|
|
57
|
+
while (i < channels.length) {
|
|
58
|
+
const ch = channels[i];
|
|
59
|
+
if (ch.fine) {
|
|
60
|
+
i++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
switch (ch.role) {
|
|
64
|
+
case 'intensity': {
|
|
65
|
+
const hasFine = channels[i + 1]?.fine && channels[i + 1].role === 'intensity';
|
|
66
|
+
const v16 = hasFine ? (bytes[i] << 8) | bytes[i + 1] : bytes[i] * 257;
|
|
67
|
+
if (v16 > 0) {
|
|
68
|
+
state.on = true;
|
|
69
|
+
state.brightness = Math.max(1, Math.round((v16 / 65535) * 100));
|
|
70
|
+
}
|
|
71
|
+
if (hasFine) {
|
|
72
|
+
i += 2;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case 'cct': {
|
|
78
|
+
const k = ch.kMin + (bytes[i] / 255) * (ch.kMax - ch.kMin);
|
|
79
|
+
state.colorTemperatureMireds = Math.round(clamp(1_000_000 / k, 50, 400));
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case 'saturation':
|
|
83
|
+
state.saturation = Math.round(clamp(bytes[i] / 2.55, 0, 100));
|
|
84
|
+
break;
|
|
85
|
+
case 'hue':
|
|
86
|
+
state.hue = Math.round((bytes[i] / 255) * 360) % 360;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
i++;
|
|
90
|
+
}
|
|
91
|
+
return state;
|
|
92
|
+
},
|
|
51
93
|
};
|
|
52
94
|
//# sourceMappingURL=hsvcct.js.map
|
package/dist/color/hsvcct.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hsvcct.js","sourceRoot":"","sources":["../../src/color/hsvcct.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,4EAA4E;AAC5E,oEAAoE;AACpE,uEAAuE;AACvE,EAAE;AACF,2DAA2D;AAC3D,0DAA0D;AAC1D,gCAAgC;AAChC,8CAA8C;AAC9C,yCAAyC;AACzC,+DAA+D;AAE/D,OAAO,EAIL,YAAY,EACZ,KAAK,EACL,MAAM,EACN,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,MAAM,GAAe;IAChC,EAAE,EAAE,QAAQ;IACZ,eAAe,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,kBAAkB,CAAC;IAC9E,QAAQ,CAAC,QAAQ;QACf,YAAY,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,MAAM,CAAC,KAAwB,EAAE,QAAsB;QACrD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;gBAAC,CAAC,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;gBAChB,KAAK,WAAW;oBACd,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;oBACxD,SAAS;gBACX,KAAK,KAAK;oBACR,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,CAAC,IAAK,EAAE,EAAE,CAAC,IAAK,CAAC,CAAC;oBAClE,MAAM;gBACR,KAAK,YAAY;oBACf,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;oBACjE,MAAM;gBACR,KAAK,KAAK;oBACR,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;oBAC5D,MAAM;YACV,CAAC;YACD,CAAC,EAAE,CAAC;QACN,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"hsvcct.js","sourceRoot":"","sources":["../../src/color/hsvcct.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export interface ControllerSpec {
|
|
|
5
5
|
ip: string;
|
|
6
6
|
refreshMinutes?: number;
|
|
7
7
|
priority?: number;
|
|
8
|
+
statePollSeconds?: number;
|
|
8
9
|
}
|
|
9
10
|
export interface ProfileSpec {
|
|
10
11
|
name: string;
|
|
@@ -45,6 +46,7 @@ export interface Controller {
|
|
|
45
46
|
ip: string;
|
|
46
47
|
refreshMinutes: number;
|
|
47
48
|
priority: number;
|
|
49
|
+
statePollSeconds: number;
|
|
48
50
|
}
|
|
49
51
|
export interface Fixture {
|
|
50
52
|
id: string;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAK5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAuCA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAK5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,+BAAgC,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;wEAEwE;AACxE,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,eAAe,EAAE,gBAAgB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C;;;;oEAIoE;AACpE,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,CAkMzE"}
|
package/dist/config.js
CHANGED
|
@@ -84,8 +84,13 @@ export function loadConfig(rawJson, cwd) {
|
|
|
84
84
|
if (!Number.isInteger(priority) || priority < 0 || priority > 200) {
|
|
85
85
|
throw new Error(`controller "${cs.id}": priority must be an integer 0..200`);
|
|
86
86
|
}
|
|
87
|
+
const statePollSeconds = cs.statePollSeconds ?? 0;
|
|
88
|
+
if (typeof statePollSeconds !== 'number' || statePollSeconds < 0) {
|
|
89
|
+
throw new Error(`controller "${cs.id}": statePollSeconds must be a number >= 0`);
|
|
90
|
+
}
|
|
87
91
|
controllersById.set(cs.id, {
|
|
88
92
|
id: cs.id, type: cs.type, ip: cs.ip, refreshMinutes, priority,
|
|
93
|
+
statePollSeconds,
|
|
89
94
|
});
|
|
90
95
|
}
|
|
91
96
|
// Profiles
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,EAAE;AACF,UAAU;AACV,mEAAmE;AACnE,uEAAuE;AACvE,oDAAoD;AACpD,mDAAmD;AACnD,EAAE;AACF,SAAS;AACT,MAAM;AACN,yBAAyB;AACzB,qBAAqB;AACrB,gDAAgD;AAChD,uBAAuB;AACvB,mEAAmE;AACnE,SAAS;AACT,oBAAoB;AACpB,iDAAiD;AACjD,6DAA6D;AAC7D,0EAA0E;AAC1E,SAAS;AACT,iBAAiB;AACjB,2DAA2D;AAC3D,8DAA8D;AAC9D,QAAQ;AACR,MAAM;AACN,EAAE;AACF,wEAAwE;AACxE,0DAA0D;AAC1D,2EAA2E;AAC3E,6BAA6B;AAC7B,wEAAwE;AACxE,0EAA0E;AAC1E,qCAAqC;AAErC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAG3B,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Fetch the live 512-slot output buffer for an internal universe index
|
|
2
|
+
* (0=A, 1=B). Returns null on any failure — callers treat read-back as
|
|
3
|
+
* best-effort. */
|
|
4
|
+
export declare function readEthergateUniverse(ip: string, universe: number): Promise<Uint8Array | null>;
|
|
5
|
+
//# sourceMappingURL=ethergate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ethergate.d.ts","sourceRoot":"","sources":["../src/ethergate.ts"],"names":[],"mappings":"AAkBA;;mBAEmB;AACnB,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA6B9F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Ethergate Mk2 state read-back.
|
|
2
|
+
//
|
|
3
|
+
// The ENTTEC DIN Ethergate Mk2 exposes its live per-port DMX output
|
|
4
|
+
// buffers over a bare CGI-ish HTTP API. Responses have NO status line or
|
|
5
|
+
// headers (raw body only), which Node's http/fetch clients reject — so we
|
|
6
|
+
// speak over a raw TCP socket.
|
|
7
|
+
//
|
|
8
|
+
// Buffer indexing is per universe-SLOT, not per port (8 Overdrive slots
|
|
9
|
+
// per port on fw V1.3): port N slot k = buffer((N-1)*8 + k).cgi. We assume
|
|
10
|
+
// the plugin's own convention of port N carrying sACN universe N, so
|
|
11
|
+
// internal universe u (0=A, 1=B) reads buffer(u*8 + 1).
|
|
12
|
+
//
|
|
13
|
+
// Body format: 64 lines "rowR=v,v,v,v,v,v,v,v" covering slots 1..512.
|
|
14
|
+
import net from 'node:net';
|
|
15
|
+
const READ_TIMEOUT_MS = 4000;
|
|
16
|
+
/** Fetch the live 512-slot output buffer for an internal universe index
|
|
17
|
+
* (0=A, 1=B). Returns null on any failure — callers treat read-back as
|
|
18
|
+
* best-effort. */
|
|
19
|
+
export function readEthergateUniverse(ip, universe) {
|
|
20
|
+
const bufferIdx = universe * 8 + 1;
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const chunks = [];
|
|
23
|
+
const sock = net.connect(80, ip);
|
|
24
|
+
const fail = () => { sock.destroy(); resolve(null); };
|
|
25
|
+
sock.setTimeout(READ_TIMEOUT_MS, fail);
|
|
26
|
+
sock.on('error', fail);
|
|
27
|
+
sock.on('connect', () => {
|
|
28
|
+
sock.write(`GET /index.html?buffer${bufferIdx}.cgi HTTP/1.0\r\nHost: ${ip}\r\n\r\n`);
|
|
29
|
+
});
|
|
30
|
+
sock.on('data', (d) => chunks.push(d));
|
|
31
|
+
sock.on('close', () => {
|
|
32
|
+
const body = Buffer.concat(chunks).toString('latin1');
|
|
33
|
+
const slots = new Uint8Array(512);
|
|
34
|
+
let seen = 0;
|
|
35
|
+
for (const line of body.split('\n')) {
|
|
36
|
+
const m = /^row(\d+)=([\d,]+)/.exec(line.trim());
|
|
37
|
+
if (!m)
|
|
38
|
+
continue;
|
|
39
|
+
const base = (Number(m[1]) - 1) * 8;
|
|
40
|
+
const vals = m[2].split(',').map(Number);
|
|
41
|
+
for (let i = 0; i < vals.length && base + i < 512; i++) {
|
|
42
|
+
slots[base + i] = vals[i] & 0xff;
|
|
43
|
+
seen++;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
resolve(seen === 512 ? slots : null);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=ethergate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ethergate.js","sourceRoot":"","sources":["../src/ethergate.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,EAAE;AACF,oEAAoE;AACpE,yEAAyE;AACzE,0EAA0E;AAC1E,+BAA+B;AAC/B,EAAE;AACF,wEAAwE;AACxE,2EAA2E;AAC3E,qEAAqE;AACrE,wDAAwD;AACxD,EAAE;AACF,sEAAsE;AAEtE,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B;;mBAEmB;AACnB,MAAM,UAAU,qBAAqB,CAAC,EAAU,EAAE,QAAgB;IAChE,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,GAAS,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACtB,IAAI,CAAC,KAAK,CAAC,yBAAyB,SAAS,0BAA0B,EAAE,UAAU,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACpB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpC,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,CAAC;oBAAE,SAAS;gBACjB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBACpC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBACvD,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;oBACjC,IAAI,EAAE,CAAC;gBACT,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -9,7 +9,15 @@ export declare class DmxPlatform implements DynamicPlatformPlugin {
|
|
|
9
9
|
private cfg;
|
|
10
10
|
private controllers;
|
|
11
11
|
private registry;
|
|
12
|
+
private statePollTimers;
|
|
12
13
|
constructor(log: Logger, config: PlatformConfig, api: API);
|
|
14
|
+
/** State read-back (sACN/Ethergate only): the gateway's live output
|
|
15
|
+
* buffers are ground truth for what's on the wire, so seed the registry
|
|
16
|
+
* from them at startup — a Homebridge restart inherits reality instead
|
|
17
|
+
* of assuming darkness — and optionally re-poll every statePollSeconds
|
|
18
|
+
* to track changes made by other senders. */
|
|
19
|
+
private startStateSync;
|
|
20
|
+
private applyReadBack;
|
|
13
21
|
private makeController;
|
|
14
22
|
/** Called by Homebridge for each cached accessory at startup. */
|
|
15
23
|
configureAccessory(accessory: PlatformAccessory): void;
|
package/dist/platform.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,OAAO,EACR,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,GAAG,EACH,cAAc,EACd,qBAAqB,EACrB,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,OAAO,EACR,MAAM,YAAY,CAAC;AAYpB,qBAAa,WAAY,YAAW,qBAAqB;aAWrC,GAAG,EAAE,MAAM;aACX,MAAM,EAAE,cAAc;aACtB,GAAG,EAAE,GAAG;IAZ1B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAC;IACxC,SAAgB,cAAc,EAAE,OAAO,cAAc,CAAC;IACtD,SAAgB,WAAW,EAAE,iBAAiB,EAAE,CAAM;IAEtD,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,eAAe,CAAwB;gBAG7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG;IAoC1B;;;;kDAI8C;IAC9C,OAAO,CAAC,cAAc;IAsCtB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,cAAc;IAWtB,iEAAiE;IACjE,kBAAkB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAKtD,OAAO,CAAC,eAAe;CA0DxB"}
|
package/dist/platform.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// its controller.
|
|
6
6
|
import { loadConfig } from './config.js';
|
|
7
7
|
import { StickController } from './controller.js';
|
|
8
|
+
import { readEthergateUniverse } from './ethergate.js';
|
|
8
9
|
import { SacnController } from './sacn.js';
|
|
9
10
|
import { StickFixture } from './platformAccessory.js';
|
|
10
11
|
import { StateRegistry } from './stateRegistry.js';
|
|
@@ -20,6 +21,7 @@ export class DmxPlatform {
|
|
|
20
21
|
cfg = null;
|
|
21
22
|
controllers = new Map();
|
|
22
23
|
registry = new StateRegistry();
|
|
24
|
+
statePollTimers = [];
|
|
23
25
|
constructor(log, config, api) {
|
|
24
26
|
this.log = log;
|
|
25
27
|
this.config = config;
|
|
@@ -40,12 +42,69 @@ export class DmxPlatform {
|
|
|
40
42
|
`${this.cfg.controllers.length === 1 ? '' : 's'}, ` +
|
|
41
43
|
`${this.cfg.fixtures.length} fixture${this.cfg.fixtures.length === 1 ? '' : 's'}, ` +
|
|
42
44
|
`${this.cfg.zones.length} zone${this.cfg.zones.length === 1 ? '' : 's'}`);
|
|
43
|
-
this.api.on('didFinishLaunching', () =>
|
|
45
|
+
this.api.on('didFinishLaunching', () => {
|
|
46
|
+
this.discoverDevices();
|
|
47
|
+
this.startStateSync();
|
|
48
|
+
});
|
|
44
49
|
this.api.on('shutdown', () => {
|
|
50
|
+
for (const t of this.statePollTimers)
|
|
51
|
+
clearInterval(t);
|
|
45
52
|
for (const c of this.controllers.values())
|
|
46
53
|
c.shutdown();
|
|
47
54
|
});
|
|
48
55
|
}
|
|
56
|
+
/** State read-back (sACN/Ethergate only): the gateway's live output
|
|
57
|
+
* buffers are ground truth for what's on the wire, so seed the registry
|
|
58
|
+
* from them at startup — a Homebridge restart inherits reality instead
|
|
59
|
+
* of assuming darkness — and optionally re-poll every statePollSeconds
|
|
60
|
+
* to track changes made by other senders. */
|
|
61
|
+
startStateSync() {
|
|
62
|
+
if (!this.cfg)
|
|
63
|
+
return;
|
|
64
|
+
for (const spec of this.cfg.controllers) {
|
|
65
|
+
if (spec.type !== 'sACN')
|
|
66
|
+
continue;
|
|
67
|
+
const ctrl = this.controllers.get(spec.id);
|
|
68
|
+
if (!(ctrl instanceof SacnController))
|
|
69
|
+
continue;
|
|
70
|
+
const fixtures = this.cfg.fixtures.filter((f) => f.controller.id === spec.id && f.profile.model.parse);
|
|
71
|
+
if (fixtures.length === 0)
|
|
72
|
+
continue;
|
|
73
|
+
const sync = async () => {
|
|
74
|
+
// Never clobber an in-flight HomeKit change with a read that may
|
|
75
|
+
// pre-date it.
|
|
76
|
+
if (Date.now() - ctrl.lastChangeAt < 5_000)
|
|
77
|
+
return;
|
|
78
|
+
const universes = [...new Set(fixtures.map((f) => f.universe))];
|
|
79
|
+
for (const u of universes) {
|
|
80
|
+
const slots = await readEthergateUniverse(spec.ip, u);
|
|
81
|
+
if (!slots) {
|
|
82
|
+
this.log.debug(`state sync: universe ${u + 1} read failed (non-Ethergate gateway?)`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
for (const fx of fixtures) {
|
|
86
|
+
if (fx.universe !== u)
|
|
87
|
+
continue;
|
|
88
|
+
this.applyReadBack(fx, slots);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
sync().then(() => this.log.info(`state sync: seeded ${fixtures.length} fixtures from ${spec.ip}`));
|
|
93
|
+
if (spec.statePollSeconds > 0) {
|
|
94
|
+
const t = setInterval(() => void sync(), spec.statePollSeconds * 1000);
|
|
95
|
+
t.unref?.();
|
|
96
|
+
this.statePollTimers.push(t);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
applyReadBack(fx, slots) {
|
|
101
|
+
const bytes = slots.slice(fx.startCh - 1, fx.startCh - 1 + fx.nChannels);
|
|
102
|
+
const state = fx.profile.model.parse(bytes, fx.profile.channels);
|
|
103
|
+
const cur = this.registry.get(fx.id);
|
|
104
|
+
if (JSON.stringify(cur) !== JSON.stringify(state)) {
|
|
105
|
+
this.registry.set(fx.id, state);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
49
108
|
makeController(c) {
|
|
50
109
|
switch (c.type) {
|
|
51
110
|
case 'StickDE3':
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,kBAAkB;AAYlB,OAAO,
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/dist/sacn.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export declare class SacnController implements DmxController {
|
|
|
11
11
|
private dirty;
|
|
12
12
|
private coalesceTimer;
|
|
13
13
|
private keepaliveTimer;
|
|
14
|
+
/** When setFixture last staged a change (keepalive re-sends excluded).
|
|
15
|
+
* Read by the platform's state-poll guard so a read-back never clobbers
|
|
16
|
+
* an in-flight HomeKit change. */
|
|
17
|
+
lastChangeAt: number;
|
|
14
18
|
private readonly socket;
|
|
15
19
|
private readonly cid;
|
|
16
20
|
private closed;
|
package/dist/sacn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sacn.d.ts","sourceRoot":"","sources":["../src/sacn.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAIzC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAYnD,qBAAa,cAAe,YAAW,aAAa;
|
|
1
|
+
{"version":3,"file":"sacn.d.ts","sourceRoot":"","sources":["../src/sacn.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAIzC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAYnD,qBAAa,cAAe,YAAW,aAAa;IAehD,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAhB3B,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAA+B;IACrD;;uCAEmC;IAC5B,YAAY,SAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmB;IACvC,OAAO,CAAC,MAAM,CAAS;gBAGJ,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAA8B;IAM3D,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAiB5D,OAAO,CAAC,WAAW;IAMnB;+BAC2B;IAC3B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,YAAY;IAYpB,sEAAsE;IACtE,OAAO,CAAC,WAAW;IA8BnB,QAAQ,IAAI,IAAI;CAYjB"}
|
package/dist/sacn.js
CHANGED
|
@@ -30,6 +30,10 @@ export class SacnController {
|
|
|
30
30
|
dirty = new Set();
|
|
31
31
|
coalesceTimer = null;
|
|
32
32
|
keepaliveTimer = null;
|
|
33
|
+
/** When setFixture last staged a change (keepalive re-sends excluded).
|
|
34
|
+
* Read by the platform's state-poll guard so a read-back never clobbers
|
|
35
|
+
* an in-flight HomeKit change. */
|
|
36
|
+
lastChangeAt = 0;
|
|
33
37
|
socket;
|
|
34
38
|
cid = randomBytes(16);
|
|
35
39
|
closed = false;
|
|
@@ -47,6 +51,7 @@ export class SacnController {
|
|
|
47
51
|
arr[fixture.startCh - 1 + i] = bytes[i];
|
|
48
52
|
}
|
|
49
53
|
this.dirty.add(fixture.universe);
|
|
54
|
+
this.lastChangeAt = Date.now();
|
|
50
55
|
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
51
56
|
this.log.info(`setFixture ${fixture.id}@DMX${fixture.startCh}/U${fixture.universe + 1}=${hex}`);
|
|
52
57
|
this.scheduleSend();
|
package/dist/sacn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sacn.js","sourceRoot":"","sources":["../src/sacn.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,gEAAgE;AAChE,mEAAmE;AACnE,mEAAmE;AACnE,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,iDAAiD;AACjD,mEAAmE;AACnE,0EAA0E;AAC1E,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,oEAAoE;AAGpE,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,UAAU,GAAG,GAAG,CAAC,CAAkB,kCAAkC;AAC3E,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC,MAAM,OAAO,cAAc;
|
|
1
|
+
{"version":3,"file":"sacn.js","sourceRoot":"","sources":["../src/sacn.ts"],"names":[],"mappings":"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"}
|
package/examples/dmx.yaml
CHANGED
|
@@ -15,7 +15,9 @@ controllers:
|
|
|
15
15
|
# are unicast to `ip`; patch universes A/B map to sACN
|
|
16
16
|
# universes 1/2, so set the gateway's ports to match.
|
|
17
17
|
# Optional `priority` (0-200, default 100) is the E1.31
|
|
18
|
-
# source priority.
|
|
18
|
+
# source priority. On an ENTTEC Ethergate Mk2, HomeKit state
|
|
19
|
+
# is seeded from the gateway's live buffers at startup;
|
|
20
|
+
# optional `statePollSeconds` re-reads every N seconds.
|
|
19
21
|
# StickDE3 — Nicolaudie Stick-DE3 (legacy; subprocess transactions).
|
|
20
22
|
# Optional `refreshMinutes` idle keepalive (default 30).
|
|
21
23
|
- id: main
|
package/package.json
CHANGED
package/src/color/hsvcct.ts
CHANGED
|
@@ -56,4 +56,40 @@ export const hsvcct: ColorModel = {
|
|
|
56
56
|
}
|
|
57
57
|
return out;
|
|
58
58
|
},
|
|
59
|
+
/** Inverse of render, for state read-back from a live universe buffer.
|
|
60
|
+
* A dark fixture parses as on:false with brightness 100 so the next
|
|
61
|
+
* HomeKit "on" restores full rather than 0%. */
|
|
62
|
+
parse(bytes: Uint8Array, channels: ChannelDef[]): HomeKitLightState {
|
|
63
|
+
const state: HomeKitLightState = { on: false, brightness: 100 };
|
|
64
|
+
let i = 0;
|
|
65
|
+
while (i < channels.length) {
|
|
66
|
+
const ch = channels[i];
|
|
67
|
+
if (ch.fine) { i++; continue; }
|
|
68
|
+
switch (ch.role) {
|
|
69
|
+
case 'intensity': {
|
|
70
|
+
const hasFine = channels[i + 1]?.fine && channels[i + 1].role === 'intensity';
|
|
71
|
+
const v16 = hasFine ? (bytes[i] << 8) | bytes[i + 1] : bytes[i] * 257;
|
|
72
|
+
if (v16 > 0) {
|
|
73
|
+
state.on = true;
|
|
74
|
+
state.brightness = Math.max(1, Math.round((v16 / 65535) * 100));
|
|
75
|
+
}
|
|
76
|
+
if (hasFine) { i += 2; continue; }
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'cct': {
|
|
80
|
+
const k = ch.kMin! + (bytes[i] / 255) * (ch.kMax! - ch.kMin!);
|
|
81
|
+
state.colorTemperatureMireds = Math.round(clamp(1_000_000 / k, 50, 400));
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'saturation':
|
|
85
|
+
state.saturation = Math.round(clamp(bytes[i] / 2.55, 0, 100));
|
|
86
|
+
break;
|
|
87
|
+
case 'hue':
|
|
88
|
+
state.hue = Math.round((bytes[i] / 255) * 360) % 360;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
i++;
|
|
92
|
+
}
|
|
93
|
+
return state;
|
|
94
|
+
},
|
|
59
95
|
};
|
package/src/config.ts
CHANGED
|
@@ -48,6 +48,7 @@ export interface ControllerSpec {
|
|
|
48
48
|
ip: string; // controller's static IP
|
|
49
49
|
refreshMinutes?: number; // StickDE3 idle keepalive: re-send state every N min (0 = off)
|
|
50
50
|
priority?: number; // sACN only: E1.31 priority 0-200 (default 100)
|
|
51
|
+
statePollSeconds?: number; // sACN/Ethergate only: re-read device state every N s (0 = startup only)
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export interface ProfileSpec {
|
|
@@ -95,6 +96,7 @@ export interface Controller {
|
|
|
95
96
|
ip: string;
|
|
96
97
|
refreshMinutes: number;
|
|
97
98
|
priority: number; // E1.31 priority; only the sACN controller reads it
|
|
99
|
+
statePollSeconds: number; // Ethergate read-back interval; 0 = seed at startup only
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
export interface Fixture {
|
|
@@ -172,8 +174,13 @@ export function loadConfig(rawJson: RawConfig, cwd?: string): LoadedConfig {
|
|
|
172
174
|
if (!Number.isInteger(priority) || priority < 0 || priority > 200) {
|
|
173
175
|
throw new Error(`controller "${cs.id}": priority must be an integer 0..200`);
|
|
174
176
|
}
|
|
177
|
+
const statePollSeconds = cs.statePollSeconds ?? 0;
|
|
178
|
+
if (typeof statePollSeconds !== 'number' || statePollSeconds < 0) {
|
|
179
|
+
throw new Error(`controller "${cs.id}": statePollSeconds must be a number >= 0`);
|
|
180
|
+
}
|
|
175
181
|
controllersById.set(cs.id, {
|
|
176
182
|
id: cs.id, type: cs.type as ControllerType, ip: cs.ip, refreshMinutes, priority,
|
|
183
|
+
statePollSeconds,
|
|
177
184
|
});
|
|
178
185
|
}
|
|
179
186
|
|
package/src/ethergate.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Ethergate Mk2 state read-back.
|
|
2
|
+
//
|
|
3
|
+
// The ENTTEC DIN Ethergate Mk2 exposes its live per-port DMX output
|
|
4
|
+
// buffers over a bare CGI-ish HTTP API. Responses have NO status line or
|
|
5
|
+
// headers (raw body only), which Node's http/fetch clients reject — so we
|
|
6
|
+
// speak over a raw TCP socket.
|
|
7
|
+
//
|
|
8
|
+
// Buffer indexing is per universe-SLOT, not per port (8 Overdrive slots
|
|
9
|
+
// per port on fw V1.3): port N slot k = buffer((N-1)*8 + k).cgi. We assume
|
|
10
|
+
// the plugin's own convention of port N carrying sACN universe N, so
|
|
11
|
+
// internal universe u (0=A, 1=B) reads buffer(u*8 + 1).
|
|
12
|
+
//
|
|
13
|
+
// Body format: 64 lines "rowR=v,v,v,v,v,v,v,v" covering slots 1..512.
|
|
14
|
+
|
|
15
|
+
import net from 'node:net';
|
|
16
|
+
|
|
17
|
+
const READ_TIMEOUT_MS = 4000;
|
|
18
|
+
|
|
19
|
+
/** Fetch the live 512-slot output buffer for an internal universe index
|
|
20
|
+
* (0=A, 1=B). Returns null on any failure — callers treat read-back as
|
|
21
|
+
* best-effort. */
|
|
22
|
+
export function readEthergateUniverse(ip: string, universe: number): Promise<Uint8Array | null> {
|
|
23
|
+
const bufferIdx = universe * 8 + 1;
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
const chunks: Buffer[] = [];
|
|
26
|
+
const sock = net.connect(80, ip);
|
|
27
|
+
const fail = (): void => { sock.destroy(); resolve(null); };
|
|
28
|
+
sock.setTimeout(READ_TIMEOUT_MS, fail);
|
|
29
|
+
sock.on('error', fail);
|
|
30
|
+
sock.on('connect', () => {
|
|
31
|
+
sock.write(`GET /index.html?buffer${bufferIdx}.cgi HTTP/1.0\r\nHost: ${ip}\r\n\r\n`);
|
|
32
|
+
});
|
|
33
|
+
sock.on('data', (d) => chunks.push(d));
|
|
34
|
+
sock.on('close', () => {
|
|
35
|
+
const body = Buffer.concat(chunks).toString('latin1');
|
|
36
|
+
const slots = new Uint8Array(512);
|
|
37
|
+
let seen = 0;
|
|
38
|
+
for (const line of body.split('\n')) {
|
|
39
|
+
const m = /^row(\d+)=([\d,]+)/.exec(line.trim());
|
|
40
|
+
if (!m) continue;
|
|
41
|
+
const base = (Number(m[1]) - 1) * 8;
|
|
42
|
+
const vals = m[2].split(',').map(Number);
|
|
43
|
+
for (let i = 0; i < vals.length && base + i < 512; i++) {
|
|
44
|
+
slots[base + i] = vals[i] & 0xff;
|
|
45
|
+
seen++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
resolve(seen === 512 ? slots : null);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
package/src/platform.ts
CHANGED
|
@@ -14,9 +14,10 @@ import type {
|
|
|
14
14
|
Service,
|
|
15
15
|
} from 'homebridge';
|
|
16
16
|
|
|
17
|
-
import { Controller, LoadedConfig, loadConfig, RawConfig } from './config.js';
|
|
17
|
+
import { Controller, Fixture, LoadedConfig, loadConfig, RawConfig } from './config.js';
|
|
18
18
|
import { StickController } from './controller.js';
|
|
19
19
|
import { DmxController } from './dmxController.js';
|
|
20
|
+
import { readEthergateUniverse } from './ethergate.js';
|
|
20
21
|
import { SacnController } from './sacn.js';
|
|
21
22
|
import { StickFixture } from './platformAccessory.js';
|
|
22
23
|
import { StateRegistry } from './stateRegistry.js';
|
|
@@ -31,6 +32,7 @@ export class DmxPlatform implements DynamicPlatformPlugin {
|
|
|
31
32
|
private cfg: LoadedConfig | null = null;
|
|
32
33
|
private controllers = new Map<string, DmxController>();
|
|
33
34
|
private registry = new StateRegistry();
|
|
35
|
+
private statePollTimers: NodeJS.Timeout[] = [];
|
|
34
36
|
|
|
35
37
|
constructor(
|
|
36
38
|
public readonly log: Logger,
|
|
@@ -61,12 +63,68 @@ export class DmxPlatform implements DynamicPlatformPlugin {
|
|
|
61
63
|
`${this.cfg.zones.length} zone${this.cfg.zones.length === 1 ? '' : 's'}`,
|
|
62
64
|
);
|
|
63
65
|
|
|
64
|
-
this.api.on('didFinishLaunching', () =>
|
|
66
|
+
this.api.on('didFinishLaunching', () => {
|
|
67
|
+
this.discoverDevices();
|
|
68
|
+
this.startStateSync();
|
|
69
|
+
});
|
|
65
70
|
this.api.on('shutdown', () => {
|
|
71
|
+
for (const t of this.statePollTimers) clearInterval(t);
|
|
66
72
|
for (const c of this.controllers.values()) c.shutdown();
|
|
67
73
|
});
|
|
68
74
|
}
|
|
69
75
|
|
|
76
|
+
/** State read-back (sACN/Ethergate only): the gateway's live output
|
|
77
|
+
* buffers are ground truth for what's on the wire, so seed the registry
|
|
78
|
+
* from them at startup — a Homebridge restart inherits reality instead
|
|
79
|
+
* of assuming darkness — and optionally re-poll every statePollSeconds
|
|
80
|
+
* to track changes made by other senders. */
|
|
81
|
+
private startStateSync(): void {
|
|
82
|
+
if (!this.cfg) return;
|
|
83
|
+
for (const spec of this.cfg.controllers) {
|
|
84
|
+
if (spec.type !== 'sACN') continue;
|
|
85
|
+
const ctrl = this.controllers.get(spec.id);
|
|
86
|
+
if (!(ctrl instanceof SacnController)) continue;
|
|
87
|
+
const fixtures = this.cfg.fixtures.filter(
|
|
88
|
+
(f) => f.controller.id === spec.id && f.profile.model.parse);
|
|
89
|
+
if (fixtures.length === 0) continue;
|
|
90
|
+
|
|
91
|
+
const sync = async (): Promise<void> => {
|
|
92
|
+
// Never clobber an in-flight HomeKit change with a read that may
|
|
93
|
+
// pre-date it.
|
|
94
|
+
if (Date.now() - ctrl.lastChangeAt < 5_000) return;
|
|
95
|
+
const universes = [...new Set(fixtures.map((f) => f.universe))];
|
|
96
|
+
for (const u of universes) {
|
|
97
|
+
const slots = await readEthergateUniverse(spec.ip, u);
|
|
98
|
+
if (!slots) {
|
|
99
|
+
this.log.debug(`state sync: universe ${u + 1} read failed (non-Ethergate gateway?)`);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
for (const fx of fixtures) {
|
|
103
|
+
if (fx.universe !== u) continue;
|
|
104
|
+
this.applyReadBack(fx, slots);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
sync().then(() => this.log.info(
|
|
110
|
+
`state sync: seeded ${fixtures.length} fixtures from ${spec.ip}`));
|
|
111
|
+
if (spec.statePollSeconds > 0) {
|
|
112
|
+
const t = setInterval(() => void sync(), spec.statePollSeconds * 1000);
|
|
113
|
+
t.unref?.();
|
|
114
|
+
this.statePollTimers.push(t);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private applyReadBack(fx: Fixture, slots: Uint8Array): void {
|
|
120
|
+
const bytes = slots.slice(fx.startCh - 1, fx.startCh - 1 + fx.nChannels);
|
|
121
|
+
const state = fx.profile.model.parse!(bytes, fx.profile.channels);
|
|
122
|
+
const cur = this.registry.get(fx.id);
|
|
123
|
+
if (JSON.stringify(cur) !== JSON.stringify(state)) {
|
|
124
|
+
this.registry.set(fx.id, state);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
70
128
|
private makeController(c: Controller): DmxController {
|
|
71
129
|
switch (c.type) {
|
|
72
130
|
case 'StickDE3':
|
package/src/sacn.ts
CHANGED
|
@@ -41,6 +41,10 @@ export class SacnController implements DmxController {
|
|
|
41
41
|
private dirty = new Set<number>();
|
|
42
42
|
private coalesceTimer: NodeJS.Timeout | null = null;
|
|
43
43
|
private keepaliveTimer: NodeJS.Timeout | null = null;
|
|
44
|
+
/** When setFixture last staged a change (keepalive re-sends excluded).
|
|
45
|
+
* Read by the platform's state-poll guard so a read-back never clobbers
|
|
46
|
+
* an in-flight HomeKit change. */
|
|
47
|
+
public lastChangeAt = 0;
|
|
44
48
|
private readonly socket: dgram.Socket;
|
|
45
49
|
private readonly cid = randomBytes(16);
|
|
46
50
|
private closed = false;
|
|
@@ -61,6 +65,7 @@ export class SacnController implements DmxController {
|
|
|
61
65
|
arr[fixture.startCh - 1 + i] = bytes[i];
|
|
62
66
|
}
|
|
63
67
|
this.dirty.add(fixture.universe);
|
|
68
|
+
this.lastChangeAt = Date.now();
|
|
64
69
|
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
65
70
|
this.log.info(`setFixture ${fixture.id}@DMX${fixture.startCh}/U${fixture.universe + 1}=${hex}`);
|
|
66
71
|
this.scheduleSend();
|