Coverage for python_carrier_infinity/config.py: 100%

68 statements  

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

1"""Accessing and changing the config""" 

2from __future__ import annotations 

3from textwrap import dedent, indent 

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

5 

6 

7class System: 

8 """Represents the top-level system config""" 

9 

10 def __init__(self, data: dict): 

11 self.data = data 

12 

13 def __str__(self) -> str: 

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

15 return dedent( 

16 f"""\ 

17 Temperature units: {self.temperature_units} 

18 HVAC mode: {self.mode} 

19 Zones:""") \ 

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

21 

22 @property 

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

24 """The config of all enabled zones""" 

25 zones = {} 

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

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

28 continue 

29 zone = Zone(zone_data) 

30 zones[zone.id] = zone 

31 return zones 

32 

33 @property 

34 def temperature_units(self) -> TemperatureUnits: 

35 """The temperature units used""" 

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

37 

38 @property 

39 def mode(self) -> Mode: 

40 """The HVAC mode""" 

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

42 

43 

44class Zone: 

45 """Represents the config of a zone""" 

46 

47 def __init__(self, data: dict): 

48 self.data = data 

49 

50 def __str__(self) -> str: 

51 activities = "\n\n".join([str(activity) for activity in self.activities.values()]) 

52 return dedent( 

53 f"""\ 

54 ID: {self.id} 

55 Name: {self.name} 

56 Hold activity: {self.hold_activity} 

57 Hold until: {self.hold_until} 

58 Activities:""") \ 

59 + "\n" + indent(activities, " ") 

60 

61 @property 

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

63 """The id of the zone""" 

64 return self.data["id"] 

65 

66 @property 

67 def name(self) -> str: 

68 """The name of the zone""" 

69 return self.data["name"] 

70 

71 @property 

72 def hold_activity(self) -> ActivityName | None: 

73 """The currently held activity""" 

74 if self.data["hold"] == "on": 

75 return ActivityName(self.data["holdActivity"]) 

76 else: 

77 return None 

78 

79 @property 

80 def hold_until(self) -> str | None: 

81 """The time by which the hold expires; None if hold is indefinite""" 

82 return self.data["otmr"] 

83 

84 @property 

85 def activities(self) -> dict[ActivityName, Activity]: 

86 """The configs for each activity""" 

87 activities = {} 

88 

89 for activity_data in self.data["activities"]: 

90 activity = Activity(activity_data) 

91 activities[activity.name] = activity 

92 return activities 

93 

94 

95class Activity: 

96 """Represents the config of an activity""" 

97 

98 def __init__(self, data: dict): 

99 self.data = data 

100 

101 def __str__(self) -> str: 

102 return dedent( 

103 f"""\ 

104 {self.name} 

105 Fan speed: {self.fan_speed} 

106 Target heating temperature: {self.target_heating_temperature} 

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

108 

109 @property 

110 def name(self) -> ActivityName: 

111 """The activity name""" 

112 return ActivityName(self.data["type"]) 

113 

114 @property 

115 def fan_speed(self) -> FanSpeed: 

116 """The fan speed""" 

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

118 

119 @property 

120 def target_heating_temperature(self) -> int: 

121 """The target heating temperature""" 

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

123 

124 @property 

125 def target_cooling_temperature(self) -> int: 

126 """The target cooling temperature""" 

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