homebridge-tydom 0.31.2 → 0.32.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/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as PLUGIN_NAME, t as PLATFORM_NAME } from "./env-B2-Dw8C2.mjs";
2
2
  //#region src/index.ts
3
3
  process.setSourceMapsEnabled(true);
4
- const { default: TydomPlatform } = await import("./platform-BjoGoTvF.mjs");
4
+ const { default: TydomPlatform } = await import("./platform-DmVGk0po.mjs");
5
5
  var src_default = (homebridge) => {
6
6
  homebridge.registerPlatform(PLUGIN_NAME, PLATFORM_NAME, TydomPlatform);
7
7
  };
@@ -4770,34 +4770,86 @@ var ThermostatAccessory = class extends BaseAccessory {
4770
4770
  #service;
4771
4771
  /** Thermic-level switches, by the Tydom value each one selects. */
4772
4772
  #levelSwitches = /* @__PURE__ */ new Map();
4773
+ /**
4774
+ * Whether this device can cool as well as heat.
4775
+ *
4776
+ * Read from the endpoint's own metadata rather than configured: reversible
4777
+ * hardware — a heat pump that runs in reverse — advertises `COOLING` among
4778
+ * the values its `authorization` property accepts, and a radiator does not.
4779
+ * Offering HomeKit a cool mode on a radiator would put a button in the Home
4780
+ * app that silently does nothing.
4781
+ */
4782
+ #canCool;
4783
+ /**
4784
+ * Which property carries the operating mode on this device.
4785
+ *
4786
+ * Delta Dore replaced `hvacMode` with `localMode` on newer thermostats — the
4787
+ * Tybox 5100 and relatives carry no `hvacMode` at all. Reading a property
4788
+ * that is not there throws, so on that hardware every
4789
+ * `TargetHeatingCoolingState` query failed: the accessory was discovered and
4790
+ * registered, then errored on every read. The values are the same apart from
4791
+ * an added `ABSENCE`, so resolving the name is the whole fix.
4792
+ *
4793
+ * `hvacMode` wins when both are present, so nothing changes for hardware that
4794
+ * already worked.
4795
+ */
4796
+ #modeProp;
4773
4797
  constructor(deps) {
4774
4798
  super(deps);
4799
+ const metadata = deps.accessory.context.metadata;
4800
+ const hasProp = (name) => metadata.some((entry) => entry.name === name);
4801
+ this.#modeProp = hasProp("hvacMode") ? "hvacMode" : hasProp("localMode") ? "localMode" : "hvacMode";
4802
+ if (!hasProp("hvacMode") && !hasProp("localMode")) deps.platform.log.warn(`Thermostat ${deps.accessory.displayName} advertises neither "hvacMode" nor "localMode"; its mode controls will not work.`);
4803
+ this.#canCool = Boolean(deps.accessory.context.metadata.find(({ name }) => name === "authorization")?.enum_values?.includes("COOLING"));
4775
4804
  const { TargetHeatingCoolingState, CurrentHeatingCoolingState, TargetTemperature, CurrentTemperature } = this.platform.Characteristic;
4776
4805
  this.#service = this.service(this.platform.Service.Thermostat);
4777
- this.#service.getCharacteristic(CurrentHeatingCoolingState).setProps({ validValues: [0, 1] }).onGet(async () => {
4806
+ this.#service.getCharacteristic(CurrentHeatingCoolingState).setProps({ validValues: this.#canCool ? [
4807
+ 0,
4808
+ 1,
4809
+ 2
4810
+ ] : [0, 1] }).onGet(async () => {
4778
4811
  debugGet(CurrentHeatingCoolingState, this.#service);
4779
4812
  const data = await this.#read();
4780
4813
  const authorization = getTydomDataPropValue(data, "authorization");
4781
4814
  const setpoint = getTydomDataPropValue(data, "setpoint");
4782
4815
  const temperature = getTydomDataPropValue(data, "temperature");
4783
- const nextValue = authorization === "HEATING" && setpoint > temperature ? CurrentHeatingCoolingState.HEAT : CurrentHeatingCoolingState.OFF;
4816
+ let nextValue = CurrentHeatingCoolingState.OFF;
4817
+ if (authorization === "HEATING" && setpoint > temperature) nextValue = CurrentHeatingCoolingState.HEAT;
4818
+ else if (authorization === "COOLING" && temperature > setpoint) nextValue = CurrentHeatingCoolingState.COOL;
4784
4819
  debugGetResult(CurrentHeatingCoolingState, this.#service, nextValue);
4785
4820
  return nextValue;
4786
4821
  });
4787
- this.#service.getCharacteristic(TargetHeatingCoolingState).setProps({ validValues: [0, 1] }).onGet(async () => {
4822
+ this.#service.getCharacteristic(TargetHeatingCoolingState).setProps({ validValues: this.#canCool ? [
4823
+ 0,
4824
+ 1,
4825
+ 2
4826
+ ] : [0, 1] }).onGet(async () => {
4788
4827
  debugGet(TargetHeatingCoolingState, this.#service);
4789
4828
  const data = await this.#read();
4790
- const hvacMode = getTydomDataPropValue(data, "hvacMode");
4791
- const nextValue = getTydomDataPropValue(data, "authorization") === "HEATING" && hvacMode === "NORMAL" ? TargetHeatingCoolingState.HEAT : TargetHeatingCoolingState.OFF;
4829
+ const hvacMode = getTydomDataPropValue(data, this.#modeProp);
4830
+ const authorization = getTydomDataPropValue(data, "authorization");
4831
+ let nextValue = TargetHeatingCoolingState.OFF;
4832
+ if (hvacMode === "NORMAL" && authorization === "HEATING") nextValue = TargetHeatingCoolingState.HEAT;
4833
+ else if (hvacMode === "NORMAL" && authorization === "COOLING") nextValue = TargetHeatingCoolingState.COOL;
4792
4834
  debugGetResult(TargetHeatingCoolingState, this.#service, nextValue);
4793
4835
  return nextValue;
4794
4836
  }).onSet(async (value) => {
4795
4837
  debugSet(TargetHeatingCoolingState, this.#service, value);
4796
- const shouldHeat = [TargetHeatingCoolingState.HEAT, TargetHeatingCoolingState.AUTO].includes(value);
4797
- const tydomValue = shouldHeat ? "NORMAL" : "STOP";
4798
- await this.#writeHvacMode(tydomValue);
4799
- debugSetResult(TargetHeatingCoolingState, this.#service, value, tydomValue);
4800
- this.#service.getCharacteristic(CurrentHeatingCoolingState).updateValue(shouldHeat ? CurrentHeatingCoolingState.HEAT : CurrentHeatingCoolingState.OFF);
4838
+ const wantsCool = this.#canCool && value === TargetHeatingCoolingState.COOL;
4839
+ const isOn = wantsCool || [TargetHeatingCoolingState.HEAT, TargetHeatingCoolingState.AUTO].includes(value);
4840
+ const hvacMode = isOn ? "NORMAL" : "STOP";
4841
+ const values = [{
4842
+ name: this.#modeProp,
4843
+ value: hvacMode
4844
+ }];
4845
+ if (this.#canCool) values.push({
4846
+ name: "authorization",
4847
+ value: isOn ? wantsCool ? "COOLING" : "HEATING" : "STOP"
4848
+ });
4849
+ await this.api.putDeviceData(this.deviceId, this.endpointId, values);
4850
+ debugSetResult(TargetHeatingCoolingState, this.#service, value, hvacMode);
4851
+ const current = wantsCool ? CurrentHeatingCoolingState.COOL : isOn ? CurrentHeatingCoolingState.HEAT : CurrentHeatingCoolingState.OFF;
4852
+ this.#service.getCharacteristic(CurrentHeatingCoolingState).updateValue(current);
4801
4853
  });
4802
4854
  this.#service.getCharacteristic(CurrentTemperature).onGet(async () => {
4803
4855
  debugGet(CurrentTemperature, this.#service);
@@ -4825,13 +4877,21 @@ var ThermostatAccessory = class extends BaseAccessory {
4825
4877
  const { TargetHeatingCoolingState, CurrentHeatingCoolingState, TargetTemperature, CurrentTemperature } = this.platform.Characteristic;
4826
4878
  for (const { name, value } of updates) switch (name) {
4827
4879
  case "authorization":
4828
- if (value !== "STOP") break;
4880
+ if (value !== "STOP") {
4881
+ if (this.#canCool && (value === "COOLING" || value === "HEATING")) {
4882
+ const next = value === "COOLING" ? TargetHeatingCoolingState.COOL : TargetHeatingCoolingState.HEAT;
4883
+ debugSetUpdate(TargetHeatingCoolingState, this.#service, next);
4884
+ this.#service.updateCharacteristic(TargetHeatingCoolingState, next);
4885
+ }
4886
+ break;
4887
+ }
4829
4888
  debugSetUpdate(CurrentHeatingCoolingState, this.#service, CurrentHeatingCoolingState.OFF);
4830
4889
  this.#service.updateCharacteristic(CurrentHeatingCoolingState, CurrentHeatingCoolingState.OFF);
4831
4890
  debugSetUpdate(TargetHeatingCoolingState, this.#service, TargetHeatingCoolingState.OFF);
4832
4891
  this.#service.updateCharacteristic(TargetHeatingCoolingState, TargetHeatingCoolingState.OFF);
4833
4892
  break;
4834
- case "hvacMode": {
4893
+ case "hvacMode":
4894
+ case "localMode": {
4835
4895
  const hvacMode = value;
4836
4896
  if (hvacMode === "NORMAL") break;
4837
4897
  this.#service.updateCharacteristic(TargetHeatingCoolingState, TargetHeatingCoolingState.OFF);
@@ -4863,7 +4923,7 @@ var ThermostatAccessory = class extends BaseAccessory {
4863
4923
  }
4864
4924
  async #writeHvacMode(value) {
4865
4925
  await this.api.putDeviceData(this.deviceId, this.endpointId, [{
4866
- name: "hvacMode",
4926
+ name: this.#modeProp,
4867
4927
  value
4868
4928
  }]);
4869
4929
  }
@@ -4904,7 +4964,7 @@ var ThermostatAccessory = class extends BaseAccessory {
4904
4964
  service.getCharacteristic(On).onGet(async () => {
4905
4965
  debugGet(On, service);
4906
4966
  const data = await this.#read();
4907
- const nextValue = subtype === "hvacMode_absence" ? getTydomDataPropValue(data, "hvacMode") === "ANTI_FROST" : getTydomDataPropValue(data, "thermicLevel") === tydomValue;
4967
+ const nextValue = subtype === "hvacMode_absence" ? getTydomDataPropValue(data, this.#modeProp) === "ANTI_FROST" : getTydomDataPropValue(data, "thermicLevel") === tydomValue;
4908
4968
  debugGetResult(On, service, nextValue);
4909
4969
  return nextValue;
4910
4970
  }).onSet(async (value) => {
@@ -5544,4 +5604,4 @@ var TydomPlatform = class {
5544
5604
  //#endregion
5545
5605
  export { TydomPlatform as default };
5546
5606
 
5547
- //# sourceMappingURL=platform-BjoGoTvF.mjs.map
5607
+ //# sourceMappingURL=platform-DmVGk0po.mjs.map