Skip to content

Commit

Permalink
Merge pull request #122 from TLongstride/cooling
Browse files Browse the repository at this point in the history
Add Full compatibility with Icon heating and cooling system
  • Loading branch information
MTrab committed Jun 3, 2024
2 parents f7058a7 + e0a9bea commit f2d5895
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 9 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,3 @@ See: [Usage.md](Usage.md)
## Known issues

- Inconsistency between API and app, devices are not updating correctly between API and app and sometimes the devices renders offline in the app - this is a Danfoss issue and not this integration
- Floorheating modules (Icon) are not reporting the actual room temperature in the API - this is a Danfoss issue and not this integration
7 changes: 7 additions & 0 deletions Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,11 @@ Possible values:

 

#### Thermal Actuator _(\*2)_

With this binary sensor, you can know if the Thermal Actuator is open or closed. The HVAC Action is base one this state.

 

_(\*1): Radiator only_
_(\*2): Icon only_
41 changes: 41 additions & 0 deletions custom_components/danfoss_ally/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,36 @@ async def async_setup_entry(
)
]
)
if "boiler_relay" in ally.devices[device]:
_LOGGER.debug(
"Found boiler relay_detector for %s", ally.devices[device]["name"]
)
entities.extend(
[
AllyBinarySensor(
ally,
ally.devices[device]["name"],
device,
"boiler relay",
ally.devices[device]["model"],
)
]
)
if "output_status" in ally.devices[device]:
_LOGGER.debug(
"Found output_status_detector for %s", ally.devices[device]["name"]
)
entities.extend(
[
AllyBinarySensor(
ally,
ally.devices[device]["name"],
device,
"Thermal actuator",
ally.devices[device]["model"],
)
]
)
if "adaptation_runstatus" in ally.devices[device]:
_LOGGER.debug(
"Found adaptation_runstatus for %s", ally.devices[device]["name"]
Expand Down Expand Up @@ -216,6 +246,11 @@ def __init__(self, ally, name, device_id, device_type, model):
self.entity_description = BinarySensorEntityDescription(
key=4, icon="mdi:gas-burner", entity_registry_enabled_default=False
)
elif self._type == "Thermal actuator":
self._state = self._device["output_status"]
self.entity_description = BinarySensorEntityDescription(
key=4, icon="mdi:pipe-valve"
)
elif self._type == "adaptation run status":
self._state = bool(int(self._device["adaptation_runstatus"]) & 0x01)
self.entity_description = BinarySensorEntityDescription(
Expand Down Expand Up @@ -278,6 +313,8 @@ def device_class(self):
return BinarySensorDeviceClass.HEAT
elif self._type == "adaptation run status":
return BinarySensorDeviceClass.RUNNING
elif self._type == "Thermal actuator":
return BinarySensorDeviceClass.OPENING
return None

@callback
Expand Down Expand Up @@ -312,6 +349,10 @@ def _async_update_data(self):
self._state = self._device["mounting_mode_active"]
elif self._type == "heat supply request":
self._state = self._device["heat_supply_request"]
elif self._type == "boiler relay":
self._state = self._device["boiler_relay"]
elif self._type == "Thermal actuator":
self._state = self._device["output_status"]
elif self._type == "adaptation run status":
self._state = bool(int(self._device["adaptation_runstatus"]) & 0x01)
elif self._type == "adaptation run valve characteristic found":
Expand Down
114 changes: 106 additions & 8 deletions custom_components/danfoss_ally/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
from homeassistant.components.climate.const import ( # SUPPORT_PRESET_MODE,; SUPPORT_TARGET_TEMPERATURE,
ATTR_HVAC_MODE,
ATTR_PRESET_MODE,
CURRENT_HVAC_HEAT,
CURRENT_HVAC_COOL,
CURRENT_HVAC_IDLE,
HVAC_MODE_AUTO,
HVAC_MODE_HEAT,
HVAC_MODE_COOL,
HVAC_MODE_OFF,
HVACAction,
PRESET_AWAY,
PRESET_HOME,
Expand Down Expand Up @@ -488,17 +495,99 @@ def __init__(
support_flags,
)

@property
def hvac_mode(self):
"""Return hvac operation ie. heat, cool mode.
Need to be one of HVAC_MODE_*.
"""
if "mode" in self._device:
if (
self._device["mode"] == "at_home"
or self._device["mode"] == "leaving_home"
or self._device["mode"] == "holiday_sat"
or self._device["mode"] == "holiday"
or self._device["mode"] == "pause"
):
return HVAC_MODE_AUTO
elif (
self._device["work_state"] == "Heat"
or self._device["work_state"] == "heat_active"
):
if self._device["manual_mode_fast"] == self._device["lower_temp"]:
return HVAC_MODE_OFF
else:
return HVAC_MODE_HEAT
elif (
self._device["work_state"] == "Cool"
or self._device["work_state"] == "cool_active"
):
if self._device["manual_mode_fast"] == self._device["upper_temp"]:
return HVAC_MODE_OFF
else:
return HVAC_MODE_COOL
@callback
def _async_update_callback(self):
"""Load data and update state."""
self._async_update_data()
self.async_write_ha_state()

def set_hvac_mode(self, hvac_mode):
"""Set new target hvac mode."""

_LOGGER.debug("Setting hvac mode to %s", hvac_mode)

if hvac_mode == HVAC_MODE_AUTO:
mode = "at_home" # We have to choose either at_home or leaving_home
manual_set = self._device["at_home_setting"]
elif hvac_mode == HVAC_MODE_HEAT:
mode = "manual"
manual_set = self._device["leaving_home_setting"]
elif hvac_mode == HVAC_MODE_COOL:
mode = "manual"
manual_set = self._device["at_home_setting"]
elif hvac_mode == HVAC_MODE_OFF:
mode = "manual"
if (
self._device["work_state"] == "heat_active"
or self._device["work_state"] == "Heat"
):
manual_set = self._device["lower_temp"]
elif (
self._device["work_state"] == "cool_active"
or self._device["work_state"] == "Cool"
):
manual_set = self._device["upper_temp"]

if mode is None:
return

self._device["mode"] = mode # Update current copy of device data
self._device["manual_mode_fast"] = manual_set
self._ally.set_mode(self._device_id, mode)
self._ally.set_temperature(self._device_id, manual_set)

# Update UI
self.async_write_ha_state()

@property
def hvac_action(self):
"""Return the current running hvac operation if supported.
Need to be one of HVACAction.*
"""
if "work_state" in self._device:
if self._device["work_state"] == "heat_active":
return HVACAction.HEATING
elif self._device["work_state"] == "Heat":
return HVACAction.IDLE

if "output_status" in self._device:
if self._device["output_status"] == True:
if (
self._device["work_state"] == "Heat"
or self._device["work_state"] == "heat_active"
):
return CURRENT_HVAC_HEAT
elif (
self._device["work_state"] == "Cool"
or self._device["work_state"] == "cool_active"
):
return CURRENT_HVAC_COOL
elif self._device["output_status"] == False:
return CURRENT_HVAC_IDLE

async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities
Expand Down Expand Up @@ -535,7 +624,6 @@ async def async_setup_entry(
if entities:
async_add_entities(entities, True)


def _generate_entities(ally: AllyConnector):
"""Create all climate entities."""
_LOGGER.debug("Setting up Danfoss Ally climate entities")
Expand All @@ -561,7 +649,17 @@ def create_climate_entity(ally, name: str, device_id: str, model: str) -> AllyCl
support_flags = (
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
)
supported_hvac_modes = [HVACMode.AUTO, HVACMode.HEAT]

if model == "Icon RT":
supported_hvac_modes = [
HVAC_MODE_AUTO,
HVAC_MODE_HEAT,
HVAC_MODE_COOL,
HVAC_MODE_OFF,
]
else:
supported_hvac_modes = [HVAC_MODE_AUTO, HVAC_MODE_HEAT]

heat_min_temp = 4.5
heat_max_temp = 35.0
heat_step = 0.5
Expand Down

0 comments on commit f2d5895

Please sign in to comment.