Skip to content

Commit

Permalink
Add Pilote Pro
Browse files Browse the repository at this point in the history
  • Loading branch information
cyr-ius committed Nov 30, 2024
1 parent 24de0c8 commit f3e4fc3
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 21 deletions.
132 changes: 113 additions & 19 deletions custom_components/heatzy/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@
ECO_TEMP_L,
FROST_TEMP,
GLOW,
PILOTE_PRO_V1,
PILOTE_V1,
PILOTE_V2,
PILOTE_V3,
PRESET_COMFORT_1,
PRESET_COMFORT_2,
SAUTER,
)

SERVICES = [
Expand Down Expand Up @@ -89,12 +90,15 @@ async def async_setup_entry(
entities.append(HeatzyPiloteV1Thermostat(coordinator, unique_id))
elif product_key in PILOTE_V2:
entities.append(HeatzyPiloteV2Thermostat(coordinator, unique_id))
elif product_key in PILOTE_V3:
entities.append(HeatzyPiloteV3Thermostat(coordinator, unique_id))
elif product_key in GLOW:
entities.append(Glowv1Thermostat(coordinator, unique_id))
elif product_key in BLOOM:
entities.append(Bloomv1Thermostat(coordinator, unique_id))
elif product_key in SAUTER:
entities.append(SauterThermostat(coordinator, unique_id))
elif product_key in PILOTE_PRO_V1:
entities.append(HeatzyPiloteProV1(coordinator, unique_id))

async_add_entities(entities)


Expand Down Expand Up @@ -375,6 +379,33 @@ async def _async_derog_mode(self, mode: int, delay: int) -> None:
_LOGGER.error("Error to set derog mode: %s (%s)", mode, error)


class HeatzyPiloteV3Thermostat(HeatzyPiloteV2Thermostat):
"""Pilote_Soc_C3, Elec_Pro_Ble, Sauter."""

_attr_preset_modes = [
PRESET_COMFORT,
PRESET_ECO,
PRESET_AWAY,
PRESET_COMFORT_1,
PRESET_COMFORT_2,
]

HEATZY_TO_HA_STATE = {
"cft": PRESET_COMFORT,
"eco": PRESET_ECO,
"fro": PRESET_AWAY,
"cft1": PRESET_COMFORT_1,
"cft2": PRESET_COMFORT_2,
}
HA_TO_HEATZY_STATE = {
PRESET_COMFORT: "cft",
PRESET_ECO: "eco",
PRESET_AWAY: "fro",
PRESET_COMFORT_1: "cft1",
PRESET_COMFORT_2: "cft2",
}


class Glowv1Thermostat(HeatzyPiloteV2Thermostat):
"""Glow."""

Expand Down Expand Up @@ -610,28 +641,91 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
_LOGGER.error("Error to set temperature (%s)", error)


class SauterThermostat(HeatzyPiloteV2Thermostat):
"""Sauter."""
class HeatzyPiloteProV1(HeatzyPiloteV2Thermostat):
"""Heatzy Pilote Pro."""

_attr_target_temperature_step = 1
_attr_supported_features = (
ClimateEntityFeature.PRESET_MODE
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF
)
_attr_preset_modes = [
PRESET_BOOST,
PRESET_COMFORT,
PRESET_ECO,
PRESET_AWAY,
PRESET_COMFORT_1,
PRESET_COMFORT_2,
]

HEATZY_TO_HA_STATE = {
"cft": PRESET_COMFORT,
"eco": PRESET_ECO,
"fro": PRESET_AWAY,
"cft1": PRESET_COMFORT_1,
"cft2": PRESET_COMFORT_2,
}
HA_TO_HEATZY_STATE = {
PRESET_COMFORT: "cft",
PRESET_ECO: "eco",
PRESET_AWAY: "fro",
PRESET_COMFORT_1: "cft1",
PRESET_COMFORT_2: "cft2",
}
@property
def current_temperature(self) -> float:
"""Return current temperature."""
return self._attr.get(CONF_CUR_TEMP) / 10

@property
def target_temperature_high(self) -> float:
"""Return comfort temperature."""
return self._attr.get(CONF_CFT_TEMP) / 10

@property
def target_temperature_low(self) -> float:
"""Return echo temperature."""
return self._attr.get(CONF_ECO_TEMP) / 10

@property
def target_temperature(self) -> float | None:
"""Return target temperature for mode."""
# Target temp is set to Low/High/Away value according to the current [preset] mode
if self.hvac_mode == HVACMode.OFF:
return None
if self.preset_mode == PRESET_ECO:
return self.target_temperature_low
if self.preset_mode == PRESET_COMFORT:
return self.target_temperature_high
if self.preset_mode == PRESET_AWAY:
return FROST_TEMP
return None

async def async_presence_detection_mode(self, delay: int) -> None:
"""Service Boost Mode."""
await self._async_derog_mode(3, delay)

async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if (temp_eco := kwargs.get(ATTR_TARGET_TEMP_LOW)) and (
temp_cft := kwargs.get(ATTR_TARGET_TEMP_HIGH)
):
self._attr[CONF_ECO_TEMP] = int(temp_eco) * 10
self._attr[CONF_CFT_TEMP] = int(temp_cft) * 10

try:
await self.coordinator.api.websocket.async_control_device(
self.unique_id,
{
CONF_ATTRS: {
CONF_CFT_TEMP: self._attr[CONF_CFT_TEMP],
CONF_ECO_TEMP: self._attr[CONF_ECO_TEMP],
}
},
)
except HeatzyException as error:
_LOGGER.error("Error to set temperature (%s)", error)

@property
def hvac_action(self) -> HVACAction:
"""Return hvac action ie. heat, cool mode."""
if self._attr.get(CONF_TIMER_SWITCH) == 1:
return HVACMode.AUTO
# If OFF then set HVAC Action to OFF
if self.hvac_mode == HVACMode.OFF:
return HVACAction.OFF
# If Target temp is higher than current temp then set HVAC Action to HEATING
if self.target_temperature and (
self.target_temperature > self.current_temperature
):
return HVACAction.HEATING
# Otherwise set to IDLE
return HVACAction.IDLE
12 changes: 10 additions & 2 deletions custom_components/heatzy/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,26 @@
PILOTE_V1 = ["9420ae048da545c88fc6274d204dd25f"]
PILOTE_V2 = [
"51d16c22a5f74280bc3cfe9ebcdc6402", # PILOTE2
"b9a67b6ce24b437d9794103fd317e627", # PILOTE_SOC
"4fc968a21e7243b390e9ede6f1c6465d", # PILOTE2_ELEC_PRO
"b9a67b6ce24b437d9794103fd317e627", # PILOTE_SOC
"b8c6657b66c34148b4dee64d615cefc7", # ELEC_PRO_SOC
]
PILOTE_V3 = [
"9dacde7ef459421eaf8dc4bea9385634", # ELEC_PRO_BLE
"46409c7f29d4411c85a3a46e5ee3703e", # Sauter PILOTE_SOC_C3
]

PILOTE_PRO_V1 = [
"a77a929fcf0d4631bc4f669080376891", # Pilote Pro
]


GLOW = [
"2fd622e45283470f9e27e8e6167d7533", # GLOW_SIMPLE
"bb10d064f8de409db633b750faa22a52", # ONYX
"fc89066ee74c4149a9beb37d4ea93604", # INEA
]
BLOOM = ["480253852d574f11b2d7fbf4460d7a41"] # BLOOM
SAUTER = ["46409c7f29d4411c85a3a46e5ee3703e"] # Sauter PILOTE_SOC_C3

# -- Not integrated --
# FLAM "f71ee820660f4f358db8b8a474689726"
Expand Down

0 comments on commit f3e4fc3

Please sign in to comment.