Skip to content

Commit

Permalink
Boost switches
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew-codechimp committed Apr 9, 2024
1 parent 9864f99 commit 9031ebe
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 59 deletions.
2 changes: 1 addition & 1 deletion custom_components/hive_local_thermostat/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@
DEFAULT_HEATING_BOOST_TEMPERATURE = 25
DEFAULT_WATER_BOOST_MINUTES = 60

WATER_MODES: Final = ["auto", "heat", "off", "emergency_heat"]
WATER_MODES: Final = ["auto", "heat", "off", "boost"]

ICON_UNKNOWN = "mdi:help"
157 changes: 110 additions & 47 deletions custom_components/hive_local_thermostat/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,20 @@
MODEL_SLR2,
)


@dataclass
class HiveSwitchEntityDescription(
HiveEntityDescription,
SwitchEntityDescription,
):
"""Class describing Hive sensor entities."""


async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback
):
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
"""Set up the sensor platform."""

entity_descriptions = [
Expand All @@ -50,36 +52,41 @@ async def async_setup_entry(
translation_key="boost_heating",
icon="mdi:radiator",
name=config_entry.title,
func=lambda js: js["running_state_heat"],
func=lambda js: js["system_mode_heat"],
topic=config_entry.options[CONF_MQTT_TOPIC],
entry_id=config_entry.entry_id,
model=config_entry.options[CONF_MODEL],
),
]

if config_entry.options[CONF_MODEL] == MODEL_SLR2:
entity_descriptions.append(HiveSwitchEntityDescription(
key="boost_water",
translation_key="boost_water",
icon="mdi:water-boiler",
name=config_entry.title,
func=lambda js: js["running_state_water"],
topic=config_entry.options[CONF_MQTT_TOPIC],
entry_id=config_entry.entry_id,
model=config_entry.options[CONF_MODEL],
entity_descriptions.append(
HiveSwitchEntityDescription(
key="boost_water",
translation_key="boost_water",
icon="mdi:water-boiler",
name=config_entry.title,
func=lambda js: js["system_mode_water"],
topic=config_entry.options[CONF_MQTT_TOPIC],
entry_id=config_entry.entry_id,
model=config_entry.options[CONF_MODEL],
)
)

_entities = {}

_entities = [HiveSwitch(entity_description=entity_description,) for entity_description in entity_descriptions]
_entities = [
HiveSwitch(
entity_description=entity_description,
)
for entity_description in entity_descriptions
]

async_add_entities(
sensorEntity for sensorEntity in _entities
)
async_add_entities(sensorEntity for sensorEntity in _entities)

hass.data[DOMAIN][config_entry.entry_id][Platform.SWITCH] = _entities


class HiveSwitch(HiveEntity, SwitchEntity):
"""hive_local_thermostat Switch class."""

Expand All @@ -90,7 +97,9 @@ def __init__(
"""Initialize the switch class."""

self.entity_description = entity_description
self._attr_unique_id = f"{DOMAIN}_{entity_description.name}_{entity_description.key}".lower()
self._attr_unique_id = (
f"{DOMAIN}_{entity_description.name}_{entity_description.key}".lower()
)
self._attr_has_entity_name = True
self._func = entity_description.func
self._topic = entity_description.topic
Expand All @@ -104,7 +113,9 @@ def process_update(self, mqtt_data) -> None:

self._attr_is_on = self._func(mqtt_data) == "emergency_heating"

if (self.hass is not None): # this is a hack to get around the fact that the entity is not yet initialized at first
if (
self.hass is not None
): # this is a hack to get around the fact that the entity is not yet initialized at first
self.async_schedule_update_ha_state()

@property
Expand All @@ -119,14 +130,33 @@ async def async_turn_on(self, **kwargs: Any) -> None:
self._pre_boost_mqtt_data = self._mqtt_data

if self.entity_description.key == "boost_water":
payload = (r'{"system_mode_water":"emergency_heating","temperature_setpoint_hold_duration_water":' +
str(self.get_entity_value("water_boost_duration", DEFAULT_WATER_BOOST_MINUTES)) +
r',"temperature_setpoint_hold_water":1}')
payload = (
r'{"system_mode_water":"emergency_heating","temperature_setpoint_hold_duration_water":'
+ str(
self.get_entity_value(
"water_boost_duration", DEFAULT_WATER_BOOST_MINUTES
)
)
+ r',"temperature_setpoint_hold_water":1}'
)
elif self.entity_description.key == "boost_heating":
payload = (r'{"system_mode_heat":"emergency_heating","temperature_setpoint_hold_duration_heat":' +
str(int(self.get_entity_value("heating_boost_duration", DEFAULT_HEATING_BOOST_MINUTES))) +
r',"temperature_setpoint_hold_heat":1,"occupied_heating_setpoint_heat":' +
str(self.get_entity_value("heating_boost_temperature", DEFAULT_HEATING_BOOST_TEMPERATURE)) + r'}')
payload = (
r'{"system_mode_heat":"emergency_heating","temperature_setpoint_hold_duration_heat":'
+ str(
int(
self.get_entity_value(
"heating_boost_duration", DEFAULT_HEATING_BOOST_MINUTES
)
)
)
+ r',"temperature_setpoint_hold_heat":1,"occupied_heating_setpoint_heat":'
+ str(
self.get_entity_value(
"heating_boost_temperature", DEFAULT_HEATING_BOOST_TEMPERATURE
)
)
+ r"}"
)

LOGGER.debug("Sending to {self._topic}/set message {payload}")
await mqtt_client.async_publish(self.hass, self._topic + "/set", payload)
Expand All @@ -140,44 +170,77 @@ async def async_turn_off(self, **kwargs: Any) -> None:
if self.entity_description.key == "boost_water":
payload = None

if self._pre_boost_mqtt_data["system_mode_water"] == "auto":
payload = r'{"system_mode_water":"heat","temperature_setpoint_hold_water":"0","temperature_setpoint_hold_duration_water":"0"}'
elif self._pre_boost_mqtt_data["system_mode_water"] == "heat":
payload = r'{"system_mode_water":"heat","temperature_setpoint_hold_water":1}'
if self._pre_boost_mqtt_data["system_mode_water"] == "heat":
payload = (
r'{"system_mode_water":"heat"'
+ r',"temperature_setpoint_hold_water":'
+ self._pre_boost_mqtt_data["temperature_setpoint_hold_water"]
+ r',"temperature_setpoint_hold_duration_water":'
+ self._pre_boost_mqtt_data[
"temperature_setpoint_hold_duration_water"
]
+ r"}"
)
elif self._pre_boost_mqtt_data["system_mode_water"] == "off":
payload = r'{"system_mode_water":"off","temperature_setpoint_hold_water":0}'
payload = (
r'{"system_mode_water":"off","temperature_setpoint_hold_water":0}'
)

if payload:
LOGGER.debug("Sending to {self._topic}/set message {payload}")
await mqtt_client.async_publish(self.hass, self._topic + "/set", payload)
await mqtt_client.async_publish(
self.hass, self._topic + "/set", payload
)

elif self.entity_description.key == "boost_heating":

if not self._pre_boost_mqtt_data:
return

if self._pre_boost_mqtt_data["system_mode_heat"] == "off":
payload = r'{"system_mode_heat":"off","temperature_setpoint_hold_heat":"0"}'
payload = (
r'{"system_mode_heat":"off","temperature_setpoint_hold_heat":"0"}'
)
LOGGER.debug("Sending to {self._topic}/set message {payload}")
await mqtt_client.async_publish(self.hass, self._topic + "/set", payload)
await mqtt_client.async_publish(
self.hass, self._topic + "/set", payload
)

sleep(0.5)

payload = r'{"occupied_heating_setpoint_heat":' + str(self.get_entity_value("heating_frost_prevention", DEFAULT_FROST_TEMPERATURE)) + r',"temperature_setpoint_hold_heat":"1","temperature_setpoint_hold_duration_heat:"65535"}'
payload = (
r'{"occupied_heating_setpoint_heat":'
+ str(
self.get_entity_value(
"heating_frost_prevention", DEFAULT_FROST_TEMPERATURE
)
)
+ r',"temperature_setpoint_hold_heat":"1","temperature_setpoint_hold_duration_heat:"65535"}'
)
LOGGER.debug("Sending to {self._topic}/set message {payload}")
await mqtt_client.async_publish(self.hass, self._topic + "/set", payload)
await mqtt_client.async_publish(
self.hass, self._topic + "/set", payload
)
self._attr_is_on = True
else:
payload = (r'{"system_mode_heat":"' +
self._pre_boost_mqtt_data["system_mode_heat"] +
r'","occupied_heating_setpoint_heat":' +
self._pre_boost_mqtt_data["occupied_heating_setpoint_heat"] +
r',"temperature_setpoint_hold_heat":' +
self._pre_boost_mqtt_data["temperature_setpoint_hold_heat"] +
r'","temperature_setpoint_hold_duration_heat":' +
self._pre_boost_mqtt_data["temperature_setpoint_hold_duration_heat"] + r'}')
payload = (
r'{"system_mode_heat":"'
+ self._pre_boost_mqtt_data["system_mode_heat"]
+ r'","occupied_heating_setpoint_heat":'
+ self._pre_boost_mqtt_data["occupied_heating_setpoint_heat"]
+ r',"temperature_setpoint_hold_heat":'
+ self._pre_boost_mqtt_data["temperature_setpoint_hold_heat"]
+ r'","temperature_setpoint_hold_duration_heat":'
+ self._pre_boost_mqtt_data[
"temperature_setpoint_hold_duration_heat"
]
+ r"}"
)

LOGGER.debug("Sending to {self._topic}/set message {payload}")
await mqtt_client.async_publish(self.hass, self._topic + "/set", payload)
await mqtt_client.async_publish(
self.hass, self._topic + "/set", payload
)

self._attr_is_on = False
self._attr_is_on = False
self.async_write_ha_state()
22 changes: 11 additions & 11 deletions custom_components/hive_local_thermostat/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@
"entity": {
"sensor": {
"running_state_water": {
"name": "Running State Water",
"name": "Running state water",
"state": {
"off": "Off",
"idle": "Idle",
"heat": "Heating"
}
},
"running_state_heat": {
"name": "Running State Heat",
"name": "Running state heat",
"state": {
"off": "Off",
"idle": "Idle",
Expand All @@ -67,30 +67,30 @@
},
"select": {
"system_mode_water": {
"name": "Water Mode",
"name": "Water mode",
"state": {
"off": "Always Off",
"off": "Always off",
"auto": "Schedule",
"heat": "Always On",
"emergency_heat": "Boost"
"heat": "Always on",
"boost": "Boost"
}
}
},
"number": {
"heating_boost_duration": {
"name": "Heating Boost Duration"
"name": "Heating boost duration"
},
"water_boost_duration": {
"name": "Water Boost Duration"
"name": "Water boost duration"
},
"heating_frost_prevention": {
"name": "Heating Frost Prevention"
"name": "Heating frost prevention"
},
"heating_default_temperature": {
"name": "Heating Default Temperature"
"name": "Heating default temperature"
},
"heating_boost_temperature": {
"name": "Heating Boost Temperature"
"name": "Heating boost temperature"
}
},
"switch": {
Expand Down

0 comments on commit 9031ebe

Please sign in to comment.