@homebridge-plugins/homebridge-tado 8.5.1-beta.0 → 8.5.1-beta.2

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.
@@ -3,9 +3,9 @@ import moment from 'moment';
3
3
  import { writeFile, access, readFile } from 'fs/promises';
4
4
  import { join } from "path";
5
5
 
6
- var settingState = false;
7
- var delayTimer = {};
6
+ let settingState = false;
8
7
  let tasksInitialized = false;
8
+ const delayTimer = {};
9
9
 
10
10
  const timeout = (ms) => new Promise((res) => setTimeout(res, ms));
11
11
  const aRefreshHistoryHandlers = [];
@@ -27,7 +27,6 @@ export default (api, accessories, config, tado, telegram) => {
27
27
 
28
28
  async function setStates(accessory, accs, target, value) {
29
29
  let zoneUpdated = false;
30
- let allZonesUpdated = false;
31
30
 
32
31
  accessories = accs.filter((acc) => acc && acc.context.config.homeName === config.homeName);
33
32
 
@@ -376,7 +375,6 @@ export default (api, accessories, config, tado, telegram) => {
376
375
  }
377
376
  }
378
377
 
379
- allZonesUpdated = true;
380
378
  await tado.setPresenceLock(config.homeId, targetState);
381
379
 
382
380
  break;
@@ -428,7 +426,6 @@ export default (api, accessories, config, tado, telegram) => {
428
426
  })
429
427
  .filter((id) => id);
430
428
 
431
- allZonesUpdated = true;
432
429
  await tado.resumeShedule(config.homeId, roomIds);
433
430
 
434
431
  //Turn all back to AUTO/ON
@@ -553,7 +550,6 @@ export default (api, accessories, config, tado, telegram) => {
553
550
  .updateValue(false);
554
551
  }
555
552
 
556
- allZonesUpdated = true;
557
553
  await tado.switchAll(config.homeId, rooms);
558
554
 
559
555
  break;
@@ -570,7 +566,7 @@ export default (api, accessories, config, tado, telegram) => {
570
566
  errorHandler(err);
571
567
  } finally {
572
568
  //always update zone to set correct state in Apple Home
573
- if (zoneUpdated || allZonesUpdated) await updateZones(allZonesUpdated ? undefined : accessory.context.config.zoneId);
569
+ if (zoneUpdated) await updateZones(accessory.context.config.zoneId);
574
570
  settingState = false;
575
571
  }
576
572
  }
@@ -750,7 +746,7 @@ export default (api, accessories, config, tado, telegram) => {
750
746
  }
751
747
  try {
752
748
  //wait for fakegato history services to be loaded
753
- await new Promise(r => setTimeout(r, 4000));
749
+ await timeout(4000);
754
750
  for (const refreshHistory of aRefreshHistoryHandlers) {
755
751
  refreshHistory();
756
752
  }
@@ -813,413 +809,391 @@ export default (api, accessories, config, tado, telegram) => {
813
809
  }
814
810
 
815
811
  async function updateMe() {
816
- if (!settingState) {
817
- Logger.debug('Polling User Info...', config.homeName);
812
+ if (settingState) return;
818
813
 
819
- const me = await tado.getMe();
814
+ Logger.debug('Polling User Info...', config.homeName);
820
815
 
821
- if (config.homeName !== me.homes[0].name) throw ('Cannot find requested home in the API!', config.homeName);
816
+ const me = await tado.getMe();
822
817
 
823
- config.homeId = me.homes[0].id;
824
- }
818
+ if (config.homeName !== me.homes[0].name) throw ('Cannot find requested home in the API!', config.homeName);
825
819
 
826
- return;
820
+ config.homeId = me.homes[0].id;
827
821
  }
828
822
 
829
823
  async function updateHome() {
830
- if (!settingState) {
831
- Logger.debug('Polling Home Info...', config.homeName);
824
+ if (settingState) return;
832
825
 
833
- const home = await tado.getHome(config.homeId);
826
+ Logger.debug('Polling Home Info...', config.homeName);
834
827
 
835
- if (!config.temperatureUnit) config.temperatureUnit = home.temperatureUnit || 'CELSIUS';
828
+ const home = await tado.getHome(config.homeId);
836
829
 
837
- //config.skills = home.skills || []; //do we need this?
830
+ if (!config.temperatureUnit) config.temperatureUnit = home.temperatureUnit || 'CELSIUS';
838
831
 
839
- if (
840
- !config.geolocation ||
841
- (config.geolocation && !config.geolocation.longitude) ||
842
- !config.geolocation.latitude
843
- ) {
844
- if (!home.geolocation) home.geolocation = {};
832
+ //config.skills = home.skills || []; //do we need this?
845
833
 
846
- config.geolocation = {
847
- longitude: (home.geolocation.longitude || '').toString() || false,
848
- latitude: (home.geolocation.latitude || '').toString() || false,
849
- };
850
- }
851
- }
834
+ if (
835
+ !config.geolocation ||
836
+ (config.geolocation && !config.geolocation.longitude) ||
837
+ !config.geolocation.latitude
838
+ ) {
839
+ if (!home.geolocation) home.geolocation = {};
852
840
 
853
- return;
841
+ config.geolocation = {
842
+ longitude: (home.geolocation.longitude || '').toString() || false,
843
+ latitude: (home.geolocation.latitude || '').toString() || false,
844
+ };
845
+ }
854
846
  }
855
847
 
856
848
  async function updateZones(idToUpdate) {
857
849
  let zoneStates = {};
858
- if (!settingState || idToUpdate !== undefined) {
859
- Logger.debug('Polling Zones...', config.homeName);
850
+ if (settingState && idToUpdate === undefined) {
851
+ await timeout(10 * 1000);
852
+ if (settingState) return zoneStates;
853
+ }
860
854
 
861
- //CentralSwitch
862
- let inManualMode = 0;
863
- let inOffMode = 0;
864
- let inAutoMode = 0;
855
+ Logger.debug('Polling Zones...', config.homeName);
865
856
 
866
- let zonesWithoutID = config.zones.filter((zone) => zone && !zone.id);
857
+ //CentralSwitch
858
+ let inManualMode = 0;
859
+ let inOffMode = 0;
860
+ let inAutoMode = 0;
867
861
 
868
- if (zonesWithoutID.length) {
869
- const allZones = (await tado.getZones(config.homeId)) || [];
870
-
871
- for (const [index, zone] of config.zones.entries()) {
872
- allZones.forEach((zoneWithID) => {
873
- if (zoneWithID.name === zone.name) config.zones[index].id = zoneWithID.id;
874
- });
875
- }
876
- }
862
+ let zonesWithoutID = config.zones.filter((zone) => zone && !zone.id);
877
863
 
864
+ if (zonesWithoutID.length) {
878
865
  const allZones = (await tado.getZones(config.homeId)) || [];
879
866
 
880
867
  for (const [index, zone] of config.zones.entries()) {
881
868
  allZones.forEach((zoneWithID) => {
882
- if (zoneWithID.name === zone.name) {
883
- const heatAccessory = accessories.filter(
884
- (acc) => acc && acc.displayName === config.homeName + ' ' + zone.name + ' Heater'
885
- );
886
-
887
- if (heatAccessory.length) heatAccessory[0].context.config.zoneId = zoneWithID.id;
888
-
889
- config.zones[index].id = zoneWithID.id;
890
- config.zones[index].battery = !config.zones[index].noBattery
891
- ? zoneWithID.devices.filter(
892
- (device) =>
893
- device &&
894
- (zone.type === 'HEATING' || zone.type === 'AIR_CONDITIONING') &&
895
- typeof device.batteryState === 'string' &&
896
- !device.batteryState.includes('NORMAL')
897
- ).length
898
- ? zoneWithID.devices.filter((device) => device && !device.batteryState.includes('NORMAL'))[0]
899
- .batteryState
900
- : zoneWithID.devices.filter((device) => device && device.duties.includes('ZONE_LEADER'))[0].batteryState
901
- : false;
902
- config.zones[index].openWindowEnabled =
903
- zoneWithID.openWindowDetection && zoneWithID.openWindowDetection.enabled ? true : false;
904
- }
869
+ if (zoneWithID.name === zone.name) config.zones[index].id = zoneWithID.id;
905
870
  });
906
871
  }
872
+ }
907
873
 
908
- let zonesToUpdate = [];
909
- if (idToUpdate !== undefined) {
910
- zoneStates[idToUpdate] = await tado.getZoneState(config.homeId, idToUpdate);
911
- zonesToUpdate = config.zones.filter(zone => zone.id === idToUpdate);
912
- } else {
913
- zoneStates = (await tado.getZoneStates(config.homeId))["zoneStates"];
914
- zonesToUpdate = config.zones;
915
- }
916
-
917
- for (const zone of zonesToUpdate) {
918
- const zoneState = zoneStates[zone.id];
874
+ const allZones = (await tado.getZones(config.homeId)) || [];
919
875
 
920
- let currentState, targetState, currentTemp, targetTemp, humidity, active, battery, tempEqual;
876
+ for (const [index, zone] of config.zones.entries()) {
877
+ allZones.forEach((zoneWithID) => {
878
+ if (zoneWithID.name === zone.name) {
879
+ const heatAccessory = accessories.filter(
880
+ (acc) => acc && acc.displayName === config.homeName + ' ' + zone.name + ' Heater'
881
+ );
921
882
 
922
- if (zoneState.setting.type === 'HEATING') {
923
- battery = zone.battery === 'NORMAL' ? 100 : 10;
883
+ if (heatAccessory.length) heatAccessory[0].context.config.zoneId = zoneWithID.id;
884
+
885
+ config.zones[index].id = zoneWithID.id;
886
+ config.zones[index].battery = !config.zones[index].noBattery
887
+ ? zoneWithID.devices.filter(
888
+ (device) =>
889
+ device &&
890
+ (zone.type === 'HEATING' || zone.type === 'AIR_CONDITIONING') &&
891
+ typeof device.batteryState === 'string' &&
892
+ !device.batteryState.includes('NORMAL')
893
+ ).length
894
+ ? zoneWithID.devices.filter((device) => device && !device.batteryState.includes('NORMAL'))[0]
895
+ .batteryState
896
+ : zoneWithID.devices.filter((device) => device && device.duties.includes('ZONE_LEADER'))[0].batteryState
897
+ : false;
898
+ config.zones[index].openWindowEnabled =
899
+ zoneWithID.openWindowDetection && zoneWithID.openWindowDetection.enabled ? true : false;
900
+ }
901
+ });
902
+ }
924
903
 
925
- if (zoneState.sensorDataPoints.humidity) humidity = zoneState.sensorDataPoints.humidity.percentage;
904
+ let zonesToUpdate = [];
905
+ if (idToUpdate !== undefined) {
906
+ zoneStates[idToUpdate] = await tado.getZoneState(config.homeId, idToUpdate);
907
+ zonesToUpdate = config.zones.filter(zone => zone.id === idToUpdate);
908
+ } else {
909
+ zoneStates = (await tado.getZoneStates(config.homeId))["zoneStates"];
910
+ zonesToUpdate = config.zones;
911
+ }
926
912
 
927
- //HEATING
928
- if (zoneState.sensorDataPoints.insideTemperature) {
929
- currentTemp =
930
- config.temperatureUnit === 'FAHRENHEIT'
931
- ? zoneState.sensorDataPoints.insideTemperature.fahrenheit
932
- : zoneState.sensorDataPoints.insideTemperature.celsius;
913
+ for (const zone of zonesToUpdate) {
914
+ const zoneState = zoneStates[zone.id];
933
915
 
934
- if (zoneState.setting.power === 'ON') {
935
- targetTemp =
936
- config.temperatureUnit === 'FAHRENHEIT'
937
- ? zoneState.setting.temperature.fahrenheit
938
- : zoneState.setting.temperature.celsius;
916
+ let currentState, targetState, currentTemp, targetTemp, humidity, active, battery, tempEqual;
939
917
 
940
- tempEqual = Math.round(currentTemp) === Math.round(targetTemp);
918
+ if (zoneState.setting.type === 'HEATING') {
919
+ battery = zone.battery === 'NORMAL' ? 100 : 10;
941
920
 
942
- //show as currently heating if current temp is lower than target temp, otherwise show as temp set
943
- currentState = currentTemp < targetTemp ? 1 : 0;
921
+ if (zoneState.sensorDataPoints.humidity) humidity = zoneState.sensorDataPoints.humidity.percentage;
944
922
 
945
- //check if auto mode is enabled
946
- targetState = zoneState.overlayType === null ? 3 : 1;
923
+ //HEATING
924
+ if (zoneState.sensorDataPoints.insideTemperature) {
925
+ currentTemp =
926
+ config.temperatureUnit === 'FAHRENHEIT'
927
+ ? zoneState.sensorDataPoints.insideTemperature.fahrenheit
928
+ : zoneState.sensorDataPoints.insideTemperature.celsius;
947
929
 
948
- active = 1;
949
- } else {
950
- //heating is switched off
951
- currentState = 0;
952
- targetState = 0;
953
- active = 0;
954
- }
930
+ if (zoneState.setting.power === 'ON') {
931
+ targetTemp =
932
+ config.temperatureUnit === 'FAHRENHEIT'
933
+ ? zoneState.setting.temperature.fahrenheit
934
+ : zoneState.setting.temperature.celsius;
955
935
 
956
- if (targetState === undefined && zoneState.overlayType === null) {
957
- targetState = 3;
958
- }
959
- }
936
+ tempEqual = Math.round(currentTemp) === Math.round(targetTemp);
960
937
 
961
- //Thermostat/HeaterCooler
962
- const thermoAccessory = accessories.filter(
963
- (acc) =>
964
- acc &&
965
- (acc.context.config.subtype === 'zone-thermostat' ||
966
- acc.context.config.subtype === 'zone-heatercooler' ||
967
- acc.context.config.subtype === 'zone-heatercooler-ac')
968
- );
938
+ //show as currently heating if current temp is lower than target temp, otherwise show as temp set
939
+ currentState = currentTemp < targetTemp ? 1 : 0;
969
940
 
970
- if (thermoAccessory.length) {
971
- thermoAccessory.forEach((acc) => {
972
- if (acc.displayName.includes(zone.name)) {
973
- let serviceThermostat = acc.getService(api.hap.Service.Thermostat);
974
- let serviceHeaterCooler = acc.getService(api.hap.Service.HeaterCooler);
941
+ //check if auto mode is enabled
942
+ targetState = zoneState.overlayType === null ? 3 : 1;
975
943
 
976
- let serviceBattery = acc.getService(api.hap.Service.BatteryService);
977
- let characteristicBattery = api.hap.Characteristic.BatteryLevel;
944
+ active = 1;
945
+ } else {
946
+ //heating is switched off
947
+ currentState = 0;
948
+ targetState = 0;
949
+ active = 0;
950
+ }
978
951
 
979
- if (serviceBattery && zone.battery) {
980
- serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
981
- }
952
+ if (targetState === undefined && zoneState.overlayType === null) {
953
+ targetState = 3;
954
+ }
955
+ }
982
956
 
983
- if (serviceThermostat) {
984
- let characteristicCurrentTemp = api.hap.Characteristic.CurrentTemperature;
985
- let characteristicTargetTemp = api.hap.Characteristic.TargetTemperature;
986
- let characteristicCurrentState = api.hap.Characteristic.CurrentHeatingCoolingState;
987
- let characteristicTargetState = api.hap.Characteristic.TargetHeatingCoolingState;
988
- let characteristicHumidity = api.hap.Characteristic.CurrentRelativeHumidity;
989
- let characteristicUnit = api.hap.Characteristic.TemperatureDisplayUnits;
957
+ //Thermostat/HeaterCooler
958
+ const thermoAccessory = accessories.filter(
959
+ (acc) =>
960
+ acc &&
961
+ (acc.context.config.subtype === 'zone-thermostat' ||
962
+ acc.context.config.subtype === 'zone-heatercooler' ||
963
+ acc.context.config.subtype === 'zone-heatercooler-ac')
964
+ );
990
965
 
991
- if (!isNaN(currentTemp)) {
992
- acc.context.config.temperatureUnit = acc.context.config.temperatureUnit || config.temperatureUnit;
966
+ if (thermoAccessory.length) {
967
+ thermoAccessory.forEach((acc) => {
968
+ if (acc.displayName.includes(zone.name)) {
969
+ let serviceThermostat = acc.getService(api.hap.Service.Thermostat);
970
+ let serviceHeaterCooler = acc.getService(api.hap.Service.HeaterCooler);
993
971
 
994
- let isFahrenheit = serviceThermostat.getCharacteristic(characteristicUnit).value === 1;
995
- let unitChanged = config.temperatureUnit !== acc.context.config.temperatureUnit;
972
+ let serviceBattery = acc.getService(api.hap.Service.BatteryService);
973
+ let characteristicBattery = api.hap.Characteristic.BatteryLevel;
996
974
 
997
- let cToF = (c) => Math.round((c * 9) / 5 + 32);
998
- let fToC = (f) => Math.round(((f - 32) * 5) / 9);
975
+ if (serviceBattery && zone.battery) {
976
+ serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
977
+ }
999
978
 
1000
- let newValue = unitChanged ? (isFahrenheit ? cToF(currentTemp) : fToC(currentTemp)) : currentTemp;
979
+ if (serviceThermostat) {
980
+ let characteristicCurrentTemp = api.hap.Characteristic.CurrentTemperature;
981
+ let characteristicTargetTemp = api.hap.Characteristic.TargetTemperature;
982
+ let characteristicCurrentState = api.hap.Characteristic.CurrentHeatingCoolingState;
983
+ let characteristicTargetState = api.hap.Characteristic.TargetHeatingCoolingState;
984
+ let characteristicHumidity = api.hap.Characteristic.CurrentRelativeHumidity;
985
+ let characteristicUnit = api.hap.Characteristic.TemperatureDisplayUnits;
1001
986
 
1002
- serviceThermostat.getCharacteristic(characteristicCurrentTemp).updateValue(newValue);
1003
- }
987
+ if (!isNaN(currentTemp)) {
988
+ acc.context.config.temperatureUnit = acc.context.config.temperatureUnit || config.temperatureUnit;
1004
989
 
1005
- if (!isNaN(targetTemp))
1006
- serviceThermostat.getCharacteristic(characteristicTargetTemp).updateValue(targetTemp);
990
+ let isFahrenheit = serviceThermostat.getCharacteristic(characteristicUnit).value === 1;
991
+ let unitChanged = config.temperatureUnit !== acc.context.config.temperatureUnit;
1007
992
 
1008
- if (!isNaN(currentState))
1009
- serviceThermostat.getCharacteristic(characteristicCurrentState).updateValue(currentState);
993
+ let cToF = (c) => Math.round((c * 9) / 5 + 32);
994
+ let fToC = (f) => Math.round(((f - 32) * 5) / 9);
1010
995
 
1011
- if (!isNaN(targetState))
1012
- serviceThermostat.getCharacteristic(characteristicTargetState).updateValue(targetState);
996
+ let newValue = unitChanged ? (isFahrenheit ? cToF(currentTemp) : fToC(currentTemp)) : currentTemp;
1013
997
 
1014
- if (!isNaN(humidity) && serviceThermostat.testCharacteristic(characteristicHumidity))
1015
- serviceThermostat.getCharacteristic(characteristicHumidity).updateValue(humidity);
998
+ serviceThermostat.getCharacteristic(characteristicCurrentTemp).updateValue(newValue);
1016
999
  }
1017
1000
 
1018
- if (serviceHeaterCooler) {
1019
- let characteristicHumidity = api.hap.Characteristic.CurrentRelativeHumidity;
1020
- let characteristicCurrentTemp = api.hap.Characteristic.CurrentTemperature;
1021
- let characteristicTargetTempHeating = api.hap.Characteristic.HeatingThresholdTemperature;
1022
- let characteristicTargetTempCooling = api.hap.Characteristic.CoolingThresholdTemperature;
1023
- let characteristicCurrentState = api.hap.Characteristic.CurrentHeaterCoolerState;
1024
- let characteristicTargetState = api.hap.Characteristic.TargetHeaterCoolerState;
1025
- let characteristicActive = api.hap.Characteristic.Active;
1001
+ if (!isNaN(targetTemp))
1002
+ serviceThermostat.getCharacteristic(characteristicTargetTemp).updateValue(targetTemp);
1026
1003
 
1027
- currentState = active ? (targetState === 3 || tempEqual ? 1 : currentState + 1) : 0;
1004
+ if (!isNaN(currentState))
1005
+ serviceThermostat.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1028
1006
 
1029
- targetState = 1;
1007
+ if (!isNaN(targetState))
1008
+ serviceThermostat.getCharacteristic(characteristicTargetState).updateValue(targetState);
1030
1009
 
1031
- if (!isNaN(active)) serviceHeaterCooler.getCharacteristic(characteristicActive).updateValue(active);
1010
+ if (!isNaN(humidity) && serviceThermostat.testCharacteristic(characteristicHumidity))
1011
+ serviceThermostat.getCharacteristic(characteristicHumidity).updateValue(humidity);
1012
+ }
1032
1013
 
1033
- if (!isNaN(currentTemp))
1034
- serviceHeaterCooler.getCharacteristic(characteristicCurrentTemp).updateValue(currentTemp);
1014
+ if (serviceHeaterCooler) {
1015
+ let characteristicHumidity = api.hap.Characteristic.CurrentRelativeHumidity;
1016
+ let characteristicCurrentTemp = api.hap.Characteristic.CurrentTemperature;
1017
+ let characteristicTargetTempHeating = api.hap.Characteristic.HeatingThresholdTemperature;
1018
+ let characteristicTargetTempCooling = api.hap.Characteristic.CoolingThresholdTemperature;
1019
+ let characteristicCurrentState = api.hap.Characteristic.CurrentHeaterCoolerState;
1020
+ let characteristicTargetState = api.hap.Characteristic.TargetHeaterCoolerState;
1021
+ let characteristicActive = api.hap.Characteristic.Active;
1035
1022
 
1036
- if (!isNaN(targetTemp)) {
1037
- serviceHeaterCooler.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1023
+ currentState = active ? (targetState === 3 || tempEqual ? 1 : currentState + 1) : 0;
1038
1024
 
1039
- serviceHeaterCooler.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1040
- }
1025
+ targetState = 1;
1041
1026
 
1042
- if (!isNaN(currentState))
1043
- serviceHeaterCooler.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1027
+ if (!isNaN(active)) serviceHeaterCooler.getCharacteristic(characteristicActive).updateValue(active);
1044
1028
 
1045
- if (!isNaN(targetState))
1046
- serviceHeaterCooler.getCharacteristic(characteristicTargetState).updateValue(targetState);
1029
+ if (!isNaN(currentTemp))
1030
+ serviceHeaterCooler.getCharacteristic(characteristicCurrentTemp).updateValue(currentTemp);
1047
1031
 
1048
- if (!isNaN(humidity) && serviceHeaterCooler.testCharacteristic(characteristicHumidity))
1049
- serviceHeaterCooler.getCharacteristic(characteristicHumidity).updateValue(humidity);
1050
- }
1051
- }
1052
- });
1053
- }
1054
- } else {
1055
- // Non-HEATING zones (AIR_CONDITIONING, HOT_WATER, etc.)
1056
- battery = zone.battery === 'NORMAL' ? 100 : 10;
1032
+ if (!isNaN(targetTemp)) {
1033
+ serviceHeaterCooler.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1057
1034
 
1058
- if (zoneState.sensorDataPoints.humidity) {
1059
- humidity = zoneState.sensorDataPoints.humidity.percentage;
1060
- }
1035
+ serviceHeaterCooler.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1036
+ }
1061
1037
 
1062
- // Get current temperature from sensor data (same as HEATING zones)
1063
- if (zoneState.sensorDataPoints.insideTemperature) {
1064
- currentTemp =
1065
- config.temperatureUnit === 'FAHRENHEIT'
1066
- ? zoneState.sensorDataPoints.insideTemperature.fahrenheit
1067
- : zoneState.sensorDataPoints.insideTemperature.celsius;
1068
- }
1038
+ if (!isNaN(currentState))
1039
+ serviceHeaterCooler.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1069
1040
 
1070
- if (zoneState.setting.power === 'ON') {
1071
- active = 1;
1041
+ if (!isNaN(targetState))
1042
+ serviceHeaterCooler.getCharacteristic(characteristicTargetState).updateValue(targetState);
1072
1043
 
1073
- // Get target temperature from setting
1074
- targetTemp =
1075
- zoneState.setting.temperature !== null && zoneState.setting.temperature
1076
- ? config.temperatureUnit === 'FAHRENHEIT'
1077
- ? zoneState.setting.temperature.fahrenheit
1078
- : zoneState.setting.temperature.celsius
1079
- : undefined;
1080
-
1081
- // Enhanced AC state handling
1082
- if (zone.type === 'AIR_CONDITIONING') {
1083
- const acMode = zoneState.setting.mode || 'COOL';
1084
- tempEqual = currentTemp && targetTemp ? Math.abs(currentTemp - targetTemp) < 0.5 : false;
1085
-
1086
- // Map AC modes to HomeKit states
1087
- switch (acMode.toUpperCase()) {
1088
- case 'HEAT':
1089
- targetState = 1; // Heating
1090
- currentState = tempEqual ? 1 : (currentTemp < targetTemp ? 2 : 1); // Idle or Heating
1091
- break;
1092
- case 'COOL':
1093
- case 'AUTO':
1094
- default:
1095
- targetState = 2; // Cooling
1096
- currentState = tempEqual ? 1 : (currentTemp > targetTemp ? 3 : 1); // Idle or Cooling
1097
- break;
1044
+ if (!isNaN(humidity) && serviceHeaterCooler.testCharacteristic(characteristicHumidity))
1045
+ serviceHeaterCooler.getCharacteristic(characteristicHumidity).updateValue(humidity);
1098
1046
  }
1099
- } else {
1100
- // Non-AC zones (HOT_WATER, etc.)
1101
- currentState = zoneState.overlayType === null ? 1 : 2;
1102
- targetState = 1;
1103
1047
  }
1104
- } else {
1105
- active = 0;
1106
- currentState = 0;
1107
- targetTemp = undefined;
1108
- targetState = zone.type === 'AIR_CONDITIONING' ? 2 : 1; // Default to cooling for AC, heating for others
1109
- }
1048
+ });
1049
+ }
1050
+ } else {
1051
+ // Non-HEATING zones (AIR_CONDITIONING, HOT_WATER, etc.)
1052
+ battery = zone.battery === 'NORMAL' ? 100 : 10;
1110
1053
 
1111
- //Thermostat/HeaterCooler
1112
- const heaterAccessory = accessories.filter(
1113
- (acc) => acc && (acc.context.config.subtype === 'zone-heatercooler-boiler' ||
1114
- acc.context.config.subtype === 'zone-heatercooler-ac')
1115
- );
1116
- const switchAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-switch');
1117
- const faucetAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-faucet');
1054
+ if (zoneState.sensorDataPoints.humidity) {
1055
+ humidity = zoneState.sensorDataPoints.humidity.percentage;
1056
+ }
1118
1057
 
1119
- if (heaterAccessory.length) {
1120
- heaterAccessory.forEach((acc) => {
1121
- if (acc.displayName.includes(zone.name)) {
1122
- let service = acc.getService(api.hap.Service.HeaterCooler);
1058
+ // Get current temperature from sensor data (same as HEATING zones)
1059
+ if (zoneState.sensorDataPoints.insideTemperature) {
1060
+ currentTemp =
1061
+ config.temperatureUnit === 'FAHRENHEIT'
1062
+ ? zoneState.sensorDataPoints.insideTemperature.fahrenheit
1063
+ : zoneState.sensorDataPoints.insideTemperature.celsius;
1064
+ }
1123
1065
 
1124
- let characteristicCurrentTemp = api.hap.Characteristic.CurrentTemperature;
1125
- let characteristicActive = api.hap.Characteristic.Active;
1126
- let characteristicCurrentState = api.hap.Characteristic.CurrentHeaterCoolerState;
1127
- let characteristicTargetState = api.hap.Characteristic.TargetHeaterCoolerState;
1128
- let characteristicTargetTempHeating = api.hap.Characteristic.HeatingThresholdTemperature;
1129
- let characteristicTargetTempCooling = api.hap.Characteristic.CoolingThresholdTemperature;
1066
+ if (zoneState.setting.power === 'ON') {
1067
+ active = 1;
1068
+
1069
+ // Get target temperature from setting
1070
+ targetTemp =
1071
+ zoneState.setting.temperature !== null && zoneState.setting.temperature
1072
+ ? config.temperatureUnit === 'FAHRENHEIT'
1073
+ ? zoneState.setting.temperature.fahrenheit
1074
+ : zoneState.setting.temperature.celsius
1075
+ : undefined;
1076
+
1077
+ // Enhanced AC state handling
1078
+ if (zone.type === 'AIR_CONDITIONING') {
1079
+ const acMode = zoneState.setting.mode || 'COOL';
1080
+ tempEqual = currentTemp && targetTemp ? Math.abs(currentTemp - targetTemp) < 0.5 : false;
1081
+
1082
+ // Map AC modes to HomeKit states
1083
+ switch (acMode.toUpperCase()) {
1084
+ case 'HEAT':
1085
+ targetState = 1; // Heating
1086
+ currentState = tempEqual ? 1 : (currentTemp < targetTemp ? 2 : 1); // Idle or Heating
1087
+ break;
1088
+ case 'COOL':
1089
+ case 'AUTO':
1090
+ default:
1091
+ targetState = 2; // Cooling
1092
+ currentState = tempEqual ? 1 : (currentTemp > targetTemp ? 3 : 1); // Idle or Cooling
1093
+ break;
1094
+ }
1095
+ } else {
1096
+ // Non-AC zones (HOT_WATER, etc.)
1097
+ currentState = zoneState.overlayType === null ? 1 : 2;
1098
+ targetState = 1;
1099
+ }
1100
+ } else {
1101
+ active = 0;
1102
+ currentState = 0;
1103
+ targetTemp = undefined;
1104
+ targetState = zone.type === 'AIR_CONDITIONING' ? 2 : 1; // Default to cooling for AC, heating for others
1105
+ }
1130
1106
 
1131
- service.getCharacteristic(characteristicActive).updateValue(active);
1107
+ //Thermostat/HeaterCooler
1108
+ const heaterAccessory = accessories.filter(
1109
+ (acc) => acc && (acc.context.config.subtype === 'zone-heatercooler-boiler' ||
1110
+ acc.context.config.subtype === 'zone-heatercooler-ac')
1111
+ );
1112
+ const switchAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-switch');
1113
+ const faucetAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-faucet');
1132
1114
 
1133
- service.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1115
+ if (heaterAccessory.length) {
1116
+ heaterAccessory.forEach((acc) => {
1117
+ if (acc.displayName.includes(zone.name)) {
1118
+ let service = acc.getService(api.hap.Service.HeaterCooler);
1134
1119
 
1135
- service.getCharacteristic(characteristicTargetState).updateValue(targetState);
1120
+ let characteristicCurrentTemp = api.hap.Characteristic.CurrentTemperature;
1121
+ let characteristicActive = api.hap.Characteristic.Active;
1122
+ let characteristicCurrentState = api.hap.Characteristic.CurrentHeaterCoolerState;
1123
+ let characteristicTargetState = api.hap.Characteristic.TargetHeaterCoolerState;
1124
+ let characteristicTargetTempHeating = api.hap.Characteristic.HeatingThresholdTemperature;
1125
+ let characteristicTargetTempCooling = api.hap.Characteristic.CoolingThresholdTemperature;
1136
1126
 
1137
- // Set current temperature from sensor data
1138
- if (!isNaN(currentTemp) || acc.context.currentTemp) {
1139
- if (!isNaN(currentTemp)) acc.context.currentTemp = currentTemp; //store current temp in config
1127
+ service.getCharacteristic(characteristicActive).updateValue(active);
1140
1128
 
1141
- service.getCharacteristic(characteristicCurrentTemp).updateValue(acc.context.currentTemp);
1142
- }
1129
+ service.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1143
1130
 
1144
- // Set target temperature for both heating and cooling
1145
- if (!isNaN(targetTemp)) {
1146
- // For AC zones, set temperature based on the mode
1147
- if (zone.type === 'AIR_CONDITIONING') {
1148
- // Always set both characteristics but log which one is active
1149
- service.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1150
- service.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1151
- } else {
1152
- // Non-AC zones (like boiler/hot water)
1153
- service.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1154
- service.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1155
- }
1156
- }
1131
+ service.getCharacteristic(characteristicTargetState).updateValue(targetState);
1157
1132
 
1158
- // Fan speed polling removed for AIR_CONDITIONING zones
1133
+ // Set current temperature from sensor data
1134
+ if (!isNaN(currentTemp) || acc.context.currentTemp) {
1135
+ if (!isNaN(currentTemp)) acc.context.currentTemp = currentTemp; //store current temp in config
1159
1136
 
1160
- // Update humidity for all zones that support it
1161
- if (!isNaN(humidity) && service.testCharacteristic(api.hap.Characteristic.CurrentRelativeHumidity)) {
1162
- service.getCharacteristic(api.hap.Characteristic.CurrentRelativeHumidity).updateValue(humidity);
1163
- }
1137
+ service.getCharacteristic(characteristicCurrentTemp).updateValue(acc.context.currentTemp);
1164
1138
  }
1165
- });
1166
- }
1167
1139
 
1168
- if (switchAccessory.length) {
1169
- switchAccessory.forEach((acc) => {
1170
- if (acc.displayName.includes(zone.name)) {
1171
- let service = acc.getService(api.hap.Service.Switch);
1140
+ // Set target temperature for both heating and cooling
1141
+ if (!isNaN(targetTemp)) {
1142
+ // For AC zones, set temperature based on the mode
1143
+ if (zone.type === 'AIR_CONDITIONING') {
1144
+ // Always set both characteristics but log which one is active
1145
+ service.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1146
+ service.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1147
+ } else {
1148
+ // Non-AC zones (like boiler/hot water)
1149
+ service.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1150
+ service.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1151
+ }
1152
+ }
1172
1153
 
1173
- let characteristic = api.hap.Characteristic.On;
1154
+ // Fan speed polling removed for AIR_CONDITIONING zones
1174
1155
 
1175
- service.getCharacteristic(characteristic).updateValue(active ? true : false);
1156
+ // Update humidity for all zones that support it
1157
+ if (!isNaN(humidity) && service.testCharacteristic(api.hap.Characteristic.CurrentRelativeHumidity)) {
1158
+ service.getCharacteristic(api.hap.Characteristic.CurrentRelativeHumidity).updateValue(humidity);
1176
1159
  }
1177
- });
1178
- }
1179
-
1180
- if (faucetAccessory.length) {
1181
- faucetAccessory.forEach((acc) => {
1182
- if (acc.displayName.includes(zone.name)) {
1183
- let service = acc.getService(api.hap.Service.Valve);
1160
+ }
1161
+ });
1162
+ }
1184
1163
 
1185
- let characteristicActive = api.hap.Characteristic.Active;
1186
- let characteristicInUse = api.hap.Characteristic.InUse;
1164
+ if (switchAccessory.length) {
1165
+ switchAccessory.forEach((acc) => {
1166
+ if (acc.displayName.includes(zone.name)) {
1167
+ let service = acc.getService(api.hap.Service.Switch);
1187
1168
 
1188
- service.getCharacteristic(characteristicActive).updateValue(active ? 1 : 0);
1169
+ let characteristic = api.hap.Characteristic.On;
1189
1170
 
1190
- service.getCharacteristic(characteristicInUse).updateValue(active ? 1 : 0);
1191
- }
1192
- });
1193
- }
1171
+ service.getCharacteristic(characteristic).updateValue(active ? true : false);
1172
+ }
1173
+ });
1194
1174
  }
1195
1175
 
1196
- //TemperatureSensor
1197
- const tempAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-temperature');
1198
-
1199
- if (tempAccessory.length) {
1200
- tempAccessory.forEach((acc) => {
1176
+ if (faucetAccessory.length) {
1177
+ faucetAccessory.forEach((acc) => {
1201
1178
  if (acc.displayName.includes(zone.name)) {
1202
- let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1203
- let characteristicBattery = api.hap.Characteristic.BatteryLevel;
1179
+ let service = acc.getService(api.hap.Service.Valve);
1204
1180
 
1205
- if (serviceBattery && !isNaN(battery)) {
1206
- serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1207
- }
1181
+ let characteristicActive = api.hap.Characteristic.Active;
1182
+ let characteristicInUse = api.hap.Characteristic.InUse;
1208
1183
 
1209
- if (!isNaN(currentTemp)) {
1210
- let service = acc.getService(api.hap.Service.TemperatureSensor);
1211
- let characteristic = api.hap.Characteristic.CurrentTemperature;
1184
+ service.getCharacteristic(characteristicActive).updateValue(active ? 1 : 0);
1212
1185
 
1213
- service.getCharacteristic(characteristic).updateValue(currentTemp);
1214
- }
1186
+ service.getCharacteristic(characteristicInUse).updateValue(active ? 1 : 0);
1215
1187
  }
1216
1188
  });
1217
1189
  }
1190
+ }
1218
1191
 
1219
- //HumiditySensor
1220
- const humidityAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-humidity');
1192
+ //TemperatureSensor
1193
+ const tempAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-temperature');
1221
1194
 
1222
- humidityAccessory.forEach((acc) => {
1195
+ if (tempAccessory.length) {
1196
+ tempAccessory.forEach((acc) => {
1223
1197
  if (acc.displayName.includes(zone.name)) {
1224
1198
  let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1225
1199
  let characteristicBattery = api.hap.Characteristic.BatteryLevel;
@@ -1228,327 +1202,340 @@ export default (api, accessories, config, tado, telegram) => {
1228
1202
  serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1229
1203
  }
1230
1204
 
1231
- if (!isNaN(humidity)) {
1232
- let service = acc.getService(api.hap.Service.HumiditySensor);
1233
- let characteristic = api.hap.Characteristic.CurrentRelativeHumidity;
1205
+ if (!isNaN(currentTemp)) {
1206
+ let service = acc.getService(api.hap.Service.TemperatureSensor);
1207
+ let characteristic = api.hap.Characteristic.CurrentTemperature;
1234
1208
 
1235
- service.getCharacteristic(characteristic).updateValue(humidity);
1209
+ service.getCharacteristic(characteristic).updateValue(currentTemp);
1236
1210
  }
1237
1211
  }
1238
1212
  });
1213
+ }
1239
1214
 
1240
- //WindowSensor
1241
- const windowContactAccessory = accessories.filter(
1242
- (acc) => acc && acc.context.config.subtype === 'zone-window-contact'
1243
- );
1244
- const windowSwitchAccessory = accessories.filter(
1245
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Open Window'
1246
- );
1247
-
1248
- if (windowContactAccessory.length) {
1249
- windowContactAccessory.forEach((acc) => {
1250
- if (acc.displayName.includes(zone.name)) {
1251
- let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1252
- let characteristicBattery = api.hap.Characteristic.BatteryLevel;
1215
+ //HumiditySensor
1216
+ const humidityAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-humidity');
1253
1217
 
1254
- if (serviceBattery && !isNaN(battery)) {
1255
- serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1256
- }
1218
+ humidityAccessory.forEach((acc) => {
1219
+ if (acc.displayName.includes(zone.name)) {
1220
+ let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1221
+ let characteristicBattery = api.hap.Characteristic.BatteryLevel;
1257
1222
 
1258
- let service = acc.getService(api.hap.Service.ContactSensor);
1259
- let characteristic = api.hap.Characteristic.ContactSensorState;
1223
+ if (serviceBattery && !isNaN(battery)) {
1224
+ serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1225
+ }
1260
1226
 
1261
- let state = zoneState.openWindow || zoneState.openWindowDetected ? 1 : 0;
1227
+ if (!isNaN(humidity)) {
1228
+ let service = acc.getService(api.hap.Service.HumiditySensor);
1229
+ let characteristic = api.hap.Characteristic.CurrentRelativeHumidity;
1262
1230
 
1263
- service.getCharacteristic(characteristic).updateValue(state);
1264
- }
1265
- });
1231
+ service.getCharacteristic(characteristic).updateValue(humidity);
1232
+ }
1266
1233
  }
1234
+ });
1267
1235
 
1268
- if (windowSwitchAccessory.length) {
1269
- windowSwitchAccessory[0].services.forEach((switchService) => {
1270
- if (switchService.subtype && switchService.subtype.includes(zone.name)) {
1271
- let service = windowSwitchAccessory[0].getServiceById(api.hap.Service.Switch, switchService.subtype);
1272
- let characteristic = api.hap.Characteristic.On;
1236
+ //WindowSensor
1237
+ const windowContactAccessory = accessories.filter(
1238
+ (acc) => acc && acc.context.config.subtype === 'zone-window-contact'
1239
+ );
1240
+ const windowSwitchAccessory = accessories.filter(
1241
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Open Window'
1242
+ );
1273
1243
 
1274
- let state = zone.openWindowEnabled ? true : false;
1244
+ if (windowContactAccessory.length) {
1245
+ windowContactAccessory.forEach((acc) => {
1246
+ if (acc.displayName.includes(zone.name)) {
1247
+ let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1248
+ let characteristicBattery = api.hap.Characteristic.BatteryLevel;
1275
1249
 
1276
- service.getCharacteristic(characteristic).updateValue(state);
1250
+ if (serviceBattery && !isNaN(battery)) {
1251
+ serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1277
1252
  }
1278
- });
1279
- }
1280
1253
 
1281
- if (zoneState.setting.type === 'HEATING') {
1282
- //CentralSwitch
1283
- if (zoneState.overlayType === null) inAutoMode += 1;
1254
+ let service = acc.getService(api.hap.Service.ContactSensor);
1255
+ let characteristic = api.hap.Characteristic.ContactSensorState;
1284
1256
 
1285
- if (zoneState.overlayType !== null && zoneState.setting.power === 'OFF') inOffMode += 1;
1257
+ let state = zoneState.openWindow || zoneState.openWindowDetected ? 1 : 0;
1286
1258
 
1287
- if (zoneState.overlayType !== null && zoneState.setting.power === 'ON' && zoneState.overlay.termination)
1288
- inManualMode += 1;
1289
- }
1259
+ service.getCharacteristic(characteristic).updateValue(state);
1260
+ }
1261
+ });
1290
1262
  }
1291
1263
 
1292
- //CentralSwitch
1293
- const centralSwitchAccessory = accessories.filter(
1294
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Central Switch'
1295
- );
1296
-
1297
- if (centralSwitchAccessory.length) {
1298
- centralSwitchAccessory[0].services.forEach((service) => {
1299
- if (service.subtype === 'Central') {
1300
- let serviceSwitch = centralSwitchAccessory[0].getServiceById(api.hap.Service.Switch, service.subtype);
1301
- let characteristicOn = api.hap.Characteristic.On;
1302
- let characteristicAuto = api.hap.Characteristic.AutoThermostats;
1303
- let characteristicOff = api.hap.Characteristic.OfflineThermostats;
1304
- let characteristicManual = api.hap.Characteristic.ManualThermostats;
1264
+ if (windowSwitchAccessory.length) {
1265
+ windowSwitchAccessory[0].services.forEach((switchService) => {
1266
+ if (switchService.subtype && switchService.subtype.includes(zone.name)) {
1267
+ let service = windowSwitchAccessory[0].getServiceById(api.hap.Service.Switch, switchService.subtype);
1268
+ let characteristic = api.hap.Characteristic.On;
1305
1269
 
1306
- let state = (inManualMode || inAutoMode) !== 0;
1270
+ let state = zone.openWindowEnabled ? true : false;
1307
1271
 
1308
- serviceSwitch.getCharacteristic(characteristicAuto).updateValue(inAutoMode);
1272
+ service.getCharacteristic(characteristic).updateValue(state);
1273
+ }
1274
+ });
1275
+ }
1309
1276
 
1310
- serviceSwitch.getCharacteristic(characteristicManual).updateValue(inManualMode);
1277
+ if (zoneState.setting.type === 'HEATING') {
1278
+ //CentralSwitch
1279
+ if (zoneState.overlayType === null) inAutoMode += 1;
1311
1280
 
1312
- serviceSwitch.getCharacteristic(characteristicOff).updateValue(inOffMode);
1281
+ if (zoneState.overlayType !== null && zoneState.setting.power === 'OFF') inOffMode += 1;
1313
1282
 
1314
- serviceSwitch.getCharacteristic(characteristicOn).updateValue(state);
1315
- }
1316
- });
1283
+ if (zoneState.overlayType !== null && zoneState.setting.power === 'ON' && zoneState.overlay.termination)
1284
+ inManualMode += 1;
1317
1285
  }
1318
1286
  }
1287
+
1288
+ //CentralSwitch
1289
+ const centralSwitchAccessory = accessories.filter(
1290
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Central Switch'
1291
+ );
1292
+
1293
+ if (centralSwitchAccessory.length) {
1294
+ centralSwitchAccessory[0].services.forEach((service) => {
1295
+ if (service.subtype === 'Central') {
1296
+ let serviceSwitch = centralSwitchAccessory[0].getServiceById(api.hap.Service.Switch, service.subtype);
1297
+ let characteristicOn = api.hap.Characteristic.On;
1298
+ let characteristicAuto = api.hap.Characteristic.AutoThermostats;
1299
+ let characteristicOff = api.hap.Characteristic.OfflineThermostats;
1300
+ let characteristicManual = api.hap.Characteristic.ManualThermostats;
1301
+
1302
+ let state = (inManualMode || inAutoMode) !== 0;
1303
+
1304
+ serviceSwitch.getCharacteristic(characteristicAuto).updateValue(inAutoMode);
1305
+
1306
+ serviceSwitch.getCharacteristic(characteristicManual).updateValue(inManualMode);
1307
+
1308
+ serviceSwitch.getCharacteristic(characteristicOff).updateValue(inOffMode);
1309
+
1310
+ serviceSwitch.getCharacteristic(characteristicOn).updateValue(state);
1311
+ }
1312
+ });
1313
+ }
1319
1314
  return zoneStates;
1320
1315
  }
1321
1316
 
1322
1317
  async function updateMobileDevices() {
1323
- if (!settingState) {
1324
- Logger.debug('Polling MobileDevices...', config.homeName);
1318
+ if (settingState) return;
1325
1319
 
1326
- const mobileDevices = await tado.getMobileDevices(config.homeId);
1320
+ Logger.debug('Polling MobileDevices...', config.homeName);
1327
1321
 
1328
- const userAccessories = accessories.filter(
1329
- (user) =>
1330
- user &&
1331
- user.context.config.subtype.includes('presence') &&
1332
- user.displayName !== user.context.config.homeName + ' Anyone'
1333
- );
1322
+ const mobileDevices = await tado.getMobileDevices(config.homeId);
1334
1323
 
1335
- const anyone = accessories.filter(
1336
- (user) =>
1337
- user &&
1338
- user.context.config.subtype.includes('presence') &&
1339
- user.displayName === user.context.config.homeName + ' Anyone'
1340
- );
1324
+ const userAccessories = accessories.filter(
1325
+ (user) =>
1326
+ user &&
1327
+ user.context.config.subtype.includes('presence') &&
1328
+ user.displayName !== user.context.config.homeName + ' Anyone'
1329
+ );
1341
1330
 
1342
- let activeUser = 0;
1331
+ const anyone = accessories.filter(
1332
+ (user) =>
1333
+ user &&
1334
+ user.context.config.subtype.includes('presence') &&
1335
+ user.displayName === user.context.config.homeName + ' Anyone'
1336
+ );
1343
1337
 
1344
- mobileDevices.forEach((device) => {
1345
- userAccessories.forEach((acc) => {
1346
- if (acc.context.config.homeName + ' ' + device.name === acc.displayName) {
1347
- let atHome = device.location && device.location.atHome ? 1 : 0;
1338
+ let activeUser = 0;
1348
1339
 
1349
- if (atHome) activeUser += 1;
1340
+ mobileDevices.forEach((device) => {
1341
+ userAccessories.forEach((acc) => {
1342
+ if (acc.context.config.homeName + ' ' + device.name === acc.displayName) {
1343
+ let atHome = device.location && device.location.atHome ? 1 : 0;
1350
1344
 
1351
- let service =
1352
- acc.getService(api.hap.Service.MotionSensor) || acc.getService(api.hap.Service.OccupancySensor);
1345
+ if (atHome) activeUser += 1;
1353
1346
 
1354
- let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1355
- ? api.hap.Characteristic.MotionDetected
1356
- : api.hap.Characteristic.OccupancyDetected;
1347
+ let service =
1348
+ acc.getService(api.hap.Service.MotionSensor) || acc.getService(api.hap.Service.OccupancySensor);
1357
1349
 
1358
- service.getCharacteristic(characteristic).updateValue(atHome);
1359
- }
1360
- });
1350
+ let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1351
+ ? api.hap.Characteristic.MotionDetected
1352
+ : api.hap.Characteristic.OccupancyDetected;
1353
+
1354
+ service.getCharacteristic(characteristic).updateValue(atHome);
1355
+ }
1361
1356
  });
1357
+ });
1362
1358
 
1363
- if (anyone.length) {
1364
- let service =
1365
- anyone[0].getService(api.hap.Service.MotionSensor) || anyone[0].getService(api.hap.Service.OccupancySensor);
1359
+ if (anyone.length) {
1360
+ let service =
1361
+ anyone[0].getService(api.hap.Service.MotionSensor) || anyone[0].getService(api.hap.Service.OccupancySensor);
1366
1362
 
1367
- let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1368
- ? api.hap.Characteristic.MotionDetected
1369
- : api.hap.Characteristic.OccupancyDetected;
1363
+ let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1364
+ ? api.hap.Characteristic.MotionDetected
1365
+ : api.hap.Characteristic.OccupancyDetected;
1370
1366
 
1371
- service.getCharacteristic(characteristic).updateValue(activeUser ? 1 : 0);
1372
- }
1367
+ service.getCharacteristic(characteristic).updateValue(activeUser ? 1 : 0);
1373
1368
  }
1374
-
1375
- return;
1376
1369
  }
1377
1370
 
1378
1371
  async function updateWeather() {
1379
- if (!settingState) {
1380
- const weatherTemperatureAccessory = accessories.filter(
1381
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Weather'
1382
- );
1372
+ if (settingState) return;
1383
1373
 
1384
- const solarIntensityAccessory = accessories.filter(
1385
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Solar Intensity'
1386
- );
1374
+ const weatherTemperatureAccessory = accessories.filter(
1375
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Weather'
1376
+ );
1387
1377
 
1388
- if (weatherTemperatureAccessory.length || solarIntensityAccessory.length) {
1389
- Logger.debug('Polling Weather...', config.homeName);
1378
+ const solarIntensityAccessory = accessories.filter(
1379
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Solar Intensity'
1380
+ );
1390
1381
 
1391
- const weather = await tado.getWeather(config.homeId);
1382
+ if (weatherTemperatureAccessory.length || solarIntensityAccessory.length) {
1383
+ Logger.debug('Polling Weather...', config.homeName);
1392
1384
 
1393
- if (weatherTemperatureAccessory.length && weather.outsideTemperature) {
1394
- let tempUnit = config.temperatureUnit;
1395
- let service = weatherTemperatureAccessory[0].getService(api.hap.Service.TemperatureSensor);
1396
- let characteristic = api.hap.Characteristic.CurrentTemperature;
1385
+ const weather = await tado.getWeather(config.homeId);
1397
1386
 
1398
- let temp =
1399
- tempUnit === 'FAHRENHEIT' ? weather.outsideTemperature.fahrenheit : weather.outsideTemperature.celsius;
1387
+ if (weatherTemperatureAccessory.length && weather.outsideTemperature) {
1388
+ let tempUnit = config.temperatureUnit;
1389
+ let service = weatherTemperatureAccessory[0].getService(api.hap.Service.TemperatureSensor);
1390
+ let characteristic = api.hap.Characteristic.CurrentTemperature;
1400
1391
 
1401
- service.getCharacteristic(characteristic).updateValue(temp);
1402
- }
1392
+ let temp =
1393
+ tempUnit === 'FAHRENHEIT' ? weather.outsideTemperature.fahrenheit : weather.outsideTemperature.celsius;
1403
1394
 
1404
- if (solarIntensityAccessory.length && weather.solarIntensity) {
1405
- let state = weather.solarIntensity.percentage !== 0;
1406
- let brightness = weather.solarIntensity.percentage;
1395
+ service.getCharacteristic(characteristic).updateValue(temp);
1396
+ }
1407
1397
 
1408
- solarIntensityAccessory[0].context.lightBulbState = state;
1409
- solarIntensityAccessory[0].context.lightBulbBrightness = brightness;
1398
+ if (solarIntensityAccessory.length && weather.solarIntensity) {
1399
+ let state = weather.solarIntensity.percentage !== 0;
1400
+ let brightness = weather.solarIntensity.percentage;
1410
1401
 
1411
- let serviceLightbulb = solarIntensityAccessory[0].getService(api.hap.Service.Lightbulb);
1412
- let serviceLightsensor = solarIntensityAccessory[0].getService(api.hap.Service.LightSensor);
1402
+ solarIntensityAccessory[0].context.lightBulbState = state;
1403
+ solarIntensityAccessory[0].context.lightBulbBrightness = brightness;
1413
1404
 
1414
- if (serviceLightbulb) {
1415
- let characteristicOn = api.hap.Characteristic.On;
1416
- let characteristicBrightness = api.hap.Characteristic.Brightness;
1405
+ let serviceLightbulb = solarIntensityAccessory[0].getService(api.hap.Service.Lightbulb);
1406
+ let serviceLightsensor = solarIntensityAccessory[0].getService(api.hap.Service.LightSensor);
1417
1407
 
1418
- serviceLightbulb.getCharacteristic(characteristicOn).updateValue(state);
1408
+ if (serviceLightbulb) {
1409
+ let characteristicOn = api.hap.Characteristic.On;
1410
+ let characteristicBrightness = api.hap.Characteristic.Brightness;
1419
1411
 
1420
- serviceLightbulb.getCharacteristic(characteristicBrightness).updateValue(brightness);
1421
- } else {
1422
- let characteristicLux = api.hap.Characteristic.CurrentAmbientLightLevel;
1412
+ serviceLightbulb.getCharacteristic(characteristicOn).updateValue(state);
1423
1413
 
1424
- serviceLightsensor
1425
- .getCharacteristic(characteristicLux)
1426
- .updateValue(brightness ? brightness * 1000 : 0.0001);
1427
- }
1414
+ serviceLightbulb.getCharacteristic(characteristicBrightness).updateValue(brightness);
1415
+ } else {
1416
+ let characteristicLux = api.hap.Characteristic.CurrentAmbientLightLevel;
1417
+
1418
+ serviceLightsensor
1419
+ .getCharacteristic(characteristicLux)
1420
+ .updateValue(brightness ? brightness * 1000 : 0.0001);
1428
1421
  }
1429
1422
  }
1430
1423
  }
1431
-
1432
- return;
1433
1424
  }
1434
1425
 
1435
1426
  async function updatePresence() {
1436
- if (!settingState) {
1437
- const presenceLockAccessory = accessories.filter(
1438
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Presence Lock'
1439
- );
1427
+ if (settingState) return;
1440
1428
 
1441
- if (presenceLockAccessory.length) {
1442
- Logger.debug('Polling PresenceLock...', config.homeName);
1429
+ const presenceLockAccessory = accessories.filter(
1430
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Presence Lock'
1431
+ );
1443
1432
 
1444
- const presenceLock = await tado.getState(config.homeId);
1433
+ if (presenceLockAccessory.length) {
1434
+ Logger.debug('Polling PresenceLock...', config.homeName);
1445
1435
 
1446
- /*
1447
- 0: Home | true
1448
- 1: Away | true
1449
- 3: Off | false
1450
- */
1436
+ const presenceLock = await tado.getState(config.homeId);
1451
1437
 
1452
- let state = presenceLock.presenceLocked ? (presenceLock.presence === 'AWAY' ? 1 : 0) : 3;
1438
+ /*
1439
+ 0: Home | true
1440
+ 1: Away | true
1441
+ 3: Off | false
1442
+ */
1453
1443
 
1454
- let serviceSecurity = presenceLockAccessory[0].getService(api.hap.Service.SecuritySystem);
1455
- let serviceHomeSwitch = presenceLockAccessory[0].getServiceById(api.hap.Service.Switch, 'HomeSwitch');
1456
- let serviceAwaySwitch = presenceLockAccessory[0].getServiceById(api.hap.Service.Switch, 'AwaySwitch');
1444
+ let state = presenceLock.presenceLocked ? (presenceLock.presence === 'AWAY' ? 1 : 0) : 3;
1457
1445
 
1458
- if (serviceSecurity) {
1459
- let characteristicCurrent = api.hap.Characteristic.SecuritySystemCurrentState;
1460
- let characteristicTarget = api.hap.Characteristic.SecuritySystemTargetState;
1446
+ let serviceSecurity = presenceLockAccessory[0].getService(api.hap.Service.SecuritySystem);
1447
+ let serviceHomeSwitch = presenceLockAccessory[0].getServiceById(api.hap.Service.Switch, 'HomeSwitch');
1448
+ let serviceAwaySwitch = presenceLockAccessory[0].getServiceById(api.hap.Service.Switch, 'AwaySwitch');
1461
1449
 
1462
- serviceSecurity.getCharacteristic(characteristicCurrent).updateValue(state);
1450
+ if (serviceSecurity) {
1451
+ let characteristicCurrent = api.hap.Characteristic.SecuritySystemCurrentState;
1452
+ let characteristicTarget = api.hap.Characteristic.SecuritySystemTargetState;
1463
1453
 
1464
- serviceSecurity.getCharacteristic(characteristicTarget).updateValue(state);
1465
- } else if (serviceHomeSwitch || serviceAwaySwitch) {
1466
- let characteristicOn = api.hap.Characteristic.On;
1454
+ serviceSecurity.getCharacteristic(characteristicCurrent).updateValue(state);
1467
1455
 
1468
- let homeState = !state ? true : false;
1456
+ serviceSecurity.getCharacteristic(characteristicTarget).updateValue(state);
1457
+ } else if (serviceHomeSwitch || serviceAwaySwitch) {
1458
+ let characteristicOn = api.hap.Characteristic.On;
1469
1459
 
1470
- let awayState = state === 1 ? true : false;
1460
+ let homeState = !state ? true : false;
1471
1461
 
1472
- serviceAwaySwitch.getCharacteristic(characteristicOn).updateValue(awayState);
1462
+ let awayState = state === 1 ? true : false;
1473
1463
 
1474
- serviceHomeSwitch.getCharacteristic(characteristicOn).updateValue(homeState);
1475
- }
1464
+ serviceAwaySwitch.getCharacteristic(characteristicOn).updateValue(awayState);
1465
+
1466
+ serviceHomeSwitch.getCharacteristic(characteristicOn).updateValue(homeState);
1476
1467
  }
1477
1468
  }
1478
1469
  }
1479
1470
 
1480
1471
  async function updateRunningTime() {
1481
- if (!settingState) {
1482
- const centralSwitchAccessory = accessories.filter(
1483
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Central Switch'
1484
- );
1472
+ if (settingState) return;
1485
1473
 
1486
- if (centralSwitchAccessory.length) {
1487
- Logger.debug('Polling RunningTime...', config.homeName);
1474
+ const centralSwitchAccessory = accessories.filter(
1475
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Central Switch'
1476
+ );
1488
1477
 
1489
- let periods = ['days', 'months', 'years'];
1478
+ if (centralSwitchAccessory.length) {
1479
+ Logger.debug('Polling RunningTime...', config.homeName);
1490
1480
 
1491
- for (const period of periods) {
1492
- let fromDate =
1493
- period === 'days'
1494
- ? moment().format('YYYY-MM-DD')
1495
- : period === 'months'
1496
- ? moment().subtract(1, 'days').subtract(1, period).format('YYYY-MM-DD')
1497
- : moment().add(1, 'months').startOf('month').subtract(1, period).format('YYYY-MM-DD');
1481
+ let periods = ['days', 'months', 'years'];
1498
1482
 
1499
- let toDate = period === 'years' ? moment().format('YYYY-MM-DD') : false;
1483
+ for (const period of periods) {
1484
+ let fromDate =
1485
+ period === 'days'
1486
+ ? moment().format('YYYY-MM-DD')
1487
+ : period === 'months'
1488
+ ? moment().subtract(1, 'days').subtract(1, period).format('YYYY-MM-DD')
1489
+ : moment().add(1, 'months').startOf('month').subtract(1, period).format('YYYY-MM-DD');
1500
1490
 
1501
- let time = period.substring(0, period.length - 1);
1491
+ let toDate = period === 'years' ? moment().format('YYYY-MM-DD') : false;
1502
1492
 
1503
- const runningTime = await tado.getRunningTime(config.homeId, time, fromDate, toDate);
1493
+ let time = period.substring(0, period.length - 1);
1504
1494
 
1505
- if (runningTime && runningTime.summary) {
1506
- let summaryInHours = runningTime.summary.totalRunningTimeInSeconds / 3600;
1495
+ const runningTime = await tado.getRunningTime(config.homeId, time, fromDate, toDate);
1507
1496
 
1508
- let serviceSwitch = centralSwitchAccessory[0].getServiceById(api.hap.Service.Switch, 'Central');
1509
- let characteristic =
1510
- period === 'years'
1511
- ? api.hap.Characteristic.OverallHeatYear
1512
- : period === 'months'
1513
- ? api.hap.Characteristic.OverallHeatMonth
1514
- : api.hap.Characteristic.OverallHeatDay;
1497
+ if (runningTime && runningTime.summary) {
1498
+ let summaryInHours = runningTime.summary.totalRunningTimeInSeconds / 3600;
1515
1499
 
1516
- serviceSwitch.getCharacteristic(characteristic).updateValue(summaryInHours);
1517
- }
1500
+ let serviceSwitch = centralSwitchAccessory[0].getServiceById(api.hap.Service.Switch, 'Central');
1501
+ let characteristic =
1502
+ period === 'years'
1503
+ ? api.hap.Characteristic.OverallHeatYear
1504
+ : period === 'months'
1505
+ ? api.hap.Characteristic.OverallHeatMonth
1506
+ : api.hap.Characteristic.OverallHeatDay;
1518
1507
 
1519
- await timeout(500);
1508
+ serviceSwitch.getCharacteristic(characteristic).updateValue(summaryInHours);
1520
1509
  }
1510
+
1511
+ await timeout(500);
1521
1512
  }
1522
1513
  }
1523
-
1524
- return;
1525
1514
  }
1526
1515
 
1527
1516
  async function updateDevices() {
1528
- if (!settingState) {
1529
- Logger.debug('Polling Devices...', config.homeName);
1517
+ if (settingState) return;
1530
1518
 
1531
- const devices = await tado.getDevices(config.homeId);
1519
+ Logger.debug('Polling Devices...', config.homeName);
1532
1520
 
1533
- const childLockAccessories = accessories.filter(
1534
- (acc) => acc && acc.context.config.subtype === 'extra-childswitch'
1535
- );
1521
+ const devices = await tado.getDevices(config.homeId);
1536
1522
 
1537
- devices.forEach((device) => {
1538
- childLockAccessories[0].services.forEach((service) => {
1539
- if (device.serialNo === service.subtype) {
1540
- let serviceChildLock = childLockAccessories[0].getServiceById(api.hap.Service.Switch, service.subtype);
1541
- let characteristic = api.hap.Characteristic.On;
1523
+ const childLockAccessories = accessories.filter(
1524
+ (acc) => acc && acc.context.config.subtype === 'extra-childswitch'
1525
+ );
1542
1526
 
1543
- let childLockEnabled = device.childLockEnabled || false;
1527
+ devices.forEach((device) => {
1528
+ childLockAccessories[0].services.forEach((service) => {
1529
+ if (device.serialNo === service.subtype) {
1530
+ let serviceChildLock = childLockAccessories[0].getServiceById(api.hap.Service.Switch, service.subtype);
1531
+ let characteristic = api.hap.Characteristic.On;
1544
1532
 
1545
- serviceChildLock.getCharacteristic(characteristic).updateValue(childLockEnabled);
1546
- }
1547
- });
1548
- });
1549
- }
1533
+ let childLockEnabled = device.childLockEnabled || false;
1550
1534
 
1551
- return;
1535
+ serviceChildLock.getCharacteristic(characteristic).updateValue(childLockEnabled);
1536
+ }
1537
+ });
1538
+ });
1552
1539
  }
1553
1540
 
1554
1541
  function errorHandler(err) {