@homebridge-plugins/homebridge-tado 8.5.1-beta.1 → 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 = [];
@@ -746,7 +746,7 @@ export default (api, accessories, config, tado, telegram) => {
746
746
  }
747
747
  try {
748
748
  //wait for fakegato history services to be loaded
749
- await new Promise(r => setTimeout(r, 4000));
749
+ await timeout(4000);
750
750
  for (const refreshHistory of aRefreshHistoryHandlers) {
751
751
  refreshHistory();
752
752
  }
@@ -809,413 +809,391 @@ export default (api, accessories, config, tado, telegram) => {
809
809
  }
810
810
 
811
811
  async function updateMe() {
812
- if (!settingState) {
813
- Logger.debug('Polling User Info...', config.homeName);
812
+ if (settingState) return;
814
813
 
815
- const me = await tado.getMe();
814
+ Logger.debug('Polling User Info...', config.homeName);
816
815
 
817
- if (config.homeName !== me.homes[0].name) throw ('Cannot find requested home in the API!', config.homeName);
816
+ const me = await tado.getMe();
818
817
 
819
- config.homeId = me.homes[0].id;
820
- }
818
+ if (config.homeName !== me.homes[0].name) throw ('Cannot find requested home in the API!', config.homeName);
821
819
 
822
- return;
820
+ config.homeId = me.homes[0].id;
823
821
  }
824
822
 
825
823
  async function updateHome() {
826
- if (!settingState) {
827
- Logger.debug('Polling Home Info...', config.homeName);
824
+ if (settingState) return;
828
825
 
829
- const home = await tado.getHome(config.homeId);
826
+ Logger.debug('Polling Home Info...', config.homeName);
830
827
 
831
- if (!config.temperatureUnit) config.temperatureUnit = home.temperatureUnit || 'CELSIUS';
828
+ const home = await tado.getHome(config.homeId);
832
829
 
833
- //config.skills = home.skills || []; //do we need this?
830
+ if (!config.temperatureUnit) config.temperatureUnit = home.temperatureUnit || 'CELSIUS';
834
831
 
835
- if (
836
- !config.geolocation ||
837
- (config.geolocation && !config.geolocation.longitude) ||
838
- !config.geolocation.latitude
839
- ) {
840
- if (!home.geolocation) home.geolocation = {};
832
+ //config.skills = home.skills || []; //do we need this?
841
833
 
842
- config.geolocation = {
843
- longitude: (home.geolocation.longitude || '').toString() || false,
844
- latitude: (home.geolocation.latitude || '').toString() || false,
845
- };
846
- }
847
- }
834
+ if (
835
+ !config.geolocation ||
836
+ (config.geolocation && !config.geolocation.longitude) ||
837
+ !config.geolocation.latitude
838
+ ) {
839
+ if (!home.geolocation) home.geolocation = {};
848
840
 
849
- return;
841
+ config.geolocation = {
842
+ longitude: (home.geolocation.longitude || '').toString() || false,
843
+ latitude: (home.geolocation.latitude || '').toString() || false,
844
+ };
845
+ }
850
846
  }
851
847
 
852
848
  async function updateZones(idToUpdate) {
853
849
  let zoneStates = {};
854
- if (!settingState || idToUpdate !== undefined) {
855
- Logger.debug('Polling Zones...', config.homeName);
850
+ if (settingState && idToUpdate === undefined) {
851
+ await timeout(10 * 1000);
852
+ if (settingState) return zoneStates;
853
+ }
856
854
 
857
- //CentralSwitch
858
- let inManualMode = 0;
859
- let inOffMode = 0;
860
- let inAutoMode = 0;
855
+ Logger.debug('Polling Zones...', config.homeName);
861
856
 
862
- let zonesWithoutID = config.zones.filter((zone) => zone && !zone.id);
857
+ //CentralSwitch
858
+ let inManualMode = 0;
859
+ let inOffMode = 0;
860
+ let inAutoMode = 0;
863
861
 
864
- if (zonesWithoutID.length) {
865
- const allZones = (await tado.getZones(config.homeId)) || [];
866
-
867
- for (const [index, zone] of config.zones.entries()) {
868
- allZones.forEach((zoneWithID) => {
869
- if (zoneWithID.name === zone.name) config.zones[index].id = zoneWithID.id;
870
- });
871
- }
872
- }
862
+ let zonesWithoutID = config.zones.filter((zone) => zone && !zone.id);
873
863
 
864
+ if (zonesWithoutID.length) {
874
865
  const allZones = (await tado.getZones(config.homeId)) || [];
875
866
 
876
867
  for (const [index, zone] of config.zones.entries()) {
877
868
  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
- );
882
-
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
- }
869
+ if (zoneWithID.name === zone.name) config.zones[index].id = zoneWithID.id;
901
870
  });
902
871
  }
872
+ }
903
873
 
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
- }
912
-
913
- for (const zone of zonesToUpdate) {
914
- const zoneState = zoneStates[zone.id];
874
+ const allZones = (await tado.getZones(config.homeId)) || [];
915
875
 
916
- 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
+ );
917
882
 
918
- if (zoneState.setting.type === 'HEATING') {
919
- 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
+ }
920
903
 
921
- 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
+ }
922
912
 
923
- //HEATING
924
- if (zoneState.sensorDataPoints.insideTemperature) {
925
- currentTemp =
926
- config.temperatureUnit === 'FAHRENHEIT'
927
- ? zoneState.sensorDataPoints.insideTemperature.fahrenheit
928
- : zoneState.sensorDataPoints.insideTemperature.celsius;
913
+ for (const zone of zonesToUpdate) {
914
+ const zoneState = zoneStates[zone.id];
929
915
 
930
- if (zoneState.setting.power === 'ON') {
931
- targetTemp =
932
- config.temperatureUnit === 'FAHRENHEIT'
933
- ? zoneState.setting.temperature.fahrenheit
934
- : zoneState.setting.temperature.celsius;
916
+ let currentState, targetState, currentTemp, targetTemp, humidity, active, battery, tempEqual;
935
917
 
936
- tempEqual = Math.round(currentTemp) === Math.round(targetTemp);
918
+ if (zoneState.setting.type === 'HEATING') {
919
+ battery = zone.battery === 'NORMAL' ? 100 : 10;
937
920
 
938
- //show as currently heating if current temp is lower than target temp, otherwise show as temp set
939
- currentState = currentTemp < targetTemp ? 1 : 0;
921
+ if (zoneState.sensorDataPoints.humidity) humidity = zoneState.sensorDataPoints.humidity.percentage;
940
922
 
941
- //check if auto mode is enabled
942
- 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;
943
929
 
944
- active = 1;
945
- } else {
946
- //heating is switched off
947
- currentState = 0;
948
- targetState = 0;
949
- active = 0;
950
- }
930
+ if (zoneState.setting.power === 'ON') {
931
+ targetTemp =
932
+ config.temperatureUnit === 'FAHRENHEIT'
933
+ ? zoneState.setting.temperature.fahrenheit
934
+ : zoneState.setting.temperature.celsius;
951
935
 
952
- if (targetState === undefined && zoneState.overlayType === null) {
953
- targetState = 3;
954
- }
955
- }
936
+ tempEqual = Math.round(currentTemp) === Math.round(targetTemp);
956
937
 
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
- );
938
+ //show as currently heating if current temp is lower than target temp, otherwise show as temp set
939
+ currentState = currentTemp < targetTemp ? 1 : 0;
965
940
 
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);
941
+ //check if auto mode is enabled
942
+ targetState = zoneState.overlayType === null ? 3 : 1;
971
943
 
972
- let serviceBattery = acc.getService(api.hap.Service.BatteryService);
973
- 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
+ }
974
951
 
975
- if (serviceBattery && zone.battery) {
976
- serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
977
- }
952
+ if (targetState === undefined && zoneState.overlayType === null) {
953
+ targetState = 3;
954
+ }
955
+ }
978
956
 
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;
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
+ );
986
965
 
987
- if (!isNaN(currentTemp)) {
988
- 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);
989
971
 
990
- let isFahrenheit = serviceThermostat.getCharacteristic(characteristicUnit).value === 1;
991
- let unitChanged = config.temperatureUnit !== acc.context.config.temperatureUnit;
972
+ let serviceBattery = acc.getService(api.hap.Service.BatteryService);
973
+ let characteristicBattery = api.hap.Characteristic.BatteryLevel;
992
974
 
993
- let cToF = (c) => Math.round((c * 9) / 5 + 32);
994
- let fToC = (f) => Math.round(((f - 32) * 5) / 9);
975
+ if (serviceBattery && zone.battery) {
976
+ serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
977
+ }
995
978
 
996
- 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;
997
986
 
998
- serviceThermostat.getCharacteristic(characteristicCurrentTemp).updateValue(newValue);
999
- }
987
+ if (!isNaN(currentTemp)) {
988
+ acc.context.config.temperatureUnit = acc.context.config.temperatureUnit || config.temperatureUnit;
1000
989
 
1001
- if (!isNaN(targetTemp))
1002
- serviceThermostat.getCharacteristic(characteristicTargetTemp).updateValue(targetTemp);
990
+ let isFahrenheit = serviceThermostat.getCharacteristic(characteristicUnit).value === 1;
991
+ let unitChanged = config.temperatureUnit !== acc.context.config.temperatureUnit;
1003
992
 
1004
- if (!isNaN(currentState))
1005
- 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);
1006
995
 
1007
- if (!isNaN(targetState))
1008
- serviceThermostat.getCharacteristic(characteristicTargetState).updateValue(targetState);
996
+ let newValue = unitChanged ? (isFahrenheit ? cToF(currentTemp) : fToC(currentTemp)) : currentTemp;
1009
997
 
1010
- if (!isNaN(humidity) && serviceThermostat.testCharacteristic(characteristicHumidity))
1011
- serviceThermostat.getCharacteristic(characteristicHumidity).updateValue(humidity);
998
+ serviceThermostat.getCharacteristic(characteristicCurrentTemp).updateValue(newValue);
1012
999
  }
1013
1000
 
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;
1001
+ if (!isNaN(targetTemp))
1002
+ serviceThermostat.getCharacteristic(characteristicTargetTemp).updateValue(targetTemp);
1022
1003
 
1023
- currentState = active ? (targetState === 3 || tempEqual ? 1 : currentState + 1) : 0;
1004
+ if (!isNaN(currentState))
1005
+ serviceThermostat.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1024
1006
 
1025
- targetState = 1;
1007
+ if (!isNaN(targetState))
1008
+ serviceThermostat.getCharacteristic(characteristicTargetState).updateValue(targetState);
1026
1009
 
1027
- if (!isNaN(active)) serviceHeaterCooler.getCharacteristic(characteristicActive).updateValue(active);
1010
+ if (!isNaN(humidity) && serviceThermostat.testCharacteristic(characteristicHumidity))
1011
+ serviceThermostat.getCharacteristic(characteristicHumidity).updateValue(humidity);
1012
+ }
1028
1013
 
1029
- if (!isNaN(currentTemp))
1030
- 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;
1031
1022
 
1032
- if (!isNaN(targetTemp)) {
1033
- serviceHeaterCooler.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1023
+ currentState = active ? (targetState === 3 || tempEqual ? 1 : currentState + 1) : 0;
1034
1024
 
1035
- serviceHeaterCooler.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1036
- }
1025
+ targetState = 1;
1037
1026
 
1038
- if (!isNaN(currentState))
1039
- serviceHeaterCooler.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1027
+ if (!isNaN(active)) serviceHeaterCooler.getCharacteristic(characteristicActive).updateValue(active);
1040
1028
 
1041
- if (!isNaN(targetState))
1042
- serviceHeaterCooler.getCharacteristic(characteristicTargetState).updateValue(targetState);
1029
+ if (!isNaN(currentTemp))
1030
+ serviceHeaterCooler.getCharacteristic(characteristicCurrentTemp).updateValue(currentTemp);
1043
1031
 
1044
- if (!isNaN(humidity) && serviceHeaterCooler.testCharacteristic(characteristicHumidity))
1045
- serviceHeaterCooler.getCharacteristic(characteristicHumidity).updateValue(humidity);
1046
- }
1047
- }
1048
- });
1049
- }
1050
- } else {
1051
- // Non-HEATING zones (AIR_CONDITIONING, HOT_WATER, etc.)
1052
- battery = zone.battery === 'NORMAL' ? 100 : 10;
1032
+ if (!isNaN(targetTemp)) {
1033
+ serviceHeaterCooler.getCharacteristic(characteristicTargetTempHeating).updateValue(targetTemp);
1053
1034
 
1054
- if (zoneState.sensorDataPoints.humidity) {
1055
- humidity = zoneState.sensorDataPoints.humidity.percentage;
1056
- }
1035
+ serviceHeaterCooler.getCharacteristic(characteristicTargetTempCooling).updateValue(targetTemp);
1036
+ }
1057
1037
 
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
- }
1038
+ if (!isNaN(currentState))
1039
+ serviceHeaterCooler.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1065
1040
 
1066
- if (zoneState.setting.power === 'ON') {
1067
- active = 1;
1041
+ if (!isNaN(targetState))
1042
+ serviceHeaterCooler.getCharacteristic(characteristicTargetState).updateValue(targetState);
1068
1043
 
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;
1044
+ if (!isNaN(humidity) && serviceHeaterCooler.testCharacteristic(characteristicHumidity))
1045
+ serviceHeaterCooler.getCharacteristic(characteristicHumidity).updateValue(humidity);
1094
1046
  }
1095
- } else {
1096
- // Non-AC zones (HOT_WATER, etc.)
1097
- currentState = zoneState.overlayType === null ? 1 : 2;
1098
- targetState = 1;
1099
1047
  }
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
- }
1048
+ });
1049
+ }
1050
+ } else {
1051
+ // Non-HEATING zones (AIR_CONDITIONING, HOT_WATER, etc.)
1052
+ battery = zone.battery === 'NORMAL' ? 100 : 10;
1106
1053
 
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');
1054
+ if (zoneState.sensorDataPoints.humidity) {
1055
+ humidity = zoneState.sensorDataPoints.humidity.percentage;
1056
+ }
1114
1057
 
1115
- if (heaterAccessory.length) {
1116
- heaterAccessory.forEach((acc) => {
1117
- if (acc.displayName.includes(zone.name)) {
1118
- 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
+ }
1119
1065
 
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;
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
+ }
1126
1106
 
1127
- 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');
1128
1114
 
1129
- 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);
1130
1119
 
1131
- 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;
1132
1126
 
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
1127
+ service.getCharacteristic(characteristicActive).updateValue(active);
1136
1128
 
1137
- service.getCharacteristic(characteristicCurrentTemp).updateValue(acc.context.currentTemp);
1138
- }
1129
+ service.getCharacteristic(characteristicCurrentState).updateValue(currentState);
1139
1130
 
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
- }
1131
+ service.getCharacteristic(characteristicTargetState).updateValue(targetState);
1153
1132
 
1154
- // 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
1155
1136
 
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);
1159
- }
1137
+ service.getCharacteristic(characteristicCurrentTemp).updateValue(acc.context.currentTemp);
1160
1138
  }
1161
- });
1162
- }
1163
1139
 
1164
- if (switchAccessory.length) {
1165
- switchAccessory.forEach((acc) => {
1166
- if (acc.displayName.includes(zone.name)) {
1167
- 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
+ }
1168
1153
 
1169
- let characteristic = api.hap.Characteristic.On;
1154
+ // Fan speed polling removed for AIR_CONDITIONING zones
1170
1155
 
1171
- 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);
1172
1159
  }
1173
- });
1174
- }
1175
-
1176
- if (faucetAccessory.length) {
1177
- faucetAccessory.forEach((acc) => {
1178
- if (acc.displayName.includes(zone.name)) {
1179
- let service = acc.getService(api.hap.Service.Valve);
1160
+ }
1161
+ });
1162
+ }
1180
1163
 
1181
- let characteristicActive = api.hap.Characteristic.Active;
1182
- 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);
1183
1168
 
1184
- service.getCharacteristic(characteristicActive).updateValue(active ? 1 : 0);
1169
+ let characteristic = api.hap.Characteristic.On;
1185
1170
 
1186
- service.getCharacteristic(characteristicInUse).updateValue(active ? 1 : 0);
1187
- }
1188
- });
1189
- }
1171
+ service.getCharacteristic(characteristic).updateValue(active ? true : false);
1172
+ }
1173
+ });
1190
1174
  }
1191
1175
 
1192
- //TemperatureSensor
1193
- const tempAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-temperature');
1194
-
1195
- if (tempAccessory.length) {
1196
- tempAccessory.forEach((acc) => {
1176
+ if (faucetAccessory.length) {
1177
+ faucetAccessory.forEach((acc) => {
1197
1178
  if (acc.displayName.includes(zone.name)) {
1198
- let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1199
- let characteristicBattery = api.hap.Characteristic.BatteryLevel;
1179
+ let service = acc.getService(api.hap.Service.Valve);
1200
1180
 
1201
- if (serviceBattery && !isNaN(battery)) {
1202
- serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1203
- }
1181
+ let characteristicActive = api.hap.Characteristic.Active;
1182
+ let characteristicInUse = api.hap.Characteristic.InUse;
1204
1183
 
1205
- if (!isNaN(currentTemp)) {
1206
- let service = acc.getService(api.hap.Service.TemperatureSensor);
1207
- let characteristic = api.hap.Characteristic.CurrentTemperature;
1184
+ service.getCharacteristic(characteristicActive).updateValue(active ? 1 : 0);
1208
1185
 
1209
- service.getCharacteristic(characteristic).updateValue(currentTemp);
1210
- }
1186
+ service.getCharacteristic(characteristicInUse).updateValue(active ? 1 : 0);
1211
1187
  }
1212
1188
  });
1213
1189
  }
1190
+ }
1214
1191
 
1215
- //HumiditySensor
1216
- 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');
1217
1194
 
1218
- humidityAccessory.forEach((acc) => {
1195
+ if (tempAccessory.length) {
1196
+ tempAccessory.forEach((acc) => {
1219
1197
  if (acc.displayName.includes(zone.name)) {
1220
1198
  let serviceBattery = acc.getService(api.hap.Service.BatteryService);
1221
1199
  let characteristicBattery = api.hap.Characteristic.BatteryLevel;
@@ -1224,327 +1202,340 @@ export default (api, accessories, config, tado, telegram) => {
1224
1202
  serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1225
1203
  }
1226
1204
 
1227
- if (!isNaN(humidity)) {
1228
- let service = acc.getService(api.hap.Service.HumiditySensor);
1229
- 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;
1230
1208
 
1231
- service.getCharacteristic(characteristic).updateValue(humidity);
1209
+ service.getCharacteristic(characteristic).updateValue(currentTemp);
1232
1210
  }
1233
1211
  }
1234
1212
  });
1213
+ }
1235
1214
 
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
- );
1243
-
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;
1215
+ //HumiditySensor
1216
+ const humidityAccessory = accessories.filter((acc) => acc && acc.context.config.subtype === 'zone-humidity');
1249
1217
 
1250
- if (serviceBattery && !isNaN(battery)) {
1251
- serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1252
- }
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;
1253
1222
 
1254
- let service = acc.getService(api.hap.Service.ContactSensor);
1255
- let characteristic = api.hap.Characteristic.ContactSensorState;
1223
+ if (serviceBattery && !isNaN(battery)) {
1224
+ serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1225
+ }
1256
1226
 
1257
- 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;
1258
1230
 
1259
- service.getCharacteristic(characteristic).updateValue(state);
1260
- }
1261
- });
1231
+ service.getCharacteristic(characteristic).updateValue(humidity);
1232
+ }
1262
1233
  }
1234
+ });
1263
1235
 
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;
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
+ );
1269
1243
 
1270
- 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;
1271
1249
 
1272
- service.getCharacteristic(characteristic).updateValue(state);
1250
+ if (serviceBattery && !isNaN(battery)) {
1251
+ serviceBattery.getCharacteristic(characteristicBattery).updateValue(battery);
1273
1252
  }
1274
- });
1275
- }
1276
1253
 
1277
- if (zoneState.setting.type === 'HEATING') {
1278
- //CentralSwitch
1279
- if (zoneState.overlayType === null) inAutoMode += 1;
1254
+ let service = acc.getService(api.hap.Service.ContactSensor);
1255
+ let characteristic = api.hap.Characteristic.ContactSensorState;
1280
1256
 
1281
- if (zoneState.overlayType !== null && zoneState.setting.power === 'OFF') inOffMode += 1;
1257
+ let state = zoneState.openWindow || zoneState.openWindowDetected ? 1 : 0;
1282
1258
 
1283
- if (zoneState.overlayType !== null && zoneState.setting.power === 'ON' && zoneState.overlay.termination)
1284
- inManualMode += 1;
1285
- }
1259
+ service.getCharacteristic(characteristic).updateValue(state);
1260
+ }
1261
+ });
1286
1262
  }
1287
1263
 
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;
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;
1301
1269
 
1302
- let state = (inManualMode || inAutoMode) !== 0;
1270
+ let state = zone.openWindowEnabled ? true : false;
1303
1271
 
1304
- serviceSwitch.getCharacteristic(characteristicAuto).updateValue(inAutoMode);
1272
+ service.getCharacteristic(characteristic).updateValue(state);
1273
+ }
1274
+ });
1275
+ }
1305
1276
 
1306
- serviceSwitch.getCharacteristic(characteristicManual).updateValue(inManualMode);
1277
+ if (zoneState.setting.type === 'HEATING') {
1278
+ //CentralSwitch
1279
+ if (zoneState.overlayType === null) inAutoMode += 1;
1307
1280
 
1308
- serviceSwitch.getCharacteristic(characteristicOff).updateValue(inOffMode);
1281
+ if (zoneState.overlayType !== null && zoneState.setting.power === 'OFF') inOffMode += 1;
1309
1282
 
1310
- serviceSwitch.getCharacteristic(characteristicOn).updateValue(state);
1311
- }
1312
- });
1283
+ if (zoneState.overlayType !== null && zoneState.setting.power === 'ON' && zoneState.overlay.termination)
1284
+ inManualMode += 1;
1313
1285
  }
1314
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
+ }
1315
1314
  return zoneStates;
1316
1315
  }
1317
1316
 
1318
1317
  async function updateMobileDevices() {
1319
- if (!settingState) {
1320
- Logger.debug('Polling MobileDevices...', config.homeName);
1318
+ if (settingState) return;
1321
1319
 
1322
- const mobileDevices = await tado.getMobileDevices(config.homeId);
1320
+ Logger.debug('Polling MobileDevices...', config.homeName);
1323
1321
 
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
- );
1322
+ const mobileDevices = await tado.getMobileDevices(config.homeId);
1330
1323
 
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
- );
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
+ );
1337
1330
 
1338
- 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
+ );
1339
1337
 
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;
1338
+ let activeUser = 0;
1344
1339
 
1345
- 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;
1346
1344
 
1347
- let service =
1348
- acc.getService(api.hap.Service.MotionSensor) || acc.getService(api.hap.Service.OccupancySensor);
1345
+ if (atHome) activeUser += 1;
1349
1346
 
1350
- let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1351
- ? api.hap.Characteristic.MotionDetected
1352
- : api.hap.Characteristic.OccupancyDetected;
1347
+ let service =
1348
+ acc.getService(api.hap.Service.MotionSensor) || acc.getService(api.hap.Service.OccupancySensor);
1353
1349
 
1354
- service.getCharacteristic(characteristic).updateValue(atHome);
1355
- }
1356
- });
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
+ }
1357
1356
  });
1357
+ });
1358
1358
 
1359
- if (anyone.length) {
1360
- let service =
1361
- 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);
1362
1362
 
1363
- let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1364
- ? api.hap.Characteristic.MotionDetected
1365
- : api.hap.Characteristic.OccupancyDetected;
1363
+ let characteristic = service.testCharacteristic(api.hap.Characteristic.MotionDetected)
1364
+ ? api.hap.Characteristic.MotionDetected
1365
+ : api.hap.Characteristic.OccupancyDetected;
1366
1366
 
1367
- service.getCharacteristic(characteristic).updateValue(activeUser ? 1 : 0);
1368
- }
1367
+ service.getCharacteristic(characteristic).updateValue(activeUser ? 1 : 0);
1369
1368
  }
1370
-
1371
- return;
1372
1369
  }
1373
1370
 
1374
1371
  async function updateWeather() {
1375
- if (!settingState) {
1376
- const weatherTemperatureAccessory = accessories.filter(
1377
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Weather'
1378
- );
1372
+ if (settingState) return;
1379
1373
 
1380
- const solarIntensityAccessory = accessories.filter(
1381
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Solar Intensity'
1382
- );
1374
+ const weatherTemperatureAccessory = accessories.filter(
1375
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Weather'
1376
+ );
1383
1377
 
1384
- if (weatherTemperatureAccessory.length || solarIntensityAccessory.length) {
1385
- Logger.debug('Polling Weather...', config.homeName);
1378
+ const solarIntensityAccessory = accessories.filter(
1379
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Solar Intensity'
1380
+ );
1386
1381
 
1387
- const weather = await tado.getWeather(config.homeId);
1382
+ if (weatherTemperatureAccessory.length || solarIntensityAccessory.length) {
1383
+ Logger.debug('Polling Weather...', config.homeName);
1388
1384
 
1389
- if (weatherTemperatureAccessory.length && weather.outsideTemperature) {
1390
- let tempUnit = config.temperatureUnit;
1391
- let service = weatherTemperatureAccessory[0].getService(api.hap.Service.TemperatureSensor);
1392
- let characteristic = api.hap.Characteristic.CurrentTemperature;
1385
+ const weather = await tado.getWeather(config.homeId);
1393
1386
 
1394
- let temp =
1395
- 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;
1396
1391
 
1397
- service.getCharacteristic(characteristic).updateValue(temp);
1398
- }
1392
+ let temp =
1393
+ tempUnit === 'FAHRENHEIT' ? weather.outsideTemperature.fahrenheit : weather.outsideTemperature.celsius;
1399
1394
 
1400
- if (solarIntensityAccessory.length && weather.solarIntensity) {
1401
- let state = weather.solarIntensity.percentage !== 0;
1402
- let brightness = weather.solarIntensity.percentage;
1395
+ service.getCharacteristic(characteristic).updateValue(temp);
1396
+ }
1403
1397
 
1404
- solarIntensityAccessory[0].context.lightBulbState = state;
1405
- solarIntensityAccessory[0].context.lightBulbBrightness = brightness;
1398
+ if (solarIntensityAccessory.length && weather.solarIntensity) {
1399
+ let state = weather.solarIntensity.percentage !== 0;
1400
+ let brightness = weather.solarIntensity.percentage;
1406
1401
 
1407
- let serviceLightbulb = solarIntensityAccessory[0].getService(api.hap.Service.Lightbulb);
1408
- let serviceLightsensor = solarIntensityAccessory[0].getService(api.hap.Service.LightSensor);
1402
+ solarIntensityAccessory[0].context.lightBulbState = state;
1403
+ solarIntensityAccessory[0].context.lightBulbBrightness = brightness;
1409
1404
 
1410
- if (serviceLightbulb) {
1411
- let characteristicOn = api.hap.Characteristic.On;
1412
- 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);
1413
1407
 
1414
- serviceLightbulb.getCharacteristic(characteristicOn).updateValue(state);
1408
+ if (serviceLightbulb) {
1409
+ let characteristicOn = api.hap.Characteristic.On;
1410
+ let characteristicBrightness = api.hap.Characteristic.Brightness;
1415
1411
 
1416
- serviceLightbulb.getCharacteristic(characteristicBrightness).updateValue(brightness);
1417
- } else {
1418
- let characteristicLux = api.hap.Characteristic.CurrentAmbientLightLevel;
1412
+ serviceLightbulb.getCharacteristic(characteristicOn).updateValue(state);
1419
1413
 
1420
- serviceLightsensor
1421
- .getCharacteristic(characteristicLux)
1422
- .updateValue(brightness ? brightness * 1000 : 0.0001);
1423
- }
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);
1424
1421
  }
1425
1422
  }
1426
1423
  }
1427
-
1428
- return;
1429
1424
  }
1430
1425
 
1431
1426
  async function updatePresence() {
1432
- if (!settingState) {
1433
- const presenceLockAccessory = accessories.filter(
1434
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Presence Lock'
1435
- );
1427
+ if (settingState) return;
1436
1428
 
1437
- if (presenceLockAccessory.length) {
1438
- Logger.debug('Polling PresenceLock...', config.homeName);
1429
+ const presenceLockAccessory = accessories.filter(
1430
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Presence Lock'
1431
+ );
1439
1432
 
1440
- const presenceLock = await tado.getState(config.homeId);
1433
+ if (presenceLockAccessory.length) {
1434
+ Logger.debug('Polling PresenceLock...', config.homeName);
1441
1435
 
1442
- /*
1443
- 0: Home | true
1444
- 1: Away | true
1445
- 3: Off | false
1446
- */
1436
+ const presenceLock = await tado.getState(config.homeId);
1447
1437
 
1448
- let state = presenceLock.presenceLocked ? (presenceLock.presence === 'AWAY' ? 1 : 0) : 3;
1438
+ /*
1439
+ 0: Home | true
1440
+ 1: Away | true
1441
+ 3: Off | false
1442
+ */
1449
1443
 
1450
- let serviceSecurity = presenceLockAccessory[0].getService(api.hap.Service.SecuritySystem);
1451
- let serviceHomeSwitch = presenceLockAccessory[0].getServiceById(api.hap.Service.Switch, 'HomeSwitch');
1452
- let serviceAwaySwitch = presenceLockAccessory[0].getServiceById(api.hap.Service.Switch, 'AwaySwitch');
1444
+ let state = presenceLock.presenceLocked ? (presenceLock.presence === 'AWAY' ? 1 : 0) : 3;
1453
1445
 
1454
- if (serviceSecurity) {
1455
- let characteristicCurrent = api.hap.Characteristic.SecuritySystemCurrentState;
1456
- 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');
1457
1449
 
1458
- serviceSecurity.getCharacteristic(characteristicCurrent).updateValue(state);
1450
+ if (serviceSecurity) {
1451
+ let characteristicCurrent = api.hap.Characteristic.SecuritySystemCurrentState;
1452
+ let characteristicTarget = api.hap.Characteristic.SecuritySystemTargetState;
1459
1453
 
1460
- serviceSecurity.getCharacteristic(characteristicTarget).updateValue(state);
1461
- } else if (serviceHomeSwitch || serviceAwaySwitch) {
1462
- let characteristicOn = api.hap.Characteristic.On;
1454
+ serviceSecurity.getCharacteristic(characteristicCurrent).updateValue(state);
1463
1455
 
1464
- let homeState = !state ? true : false;
1456
+ serviceSecurity.getCharacteristic(characteristicTarget).updateValue(state);
1457
+ } else if (serviceHomeSwitch || serviceAwaySwitch) {
1458
+ let characteristicOn = api.hap.Characteristic.On;
1465
1459
 
1466
- let awayState = state === 1 ? true : false;
1460
+ let homeState = !state ? true : false;
1467
1461
 
1468
- serviceAwaySwitch.getCharacteristic(characteristicOn).updateValue(awayState);
1462
+ let awayState = state === 1 ? true : false;
1469
1463
 
1470
- serviceHomeSwitch.getCharacteristic(characteristicOn).updateValue(homeState);
1471
- }
1464
+ serviceAwaySwitch.getCharacteristic(characteristicOn).updateValue(awayState);
1465
+
1466
+ serviceHomeSwitch.getCharacteristic(characteristicOn).updateValue(homeState);
1472
1467
  }
1473
1468
  }
1474
1469
  }
1475
1470
 
1476
1471
  async function updateRunningTime() {
1477
- if (!settingState) {
1478
- const centralSwitchAccessory = accessories.filter(
1479
- (acc) => acc && acc.displayName === acc.context.config.homeName + ' Central Switch'
1480
- );
1472
+ if (settingState) return;
1481
1473
 
1482
- if (centralSwitchAccessory.length) {
1483
- Logger.debug('Polling RunningTime...', config.homeName);
1474
+ const centralSwitchAccessory = accessories.filter(
1475
+ (acc) => acc && acc.displayName === acc.context.config.homeName + ' Central Switch'
1476
+ );
1484
1477
 
1485
- let periods = ['days', 'months', 'years'];
1478
+ if (centralSwitchAccessory.length) {
1479
+ Logger.debug('Polling RunningTime...', config.homeName);
1486
1480
 
1487
- for (const period of periods) {
1488
- let fromDate =
1489
- period === 'days'
1490
- ? moment().format('YYYY-MM-DD')
1491
- : period === 'months'
1492
- ? moment().subtract(1, 'days').subtract(1, period).format('YYYY-MM-DD')
1493
- : moment().add(1, 'months').startOf('month').subtract(1, period).format('YYYY-MM-DD');
1481
+ let periods = ['days', 'months', 'years'];
1494
1482
 
1495
- 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');
1496
1490
 
1497
- let time = period.substring(0, period.length - 1);
1491
+ let toDate = period === 'years' ? moment().format('YYYY-MM-DD') : false;
1498
1492
 
1499
- const runningTime = await tado.getRunningTime(config.homeId, time, fromDate, toDate);
1493
+ let time = period.substring(0, period.length - 1);
1500
1494
 
1501
- if (runningTime && runningTime.summary) {
1502
- let summaryInHours = runningTime.summary.totalRunningTimeInSeconds / 3600;
1495
+ const runningTime = await tado.getRunningTime(config.homeId, time, fromDate, toDate);
1503
1496
 
1504
- let serviceSwitch = centralSwitchAccessory[0].getServiceById(api.hap.Service.Switch, 'Central');
1505
- let characteristic =
1506
- period === 'years'
1507
- ? api.hap.Characteristic.OverallHeatYear
1508
- : period === 'months'
1509
- ? api.hap.Characteristic.OverallHeatMonth
1510
- : api.hap.Characteristic.OverallHeatDay;
1497
+ if (runningTime && runningTime.summary) {
1498
+ let summaryInHours = runningTime.summary.totalRunningTimeInSeconds / 3600;
1511
1499
 
1512
- serviceSwitch.getCharacteristic(characteristic).updateValue(summaryInHours);
1513
- }
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;
1514
1507
 
1515
- await timeout(500);
1508
+ serviceSwitch.getCharacteristic(characteristic).updateValue(summaryInHours);
1516
1509
  }
1510
+
1511
+ await timeout(500);
1517
1512
  }
1518
1513
  }
1519
-
1520
- return;
1521
1514
  }
1522
1515
 
1523
1516
  async function updateDevices() {
1524
- if (!settingState) {
1525
- Logger.debug('Polling Devices...', config.homeName);
1517
+ if (settingState) return;
1526
1518
 
1527
- const devices = await tado.getDevices(config.homeId);
1519
+ Logger.debug('Polling Devices...', config.homeName);
1528
1520
 
1529
- const childLockAccessories = accessories.filter(
1530
- (acc) => acc && acc.context.config.subtype === 'extra-childswitch'
1531
- );
1521
+ const devices = await tado.getDevices(config.homeId);
1532
1522
 
1533
- devices.forEach((device) => {
1534
- childLockAccessories[0].services.forEach((service) => {
1535
- if (device.serialNo === service.subtype) {
1536
- let serviceChildLock = childLockAccessories[0].getServiceById(api.hap.Service.Switch, service.subtype);
1537
- let characteristic = api.hap.Characteristic.On;
1523
+ const childLockAccessories = accessories.filter(
1524
+ (acc) => acc && acc.context.config.subtype === 'extra-childswitch'
1525
+ );
1538
1526
 
1539
- 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;
1540
1532
 
1541
- serviceChildLock.getCharacteristic(characteristic).updateValue(childLockEnabled);
1542
- }
1543
- });
1544
- });
1545
- }
1533
+ let childLockEnabled = device.childLockEnabled || false;
1546
1534
 
1547
- return;
1535
+ serviceChildLock.getCharacteristic(characteristic).updateValue(childLockEnabled);
1536
+ }
1537
+ });
1538
+ });
1548
1539
  }
1549
1540
 
1550
1541
  function errorHandler(err) {