Coverage for python_carrier_infinity/status.py: 98%

70 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-08-19 01:56 +0000

1"""Accessing the current status""" 

2from __future__ import annotations 

3from textwrap import dedent, indent 

4from datetime import datetime 

5import dateutil 

6import dateutil.parser 

7from .types import ActivityName, FanSpeed, Mode, TemperatureUnits 

8 

9 

10class System: 

11 """Represents the top-level system status""" 

12 

13 def __init__(self, data: dict): 

14 self.data = data 

15 

16 def __str__(self) -> str: 

17 zones = "\n\n".join([str(zone) for zone in self.zones.values()]) 

18 return dedent( 

19 f"""\ 

20 Timestamp: {str(self.timestamp)} 

21 Mode: {self.mode} 

22 Temperature units: {self.temperature_units} 

23 Outside temperature: {self.outside_temperature} 

24 Current operation: {self.current_operation} 

25 Current airflow: {self.airflow} 

26 Humidifier active: {self.humidifier_active} 

27 Zones:""") \ 

28 + "\n" + indent(zones, " ") 

29 

30 @property 

31 def zones(self) -> dict[str, Zone]: 

32 """The status of all enabled zones""" 

33 zones = {} 

34 for zone_data in self.data["zones"]: 

35 if zone_data["enabled"] == "off": 

36 continue 

37 zone = Zone(zone_data) 

38 zones[zone.id] = zone 

39 return zones 

40 

41 @property 

42 def timestamp(self) -> datetime: 

43 """The timestamp of the status report""" 

44 return dateutil.parser.isoparse(self.data["utcTime"]) 

45 

46 @property 

47 def mode(self) -> Mode: 

48 """The HVAC mode""" 

49 return Mode(self.data["mode"]) 

50 

51 @property 

52 def outside_temperature(self) -> int: 

53 """The outside air temperature""" 

54 return int(self.data["oat"]) 

55 

56 @property 

57 def temperature_units(self) -> TemperatureUnits: 

58 """The temperature units used""" 

59 return TemperatureUnits(self.data["cfgem"]) 

60 

61 @property 

62 def current_operation(self) -> str: 

63 """The current operation in progress""" 

64 return self.data["idu"]["opstat"] 

65 

66 @property 

67 def humidifier_active(self) -> bool: 

68 """The status of the humidifer""" 

69 if self.data["humid"] == "on": 69 ↛ 70line 69 didn't jump to line 70, because the condition on line 69 was never true

70 return True 

71 return False 

72 

73 @property 

74 def airflow(self) -> int: 

75 """The current airflow in cfm""" 

76 return self.data["idu"]["cfm"] 

77 

78 

79class Zone: 

80 """Represents the status of a zone""" 

81 

82 def __init__(self, data: dict): 

83 self.data = data 

84 

85 def __str__(self) -> str: 

86 return dedent( 

87 f"""\ 

88 ID: {self.id} 

89 Activity: {self.activity} 

90 Temperature: {self.temperature} 

91 Humidity: {self.relative_humidity} 

92 Fan speed: {self.fan_speed} 

93 Target heating temperature: {self.target_heating_temperature} 

94 Target cooling temperature: {self.target_cooling_temperature}""") 

95 

96 @property 

97 def id(self) -> str: # pylint: disable=invalid-name 

98 """The id of the zone""" 

99 return self.data["id"] 

100 

101 @property 

102 def activity(self) -> ActivityName: 

103 """The configured activity""" 

104 return ActivityName(self.data["currentActivity"]) 

105 

106 @property 

107 def temperature(self) -> int: 

108 """The temperature""" 

109 return int(self.data["rt"]) 

110 

111 @property 

112 def relative_humidity(self) -> int: 

113 """The relative humidity""" 

114 return int(self.data["rh"]) 

115 

116 @property 

117 def fan_speed(self) -> FanSpeed: 

118 """The configured fan speed""" 

119 return FanSpeed(self.data["fan"]) 

120 

121 @property 

122 def target_heating_temperature(self) -> int: 

123 """The configured target heating temperature""" 

124 return int(self.data["htsp"]) 

125 

126 @property 

127 def target_cooling_temperature(self) -> int: 

128 """The configured target cooling temperature""" 

129 return int(self.data["clsp"])