Skip to content

Commit 79d85fa

Browse files
authored
Merge pull request #33 from granvillebarker/add-c4-climate-and-fan
Add c4 climate and fan
2 parents a0cb2e8 + 16207b9 commit 79d85fa

2 files changed

Lines changed: 201 additions & 0 deletions

File tree

pyControl4/climate.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
"""Controls Control4 Climate Control devices."""
2+
3+
from pyControl4 import C4Entity
4+
5+
6+
class C4Climate(C4Entity):
7+
# ------------------------
8+
# HVAC and Fan States
9+
# ------------------------
10+
11+
async def getHVACState(self):
12+
"""Returns the current HVAC state (e.g., on/off or active mode)."""
13+
return await self.director.getItemVariableValue(self.item_id,
14+
"HVAC_STATE")
15+
16+
async def getFANState(self):
17+
"""Returns the current power state of the fan (True=on, False=off)."""
18+
return await self.director.getItemVariableValue(self.item_id,
19+
"FAN_STATE")
20+
21+
# ------------------------
22+
# Mode Getters
23+
# ------------------------
24+
25+
async def getHVACMode(self):
26+
"""Returns the currently active HVAC mode."""
27+
return await self.director.getItemVariableValue(self.item_id,
28+
"HVAC_MODE")
29+
30+
async def getHVACModes(self):
31+
"""Returns a list of supported HVAC modes."""
32+
return await self.director.getItemVariableValue(self.item_id,
33+
"HVAC_MODES_LIST")
34+
35+
async def getFANMode(self):
36+
"""Returns the currently active fan mode."""
37+
return await self.director.getItemVariableValue(self.item_id,
38+
"FAN_MODE")
39+
40+
async def getFANModes(self):
41+
"""Returns a list of supported fan modes."""
42+
return await self.director.getItemVariableValue(self.item_id,
43+
"FAN_MODES_LIST")
44+
45+
# ------------------------
46+
# Setpoint Getters
47+
# ------------------------
48+
49+
async def getCoolSetpointF(self):
50+
"""Returns the cooling setpoint temperature in Fahrenheit."""
51+
return await self.director.getItemVariableValue(self.item_id,
52+
"COOL_SETPOINT_F")
53+
54+
async def getHeatSetpointF(self):
55+
"""Returns the heating setpoint temperature in Fahrenheit."""
56+
return await self.director.getItemVariableValue(self.item_id,
57+
"HEAT_SETPOINT_F")
58+
59+
# ------------------------
60+
# Sensor Readings
61+
# ------------------------
62+
63+
async def getHumidity(self):
64+
"""Returns the current humidity percentage."""
65+
return await self.director.getItemVariableValue(self.item_id,
66+
"HUMIDITY")
67+
68+
async def getCurrentTemperature(self):
69+
"""Returns the current ambient temperature in Fahrenheit."""
70+
return await self.director.getItemVariableValue(self.item_id,
71+
"TEMPERATURE_F")
72+
73+
# ------------------------
74+
# Setters / Commands
75+
# ------------------------
76+
77+
async def setTemperature(self, temp):
78+
"""Sets the cooling setpoint temperature in Fahrenheit."""
79+
await self.setCoolSetpoint(temp) # Delegates to the proper method
80+
81+
async def setCoolSetpoint(self, temp):
82+
"""Sets the cooling setpoint temperature in Fahrenheit."""
83+
await self.director.sendPostRequest(
84+
f"/api/v1/items/{self.item_id}/commands",
85+
"SET_SETPOINT_COOL",
86+
{"FAHRENHEIT": temp},
87+
)
88+
89+
async def setHeatSetpoint(self, temp):
90+
"""Sets the heating setpoint temperature in Fahrenheit."""
91+
await self.director.sendPostRequest(
92+
f"/api/v1/items/{self.item_id}/commands",
93+
"SET_SETPOINT_HEAT",
94+
{"FAHRENHEIT": temp},
95+
)
96+
97+
async def setHvacMode(self, mode):
98+
"""Sets the HVAC operating mode (e.g., heat, cool, auto)."""
99+
await self.director.sendPostRequest(
100+
f"/api/v1/items/{self.item_id}/commands",
101+
"SET_MODE_HVAC",
102+
{"MODE": mode},
103+
)
104+
105+
async def setFanMode(self, mode):
106+
"""Sets the fan operating mode (e.g., auto, on, circulate)."""
107+
await self.director.sendPostRequest(
108+
f"/api/v1/items/{self.item_id}/commands",
109+
"SET_MODE_FAN",
110+
{"MODE": mode},
111+
)
112+
113+
async def setPreset(self, preset):
114+
"""Applies a predefined climate preset by name."""
115+
await self.director.sendPostRequest(
116+
f"/api/v1/items/{self.item_id}/commands",
117+
"SET_PRESET",
118+
{"NAME": preset},
119+
)

pyControl4/fan.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""Controls Control4 Fan devices."""
2+
3+
from pyControl4 import C4Entity
4+
5+
6+
class C4Fan(C4Entity):
7+
# ------------------------
8+
# Fan State Getters
9+
# ------------------------
10+
11+
async def getState(self):
12+
"""
13+
Returns the current power state of the fan.
14+
15+
Returns:
16+
bool: True if the fan is on, False otherwise.
17+
"""
18+
value = await self.director.getItemVariableValue(self.item_id, "IS_ON")
19+
return bool(value)
20+
21+
async def getSpeed(self):
22+
"""
23+
Returns the current speed of the fan controller.
24+
25+
Valid speed values:
26+
0 - Off
27+
1 - Low
28+
2 - Medium
29+
3 - Medium High
30+
4 - High
31+
32+
Note:
33+
Only valid for fan controllers. On non-dimmer switches,
34+
use `getState()` instead.
35+
36+
Returns:
37+
int: Current fan speed (0–4).
38+
"""
39+
value = await self.director.getItemVariableValue(self.item_id,
40+
"CURRENT_SPEED")
41+
return int(value)
42+
43+
# ------------------------
44+
# Fan Control Setters
45+
# ------------------------
46+
47+
async def setSpeed(self, speed: int):
48+
"""
49+
Sets the fan speed or turns it off.
50+
51+
Parameters:
52+
speed (int): Fan speed level:
53+
0 - Off
54+
1 - Low
55+
2 - Medium
56+
3 - Medium High
57+
4 - High
58+
"""
59+
await self.director.sendPostRequest(
60+
f"/api/v1/items/{self.item_id}/commands",
61+
"SET_SPEED",
62+
{"SPEED": speed},
63+
)
64+
65+
async def setPreset(self, preset: int):
66+
"""
67+
Sets the fan's preset speed — the speed used when the fan is
68+
turned on without specifying speed.
69+
70+
Parameters:
71+
preset (int): Preset fan speed level:
72+
0 - Off
73+
1 - Low
74+
2 - Medium
75+
3 - Medium High
76+
4 - High
77+
"""
78+
await self.director.sendPostRequest(
79+
f"/api/v1/items/{self.item_id}/commands",
80+
"DESIGNATE_PRESET",
81+
{"PRESET": preset},
82+
)

0 commit comments

Comments
 (0)