Skip to content

Commit

Permalink
Add another service call to switch hot water off
Browse files Browse the repository at this point in the history
And add a load more operation modes for standard boost/off durations.
  • Loading branch information
tonyroberts committed Nov 15, 2023
1 parent 3b2255e commit adec825
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 34 deletions.
19 changes: 19 additions & 0 deletions custom_components/wundasmart/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,22 @@ hw_boost:
advanced: false
example: '00:30:00'
default: '00:30:00'
selector:
time:
hw_off:
name: Turn off hot water
description: Turns the water heater off for a specific amount of time.
target:
entity:
integration: wundasmart
domain: water_heater
fields:
duration:
name: Duration
description: Time to turn the water heater off for.
required: true
advanced: false
example: '00:30:00'
default: '00:30:00'
selector:
time:
26 changes: 26 additions & 0 deletions custom_components/wundasmart/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,32 @@
}
}
}
},
"water_heater": {
"wundasmart": {
"state": {
"auto": "Auto",
"auto_on": "On (Auto)",
"auto_off": "Off (Auto)",
"boost_on": "On",
"off": "Off"
},
"state_attributes": {
"operation_mode": {
"state": {
"auto": "Auto",
"boost_30": "Boost (30 mins)",
"boost_60": "Boost (1 hour)",
"boost_90": "Boost (1.5 hours)",
"boost_120": "Boost (2 hours)",
"off_30": "Off (30 mins)",
"off_60": "Off (1 hour)",
"off_90": "Off (1.5 hours)",
"off_120": "Off (2 hours)"
}
}
}
}
}
}
}
115 changes: 81 additions & 34 deletions custom_components/wundasmart/water_heater.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,49 @@

SUPPORTED_FEATURES = WaterHeaterEntityFeature.ON_OFF | WaterHeaterEntityFeature.OPERATION_MODE

STATE_AUTO_ON = "On (Auto)"
STATE_AUTO_OFF = "Off (Auto)"
STATE_BOOST_ON = "On (Boost)"
STATE_BOOST_OFF = "Off (Manual)"
STATE_AUTO = "Auto"

HW_BOOST_TIME = 60 * 30 # boost for 30 minutes
HW_OFF_TIME = 60 * 60 # switch off for 1 hour

OPERATION_SET_AUTO = "Auto"
OPERATION_BOOST_ON = "Boost (30 mins)"
OPERATION_BOOST_OFF = "Off (1 hour)"
STATE_AUTO_ON = "auto_on"
STATE_AUTO_OFF = "auto_off"
STATE_BOOST_ON = "boost_on"
STATE_OFF = "boost_off"
STATE_AUTO = "auto"

OPERATION_SET_AUTO = "auto"
OPERATION_BOOST_30 = "boost_30"
OPERATION_BOOST_60 = "boost_60"
OPERATION_BOOST_90 = "boost_90"
OPERATION_BOOST_120 = "boost_120"
OPERATION_OFF_30 = "off_30"
OPERATION_OFF_60 = "off_60"
OPERATION_OFF_90 = "off_90"
OPERATION_OFF_120 = "off_90"

HW_BOOST_OPERATIONS = {
OPERATION_BOOST_30,
OPERATION_BOOST_60,
OPERATION_BOOST_90,
OPERATION_BOOST_120
}

HW_OFF_OPERATIONS = {
OPERATION_OFF_30,
OPERATION_OFF_60,
OPERATION_OFF_90,
OPERATION_OFF_120
}

HW_BOOST_TIME = {
OPERATION_BOOST_30: 30 * 60,
OPERATION_BOOST_60: 60 * 60,
OPERATION_BOOST_90: 90 * 60,
OPERATION_BOOST_120: 120 * 60
}

HW_OFF_TIME = {
OPERATION_OFF_30: 30 * 60,
OPERATION_OFF_60: 60 * 60,
OPERATION_OFF_90: 90 * 60,
OPERATION_OFF_120: 120 * 60
}


async def async_setup_entry(
Expand Down Expand Up @@ -80,15 +111,19 @@ async def async_setup_entry(
"async_set_boost",
)

platform.async_register_entity_service(
"hw_off",
{
vol.Required("duration"): cv.positive_time_period
},
"async_set_off",
)


class Device(CoordinatorEntity[WundasmartDataUpdateCoordinator], WaterHeaterEntity):
"""Representation of an Wundasmart water heater."""

_attr_operation_list = [
OPERATION_SET_AUTO,
OPERATION_BOOST_ON,
OPERATION_BOOST_OFF
]
_attr_operation_list = list({ OPERATION_SET_AUTO } | HW_BOOST_OPERATIONS | HW_OFF_OPERATIONS)
_attr_supported_features = WaterHeaterEntityFeature.OPERATION_MODE
_attr_temperature_unit = TEMP_CELSIUS
_attr_translation_key = DOMAIN
Expand Down Expand Up @@ -141,7 +176,7 @@ def __update_state(self):
if hw_mode_state:
self._attr_current_operation = STATE_BOOST_ON if hw_boost_state else STATE_AUTO_ON
else:
self._attr_current_operation = STATE_BOOST_OFF if hw_boost_state else STATE_AUTO_OFF
self._attr_current_operation = STATE_OFF if hw_boost_state else STATE_AUTO_OFF

@callback
def _handle_coordinator_update(self) -> None:
Expand All @@ -155,33 +190,45 @@ async def async_added_to_hass(self) -> None:
self._handle_coordinator_update()

async def async_set_operation_mode(self, operation_mode: str) -> None:
if operation_mode == OPERATION_BOOST_OFF:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_off_time": HW_OFF_TIME
})
elif operation_mode == OPERATION_BOOST_ON:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_boost_time": HW_BOOST_TIME
})
elif operation_mode == OPERATION_SET_AUTO:
if operation_mode:
if operation_mode in HW_OFF_OPERATIONS:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_off_time": HW_OFF_TIME[operation_mode]
})
elif operation_mode in HW_BOOST_OPERATIONS:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_boost_time": HW_BOOST_TIME[operation_mode]
})
elif operation_mode == OPERATION_SET_AUTO:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_boost_time": 0
})
else:
raise NotImplementedError(f"Unsupported operation mode {operation_mode}")

# Fetch the updated state
await self.coordinator.async_request_refresh()

async def async_set_boost(self, duration: timedelta):
seconds = int((duration.days * 24 * 3600) + math.ceil(duration.seconds))
if seconds > 0:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_boost_time": 0
"hw_boost_time": seconds
})
else:
raise NotImplementedError(f"Unsupported operation mode {operation_mode}")

# Fetch the updated state
await self.coordinator.async_request_refresh()

async def async_set_boost(self, duration: timedelta):
async def async_set_off(self, duration: timedelta):
seconds = int((duration.days * 24 * 3600) + math.ceil(duration.seconds))
if seconds > 0:
await send_command(self._session, self._wunda_ip, self._wunda_user, self._wunda_pass, params={
"cmd": 3,
"hw_boost_time": seconds
"hw_off_time": seconds
})

# Fetch the updated state
Expand Down

0 comments on commit adec825

Please sign in to comment.