@ecopoesis/homebridge-dmx 0.5.4 → 0.5.5

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.
@@ -55,6 +55,15 @@ export declare function rgbBytes(rgb01: {
55
55
  b: number;
56
56
  };
57
57
  export declare function clamp(v: number, lo: number, hi: number): number;
58
+ /** Approximate a mired white point as HomeKit hue/sat — the swatch the Home
59
+ * app itself renders for that color temperature (Tanner Helland blackbody
60
+ * fit; 200 mireds/5000 K → rgb(255,228,206) → h27 s19, matching iOS).
61
+ * Needed for the dual-mode display convention (HAP-NodeJS#618): in white
62
+ * mode, Hue/Saturation must mirror the CCT's representation. */
63
+ export declare function miredsToHueSat(mireds: number): {
64
+ hue: number;
65
+ saturation: number;
66
+ };
58
67
  /** Tag a single-byte channel index plus its fine companion (if any), and
59
68
  * emit the right 16-bit split into `out`. Returns the index advanced past
60
69
  * any fine companion. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/color/types.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,gBAAgB,GACxB,IAAI,GACJ,YAAY,GACZ,KAAK,GACL,YAAY,GACZ,kBAAkB,CAAC;AAEvB;oDACoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,KAAK,GACL,YAAY,GACZ,KAAK,GACL,KAAK,GACL,OAAO,GACP,MAAM,GACN,OAAO,GACP,YAAY,GACZ,YAAY,GACZ,OAAO,CAAC;AAEZ;;mFAEmF;AACnF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,EAAE,gBAAgB,EAAE,CAAC;IAC7C,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACvC,8EAA8E;IAC9E,MAAM,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC;IACrE,yDAAyD;IACzD,KAAK,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC;CACtE;AAID,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAI7D;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAG5D;AAED,yDAAyD;AACzD,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrF;AAED;kDACkD;AAClD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAc9F;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,iBAAiB,GAC3F;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAOpC;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;0BAE0B;AAC1B,wBAAgB,YAAY,CAC1B,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,UAAU,EAAE,EACtB,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,MAAM,GACd,MAAM,CASR;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAY/E"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/color/types.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,40 @@ export function rgbBytes(rgb01, state) {
61
61
  export function clamp(v, lo, hi) {
62
62
  return v < lo ? lo : v > hi ? hi : v;
63
63
  }
64
+ /** Approximate a mired white point as HomeKit hue/sat — the swatch the Home
65
+ * app itself renders for that color temperature (Tanner Helland blackbody
66
+ * fit; 200 mireds/5000 K → rgb(255,228,206) → h27 s19, matching iOS).
67
+ * Needed for the dual-mode display convention (HAP-NodeJS#618): in white
68
+ * mode, Hue/Saturation must mirror the CCT's representation. */
69
+ export function miredsToHueSat(mireds) {
70
+ const t = clamp(1_000_000 / mireds, 1000, 40000) / 100;
71
+ let r, g, b;
72
+ if (t <= 66) {
73
+ r = 255;
74
+ g = clamp(99.4708025861 * Math.log(t) - 161.1195681661, 0, 255);
75
+ b = t <= 19 ? 0 : clamp(138.5177312231 * Math.log(t - 10) - 305.0447927307, 0, 255);
76
+ }
77
+ else {
78
+ r = clamp(329.698727446 * Math.pow(t - 60, -0.1332047592), 0, 255);
79
+ g = clamp(288.1221695283 * Math.pow(t - 60, -0.0755148492), 0, 255);
80
+ b = 255;
81
+ }
82
+ const max = Math.max(r, g, b);
83
+ const min = Math.min(r, g, b);
84
+ const d = max - min;
85
+ let h = 0;
86
+ if (d !== 0) {
87
+ if (max === r)
88
+ h = 60 * (((g - b) / d) % 6);
89
+ else if (max === g)
90
+ h = 60 * (((b - r) / d) + 2);
91
+ else
92
+ h = 60 * (((r - g) / d) + 4);
93
+ }
94
+ if (h < 0)
95
+ h += 360;
96
+ return { hue: Math.round(h), saturation: Math.round(max === 0 ? 0 : (d / max) * 100) };
97
+ }
64
98
  /** Tag a single-byte channel index plus its fine companion (if any), and
65
99
  * emit the right 16-bit split into `out`. Returns the index advanced past
66
100
  * any fine companion. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/color/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/color/types.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,14 @@ export declare class StickFixture {
12
12
  private pending;
13
13
  private bulb;
14
14
  constructor(platform: DmxPlatform, accessory: PlatformAccessory, fixture: Fixture, controller: DmxController, registry: StateRegistry);
15
+ /** HomeKit-facing view of the registry state, per the dual-mode display
16
+ * convention (HAP-NodeJS#618): in white mode (sat 0) Hue/Saturation
17
+ * mirror the CCT's hue/sat representation and ColorTemperature carries
18
+ * the real mireds; in color mode Hue/Saturation are the real values and
19
+ * ColorTemperature parks at the characteristic's minimum — that's how
20
+ * the Home app recognizes color mode on a fresh read (a "real" CT value
21
+ * makes reopened tiles render the CCT swatch instead of the color). */
22
+ private display;
15
23
  private pushFromRegistry;
16
24
  private schedule;
17
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"platformAccessory.d.ts","sourceRoot":"","sources":["../src/platformAccessory.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,qBAAa,YAAY;IAKrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,IAAI,CAAU;gBAGH,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,aAAa,EACzB,QAAQ,EAAE,aAAa;IAoE1C,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,QAAQ;CAcjB"}
1
+ {"version":3,"file":"platformAccessory.d.ts","sourceRoot":"","sources":["../src/platformAccessory.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,qBAAa,YAAY;IAKrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,IAAI,CAAU;gBAGH,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,aAAa,EACzB,QAAQ,EAAE,aAAa;IAoE1C;;;;;;4EAMwE;IACxE,OAAO,CAAC,OAAO;IAkBf,OAAO,CAAC,gBAAgB;IAoBxB,OAAO,CAAC,QAAQ;CAcjB"}
@@ -3,6 +3,7 @@
3
3
  // State is owned by the platform-wide StateRegistry. We read on .onGet,
4
4
  // write on .onSet, and subscribe to changes so the HomeKit-displayed
5
5
  // values track the registry (e.g. when a zone updates this fixture).
6
+ import { miredsToHueSat } from './color/types.js';
6
7
  import { CHARACTERISTIC_UPDATE_DELAY_MS } from './settings.js';
7
8
  export class StickFixture {
8
9
  platform;
@@ -44,7 +45,7 @@ export class StickFixture {
44
45
  }
45
46
  if (chars.includes('Hue')) {
46
47
  this.bulb.getCharacteristic(C.Hue)
47
- .onGet(() => registry.get(fixture.id).hue ?? 0)
48
+ .onGet(() => this.display().hue)
48
49
  .onSet((v) => {
49
50
  registry.update(fixture.id, { hue: Number(v) });
50
51
  this.schedule();
@@ -52,7 +53,7 @@ export class StickFixture {
52
53
  }
53
54
  if (chars.includes('Saturation')) {
54
55
  this.bulb.getCharacteristic(C.Saturation)
55
- .onGet(() => registry.get(fixture.id).saturation ?? 0)
56
+ .onGet(() => this.display().saturation)
56
57
  .onSet((v) => {
57
58
  registry.update(fixture.id, { saturation: Number(v) });
58
59
  this.schedule();
@@ -60,7 +61,7 @@ export class StickFixture {
60
61
  }
61
62
  if (chars.includes('ColorTemperature')) {
62
63
  this.bulb.getCharacteristic(C.ColorTemperature)
63
- .onGet(() => registry.get(fixture.id).colorTemperatureMireds ?? 200)
64
+ .onGet(() => this.display().ct)
64
65
  .onSet((v) => {
65
66
  // CCT change implies white mode; zero saturation.
66
67
  registry.update(fixture.id, {
@@ -78,24 +79,51 @@ export class StickFixture {
78
79
  this.pushFromRegistry();
79
80
  });
80
81
  }
81
- pushFromRegistry() {
82
+ /** HomeKit-facing view of the registry state, per the dual-mode display
83
+ * convention (HAP-NodeJS#618): in white mode (sat 0) Hue/Saturation
84
+ * mirror the CCT's hue/sat representation and ColorTemperature carries
85
+ * the real mireds; in color mode Hue/Saturation are the real values and
86
+ * ColorTemperature parks at the characteristic's minimum — that's how
87
+ * the Home app recognizes color mode on a fresh read (a "real" CT value
88
+ * makes reopened tiles render the CCT swatch instead of the color). */
89
+ display() {
82
90
  const s = this.registry.get(this.fixture.id);
91
+ const chars = this.fixture.profile.model.characteristics;
92
+ const base = { on: s.on, brightness: s.brightness };
93
+ if (!chars.includes('ColorTemperature') || !chars.includes('Hue')) {
94
+ return { ...base, hue: s.hue ?? 0, saturation: s.saturation ?? 0,
95
+ ct: s.colorTemperatureMireds ?? 200, whiteMode: (s.saturation ?? 0) === 0 };
96
+ }
97
+ if ((s.saturation ?? 0) === 0) {
98
+ const ct = s.colorTemperatureMireds ?? 200;
99
+ const rep = miredsToHueSat(ct);
100
+ return { ...base, hue: rep.hue, saturation: rep.saturation, ct, whiteMode: true };
101
+ }
102
+ const ctChar = this.bulb.getCharacteristic(this.platform.Characteristic.ColorTemperature);
103
+ const minCt = ctChar.props.minValue ?? 140;
104
+ return { ...base, hue: s.hue ?? 0, saturation: s.saturation, ct: minCt, whiteMode: false };
105
+ }
106
+ pushFromRegistry() {
107
+ const d = this.display();
83
108
  const C = this.platform.Characteristic;
84
109
  const chars = this.fixture.profile.model.characteristics;
85
- this.bulb.updateCharacteristic(C.On, s.on);
110
+ this.bulb.updateCharacteristic(C.On, d.on);
86
111
  if (chars.includes('Brightness'))
87
- this.bulb.updateCharacteristic(C.Brightness, s.brightness);
88
- if (chars.includes('Hue') && s.hue != null)
89
- this.bulb.updateCharacteristic(C.Hue, s.hue);
90
- if (chars.includes('Saturation') && s.saturation != null)
91
- this.bulb.updateCharacteristic(C.Saturation, s.saturation);
92
- // The Home app displays whichever mode was updated last (color vs
93
- // temperature). Only push ColorTemperature when the fixture is actually
94
- // in white mode (sat 0), so a color-mode update leaves Hue/Saturation as
95
- // the winning (displayed) pair.
96
- if (chars.includes('ColorTemperature') && s.colorTemperatureMireds != null
97
- && (s.saturation ?? 0) === 0) {
98
- this.bulb.updateCharacteristic(C.ColorTemperature, s.colorTemperatureMireds);
112
+ this.bulb.updateCharacteristic(C.Brightness, d.brightness);
113
+ if (chars.includes('Hue'))
114
+ this.bulb.updateCharacteristic(C.Hue, d.hue);
115
+ if (chars.includes('Saturation'))
116
+ this.bulb.updateCharacteristic(C.Saturation, d.saturation);
117
+ if (chars.includes('ColorTemperature')) {
118
+ if (d.whiteMode) {
119
+ // Real CCT, pushed last so temperature wins the display-mode race.
120
+ this.bulb.updateCharacteristic(C.ColorTemperature, d.ct);
121
+ }
122
+ else {
123
+ // Park CT at min WITHOUT an event (a CT event would flip the Home
124
+ // app to temperature display); plain .value assignment is silent.
125
+ this.bulb.getCharacteristic(C.ColorTemperature).value = d.ct;
126
+ }
99
127
  }
100
128
  }
101
129
  schedule() {
@@ -1 +1 @@
1
- {"version":3,"file":"platformAccessory.js","sourceRoot":"","sources":["../src/platformAccessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platformAccessory.js","sourceRoot":"","sources":["../src/platformAccessory.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,9 @@ export declare class ZoneFixture {
14
14
  constructor(platform: DmxPlatform, accessory: PlatformAccessory, zone: Zone, controllers: Map<string, DmxController>, registry: StateRegistry);
15
15
  /** Compute majority state across members, per characteristic. */
16
16
  private majorityState;
17
+ /** HomeKit-facing view of the majority state — same dual-mode display
18
+ * convention as StickFixture.display() (HAP-NodeJS#618). */
19
+ private display;
17
20
  /** A HomeKit set on the zone: build the new state from the current
18
21
  * majority + the patch the user is applying, write it into every
19
22
  * member, and trigger the controller after a small debounce so
@@ -1 +1 @@
1
- {"version":3,"file":"zoneAccessory.d.ts","sourceRoot":"","sources":["../src/zoneAccessory.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAgB,MAAM,oBAAoB,CAAC;AAEjE,qBAAa,WAAW;IAMpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,IAAI,CAAU;gBAGH,QAAQ,EAAE,WAAW,EACtC,SAAS,EAAE,iBAAiB,EACX,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EACvC,QAAQ,EAAE,aAAa;IAmD1C,iEAAiE;IACjE,OAAO,CAAC,aAAa;IAWrB;;;mDAG+C;IAC/C,OAAO,CAAC,cAAc;IAiBtB;qDACiD;IACjD,OAAO,CAAC,gBAAgB;IAuBxB;8CAC0C;IAC1C,OAAO,CAAC,eAAe;CAyBxB;AAGD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"zoneAccessory.d.ts","sourceRoot":"","sources":["../src/zoneAccessory.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAgB,MAAM,oBAAoB,CAAC;AAEjE,qBAAa,WAAW;IAMpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,IAAI,CAAU;gBAGH,QAAQ,EAAE,WAAW,EACtC,SAAS,EAAE,iBAAiB,EACX,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EACvC,QAAQ,EAAE,aAAa;IAmD1C,iEAAiE;IACjE,OAAO,CAAC,aAAa;IAWrB;iEAC6D;IAC7D,OAAO,CAAC,OAAO;IAiBf;;;mDAG+C;IAC/C,OAAO,CAAC,cAAc;IAiBtB;qDACiD;IACjD,OAAO,CAAC,gBAAgB;IAuBxB;8CAC0C;IAC1C,OAAO,CAAC,eAAe;CA4BxB;AAGD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC"}
@@ -14,6 +14,7 @@
14
14
  // When ANY member's state changes (by any path), the zone's HomeKit
15
15
  // characteristics push the new majority — so zones containing overlapping
16
16
  // members stay coherent with each other.
17
+ import { miredsToHueSat } from './color/types.js';
17
18
  import { CHARACTERISTIC_UPDATE_DELAY_MS } from './settings.js';
18
19
  import { pickMajority } from './stateRegistry.js';
19
20
  export class ZoneFixture {
@@ -49,17 +50,17 @@ export class ZoneFixture {
49
50
  }
50
51
  if (has('Hue')) {
51
52
  this.bulb.getCharacteristic(C.Hue)
52
- .onGet(() => this.majorityState().hue ?? 0)
53
+ .onGet(() => this.display().hue)
53
54
  .onSet((v) => this.applyToMembers({ hue: Number(v) }));
54
55
  }
55
56
  if (has('Saturation')) {
56
57
  this.bulb.getCharacteristic(C.Saturation)
57
- .onGet(() => this.majorityState().saturation ?? 0)
58
+ .onGet(() => this.display().saturation)
58
59
  .onSet((v) => this.applyToMembers({ saturation: Number(v) }));
59
60
  }
60
61
  if (has('ColorTemperature')) {
61
62
  this.bulb.getCharacteristic(C.ColorTemperature)
62
- .onGet(() => this.majorityState().colorTemperatureMireds ?? 200)
63
+ .onGet(() => this.display().ct)
63
64
  .onSet((v) => this.applyToMembers({
64
65
  colorTemperatureMireds: Number(v),
65
66
  saturation: 0,
@@ -83,6 +84,24 @@ export class ZoneFixture {
83
84
  colorTemperatureMireds: pickMajority(ss.map((s) => ({ id: s.id, v: s.state.colorTemperatureMireds }))),
84
85
  };
85
86
  }
87
+ /** HomeKit-facing view of the majority state — same dual-mode display
88
+ * convention as StickFixture.display() (HAP-NodeJS#618). */
89
+ display() {
90
+ const s = this.majorityState();
91
+ if (!this.zone.characteristics.includes('ColorTemperature')
92
+ || !this.zone.characteristics.includes('Hue')) {
93
+ return { hue: s.hue ?? 0, saturation: s.saturation ?? 0,
94
+ ct: s.colorTemperatureMireds ?? 200, whiteMode: (s.saturation ?? 0) === 0 };
95
+ }
96
+ if ((s.saturation ?? 0) === 0) {
97
+ const ct = s.colorTemperatureMireds ?? 200;
98
+ const rep = miredsToHueSat(ct);
99
+ return { hue: rep.hue, saturation: rep.saturation, ct, whiteMode: true };
100
+ }
101
+ const ctChar = this.bulb.getCharacteristic(this.platform.Characteristic.ColorTemperature);
102
+ const minCt = ctChar.props.minValue ?? 140;
103
+ return { hue: s.hue ?? 0, saturation: s.saturation, ct: minCt, whiteMode: false };
104
+ }
86
105
  /** A HomeKit set on the zone: build the new state from the current
87
106
  * majority + the patch the user is applying, write it into every
88
107
  * member, and trigger the controller after a small debounce so
@@ -134,23 +153,27 @@ export class ZoneFixture {
134
153
  this.refreshPending = setTimeout(() => {
135
154
  this.refreshPending = null;
136
155
  const s = this.majorityState();
156
+ const d = this.display();
137
157
  const C = this.platform.Characteristic;
138
158
  this.bulb.updateCharacteristic(C.On, s.on);
139
159
  if (this.zone.characteristics.includes('Brightness')) {
140
160
  this.bulb.updateCharacteristic(C.Brightness, s.brightness);
141
161
  }
142
- if (this.zone.characteristics.includes('Hue') && s.hue != null) {
143
- this.bulb.updateCharacteristic(C.Hue, s.hue);
162
+ if (this.zone.characteristics.includes('Hue')) {
163
+ this.bulb.updateCharacteristic(C.Hue, d.hue);
144
164
  }
145
- if (this.zone.characteristics.includes('Saturation') && s.saturation != null) {
146
- this.bulb.updateCharacteristic(C.Saturation, s.saturation);
165
+ if (this.zone.characteristics.includes('Saturation')) {
166
+ this.bulb.updateCharacteristic(C.Saturation, d.saturation);
147
167
  }
148
- // Same rule as StickFixture.pushFromRegistry: the Home app displays
149
- // whichever mode updated last, so only push ColorTemperature when the
150
- // zone majority is actually in white mode (sat 0).
151
- if (this.zone.characteristics.includes('ColorTemperature') && s.colorTemperatureMireds != null
152
- && (s.saturation ?? 0) === 0) {
153
- this.bulb.updateCharacteristic(C.ColorTemperature, s.colorTemperatureMireds);
168
+ if (this.zone.characteristics.includes('ColorTemperature')) {
169
+ if (d.whiteMode) {
170
+ // Real CCT, pushed last so temperature wins the display-mode race.
171
+ this.bulb.updateCharacteristic(C.ColorTemperature, d.ct);
172
+ }
173
+ else {
174
+ // Park CT at min silently (see StickFixture.pushFromRegistry).
175
+ this.bulb.getCharacteristic(C.ColorTemperature).value = d.ct;
176
+ }
154
177
  }
155
178
  }, CHARACTERISTIC_UPDATE_DELAY_MS);
156
179
  }
@@ -1 +1 @@
1
- {"version":3,"file":"zoneAccessory.js","sourceRoot":"","sources":["../src/zoneAccessory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zoneAccessory.js","sourceRoot":"","sources":["../src/zoneAccessory.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ecopoesis/homebridge-dmx",
3
3
  "displayName": "DMX",
4
- "version": "0.5.4",
4
+ "version": "0.5.5",
5
5
  "description": "Homebridge platform for DMX controllers (currently Nicolaudie Stick-DE3)",
6
6
  "license": "Apache-2.0",
7
7
  "type": "module",
@@ -115,6 +115,36 @@ export function clamp(v: number, lo: number, hi: number): number {
115
115
  return v < lo ? lo : v > hi ? hi : v;
116
116
  }
117
117
 
118
+ /** Approximate a mired white point as HomeKit hue/sat — the swatch the Home
119
+ * app itself renders for that color temperature (Tanner Helland blackbody
120
+ * fit; 200 mireds/5000 K → rgb(255,228,206) → h27 s19, matching iOS).
121
+ * Needed for the dual-mode display convention (HAP-NodeJS#618): in white
122
+ * mode, Hue/Saturation must mirror the CCT's representation. */
123
+ export function miredsToHueSat(mireds: number): { hue: number; saturation: number } {
124
+ const t = clamp(1_000_000 / mireds, 1000, 40000) / 100;
125
+ let r: number, g: number, b: number;
126
+ if (t <= 66) {
127
+ r = 255;
128
+ g = clamp(99.4708025861 * Math.log(t) - 161.1195681661, 0, 255);
129
+ b = t <= 19 ? 0 : clamp(138.5177312231 * Math.log(t - 10) - 305.0447927307, 0, 255);
130
+ } else {
131
+ r = clamp(329.698727446 * Math.pow(t - 60, -0.1332047592), 0, 255);
132
+ g = clamp(288.1221695283 * Math.pow(t - 60, -0.0755148492), 0, 255);
133
+ b = 255;
134
+ }
135
+ const max = Math.max(r, g, b);
136
+ const min = Math.min(r, g, b);
137
+ const d = max - min;
138
+ let h = 0;
139
+ if (d !== 0) {
140
+ if (max === r) h = 60 * (((g - b) / d) % 6);
141
+ else if (max === g) h = 60 * (((b - r) / d) + 2);
142
+ else h = 60 * (((r - g) / d) + 4);
143
+ }
144
+ if (h < 0) h += 360;
145
+ return { hue: Math.round(h), saturation: Math.round(max === 0 ? 0 : (d / max) * 100) };
146
+ }
147
+
118
148
  /** Tag a single-byte channel index plus its fine companion (if any), and
119
149
  * emit the right 16-bit split into `out`. Returns the index advanced past
120
150
  * any fine companion. */
@@ -11,7 +11,7 @@ import type {
11
11
  } from 'homebridge';
12
12
 
13
13
  import { Fixture } from './config.js';
14
- import { HomeKitLightState } from './color/types.js';
14
+ import { HomeKitLightState, miredsToHueSat } from './color/types.js';
15
15
  import { DmxController } from './dmxController.js';
16
16
  import type { DmxPlatform } from './platform.js';
17
17
  import { CHARACTERISTIC_UPDATE_DELAY_MS } from './settings.js';
@@ -59,7 +59,7 @@ export class StickFixture {
59
59
  }
60
60
  if (chars.includes('Hue')) {
61
61
  this.bulb.getCharacteristic(C.Hue)
62
- .onGet(() => registry.get(fixture.id).hue ?? 0)
62
+ .onGet(() => this.display().hue)
63
63
  .onSet((v) => {
64
64
  registry.update(fixture.id, { hue: Number(v) });
65
65
  this.schedule();
@@ -67,7 +67,7 @@ export class StickFixture {
67
67
  }
68
68
  if (chars.includes('Saturation')) {
69
69
  this.bulb.getCharacteristic(C.Saturation)
70
- .onGet(() => registry.get(fixture.id).saturation ?? 0)
70
+ .onGet(() => this.display().saturation)
71
71
  .onSet((v) => {
72
72
  registry.update(fixture.id, { saturation: Number(v) });
73
73
  this.schedule();
@@ -75,7 +75,7 @@ export class StickFixture {
75
75
  }
76
76
  if (chars.includes('ColorTemperature')) {
77
77
  this.bulb.getCharacteristic(C.ColorTemperature)
78
- .onGet(() => registry.get(fixture.id).colorTemperatureMireds ?? 200)
78
+ .onGet(() => this.display().ct)
79
79
  .onSet((v) => {
80
80
  // CCT change implies white mode; zero saturation.
81
81
  registry.update(fixture.id, {
@@ -94,21 +94,48 @@ export class StickFixture {
94
94
  });
95
95
  }
96
96
 
97
- private pushFromRegistry(): void {
97
+ /** HomeKit-facing view of the registry state, per the dual-mode display
98
+ * convention (HAP-NodeJS#618): in white mode (sat 0) Hue/Saturation
99
+ * mirror the CCT's hue/sat representation and ColorTemperature carries
100
+ * the real mireds; in color mode Hue/Saturation are the real values and
101
+ * ColorTemperature parks at the characteristic's minimum — that's how
102
+ * the Home app recognizes color mode on a fresh read (a "real" CT value
103
+ * makes reopened tiles render the CCT swatch instead of the color). */
104
+ private display(): { on: boolean; brightness: number; hue: number; saturation: number; ct: number; whiteMode: boolean } {
98
105
  const s = this.registry.get(this.fixture.id);
106
+ const chars = this.fixture.profile.model.characteristics;
107
+ const base = { on: s.on, brightness: s.brightness };
108
+ if (!chars.includes('ColorTemperature') || !chars.includes('Hue')) {
109
+ return { ...base, hue: s.hue ?? 0, saturation: s.saturation ?? 0,
110
+ ct: s.colorTemperatureMireds ?? 200, whiteMode: (s.saturation ?? 0) === 0 };
111
+ }
112
+ if ((s.saturation ?? 0) === 0) {
113
+ const ct = s.colorTemperatureMireds ?? 200;
114
+ const rep = miredsToHueSat(ct);
115
+ return { ...base, hue: rep.hue, saturation: rep.saturation, ct, whiteMode: true };
116
+ }
117
+ const ctChar = this.bulb.getCharacteristic(this.platform.Characteristic.ColorTemperature);
118
+ const minCt = (ctChar.props.minValue as number | undefined) ?? 140;
119
+ return { ...base, hue: s.hue ?? 0, saturation: s.saturation!, ct: minCt, whiteMode: false };
120
+ }
121
+
122
+ private pushFromRegistry(): void {
123
+ const d = this.display();
99
124
  const C = this.platform.Characteristic;
100
125
  const chars = this.fixture.profile.model.characteristics;
101
- this.bulb.updateCharacteristic(C.On, s.on);
102
- if (chars.includes('Brightness')) this.bulb.updateCharacteristic(C.Brightness, s.brightness);
103
- if (chars.includes('Hue') && s.hue != null) this.bulb.updateCharacteristic(C.Hue, s.hue);
104
- if (chars.includes('Saturation') && s.saturation != null) this.bulb.updateCharacteristic(C.Saturation, s.saturation);
105
- // The Home app displays whichever mode was updated last (color vs
106
- // temperature). Only push ColorTemperature when the fixture is actually
107
- // in white mode (sat 0), so a color-mode update leaves Hue/Saturation as
108
- // the winning (displayed) pair.
109
- if (chars.includes('ColorTemperature') && s.colorTemperatureMireds != null
110
- && (s.saturation ?? 0) === 0) {
111
- this.bulb.updateCharacteristic(C.ColorTemperature, s.colorTemperatureMireds);
126
+ this.bulb.updateCharacteristic(C.On, d.on);
127
+ if (chars.includes('Brightness')) this.bulb.updateCharacteristic(C.Brightness, d.brightness);
128
+ if (chars.includes('Hue')) this.bulb.updateCharacteristic(C.Hue, d.hue);
129
+ if (chars.includes('Saturation')) this.bulb.updateCharacteristic(C.Saturation, d.saturation);
130
+ if (chars.includes('ColorTemperature')) {
131
+ if (d.whiteMode) {
132
+ // Real CCT, pushed last so temperature wins the display-mode race.
133
+ this.bulb.updateCharacteristic(C.ColorTemperature, d.ct);
134
+ } else {
135
+ // Park CT at min WITHOUT an event (a CT event would flip the Home
136
+ // app to temperature display); plain .value assignment is silent.
137
+ this.bulb.getCharacteristic(C.ColorTemperature).value = d.ct;
138
+ }
112
139
  }
113
140
  }
114
141
 
@@ -22,7 +22,7 @@ import type {
22
22
  } from 'homebridge';
23
23
 
24
24
  import { Fixture, Zone } from './config.js';
25
- import { HKCharacteristic, HomeKitLightState } from './color/types.js';
25
+ import { HKCharacteristic, HomeKitLightState, miredsToHueSat } from './color/types.js';
26
26
  import { DmxController } from './dmxController.js';
27
27
  import type { DmxPlatform } from './platform.js';
28
28
  import { CHARACTERISTIC_UPDATE_DELAY_MS } from './settings.js';
@@ -65,17 +65,17 @@ export class ZoneFixture {
65
65
  }
66
66
  if (has('Hue')) {
67
67
  this.bulb.getCharacteristic(C.Hue)
68
- .onGet(() => this.majorityState().hue ?? 0)
68
+ .onGet(() => this.display().hue)
69
69
  .onSet((v) => this.applyToMembers({ hue: Number(v) }));
70
70
  }
71
71
  if (has('Saturation')) {
72
72
  this.bulb.getCharacteristic(C.Saturation)
73
- .onGet(() => this.majorityState().saturation ?? 0)
73
+ .onGet(() => this.display().saturation)
74
74
  .onSet((v) => this.applyToMembers({ saturation: Number(v) }));
75
75
  }
76
76
  if (has('ColorTemperature')) {
77
77
  this.bulb.getCharacteristic(C.ColorTemperature)
78
- .onGet(() => this.majorityState().colorTemperatureMireds ?? 200)
78
+ .onGet(() => this.display().ct)
79
79
  .onSet((v) => this.applyToMembers({
80
80
  colorTemperatureMireds: Number(v),
81
81
  saturation: 0,
@@ -101,6 +101,25 @@ export class ZoneFixture {
101
101
  };
102
102
  }
103
103
 
104
+ /** HomeKit-facing view of the majority state — same dual-mode display
105
+ * convention as StickFixture.display() (HAP-NodeJS#618). */
106
+ private display(): { hue: number; saturation: number; ct: number; whiteMode: boolean } {
107
+ const s = this.majorityState();
108
+ if (!this.zone.characteristics.includes('ColorTemperature')
109
+ || !this.zone.characteristics.includes('Hue')) {
110
+ return { hue: s.hue ?? 0, saturation: s.saturation ?? 0,
111
+ ct: s.colorTemperatureMireds ?? 200, whiteMode: (s.saturation ?? 0) === 0 };
112
+ }
113
+ if ((s.saturation ?? 0) === 0) {
114
+ const ct = s.colorTemperatureMireds ?? 200;
115
+ const rep = miredsToHueSat(ct);
116
+ return { hue: rep.hue, saturation: rep.saturation, ct, whiteMode: true };
117
+ }
118
+ const ctChar = this.bulb.getCharacteristic(this.platform.Characteristic.ColorTemperature);
119
+ const minCt = (ctChar.props.minValue as number | undefined) ?? 140;
120
+ return { hue: s.hue ?? 0, saturation: s.saturation!, ct: minCt, whiteMode: false };
121
+ }
122
+
104
123
  /** A HomeKit set on the zone: build the new state from the current
105
124
  * majority + the patch the user is applying, write it into every
106
125
  * member, and trigger the controller after a small debounce so
@@ -154,23 +173,26 @@ export class ZoneFixture {
154
173
  this.refreshPending = setTimeout(() => {
155
174
  this.refreshPending = null;
156
175
  const s = this.majorityState();
176
+ const d = this.display();
157
177
  const C = this.platform.Characteristic;
158
178
  this.bulb.updateCharacteristic(C.On, s.on);
159
179
  if (this.zone.characteristics.includes('Brightness')) {
160
180
  this.bulb.updateCharacteristic(C.Brightness, s.brightness);
161
181
  }
162
- if (this.zone.characteristics.includes('Hue') && s.hue != null) {
163
- this.bulb.updateCharacteristic(C.Hue, s.hue);
182
+ if (this.zone.characteristics.includes('Hue')) {
183
+ this.bulb.updateCharacteristic(C.Hue, d.hue);
164
184
  }
165
- if (this.zone.characteristics.includes('Saturation') && s.saturation != null) {
166
- this.bulb.updateCharacteristic(C.Saturation, s.saturation);
185
+ if (this.zone.characteristics.includes('Saturation')) {
186
+ this.bulb.updateCharacteristic(C.Saturation, d.saturation);
167
187
  }
168
- // Same rule as StickFixture.pushFromRegistry: the Home app displays
169
- // whichever mode updated last, so only push ColorTemperature when the
170
- // zone majority is actually in white mode (sat 0).
171
- if (this.zone.characteristics.includes('ColorTemperature') && s.colorTemperatureMireds != null
172
- && (s.saturation ?? 0) === 0) {
173
- this.bulb.updateCharacteristic(C.ColorTemperature, s.colorTemperatureMireds);
188
+ if (this.zone.characteristics.includes('ColorTemperature')) {
189
+ if (d.whiteMode) {
190
+ // Real CCT, pushed last so temperature wins the display-mode race.
191
+ this.bulb.updateCharacteristic(C.ColorTemperature, d.ct);
192
+ } else {
193
+ // Park CT at min silently (see StickFixture.pushFromRegistry).
194
+ this.bulb.getCharacteristic(C.ColorTemperature).value = d.ct;
195
+ }
174
196
  }
175
197
  }, CHARACTERISTIC_UPDATE_DELAY_MS);
176
198
  }