1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-15 07:36:16 +00:00

CoolMasterNet: Send wakeup prompt (#156116)

This commit is contained in:
ashalita
2025-12-18 19:59:35 +02:00
committed by GitHub
parent 6a868ca5cc
commit 78cc41fdc0
8 changed files with 66 additions and 23 deletions

View File

@@ -7,7 +7,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from .const import CONF_SWING_SUPPORT, DOMAIN
from .const import CONF_SEND_WAKEUP_PROMPT, CONF_SWING_SUPPORT, DOMAIN
from .coordinator import CoolmasterConfigEntry, CoolmasterDataUpdateCoordinator
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CLIMATE, Platform.SENSOR]
@@ -17,10 +17,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: CoolmasterConfigEntry) -
"""Set up Coolmaster from a config entry."""
host = entry.data[CONF_HOST]
port = entry.data[CONF_PORT]
send_wakeup_prompt = entry.data.get(CONF_SEND_WAKEUP_PROMPT, False)
if not entry.data.get(CONF_SWING_SUPPORT):
coolmaster = CoolMasterNet(
host,
port,
send_initial_line_feed=send_wakeup_prompt,
)
else:
# Swing support adds an additional request per unit. The requests are
@@ -29,6 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: CoolmasterConfigEntry) -
coolmaster = CoolMasterNet(
host,
port,
send_initial_line_feed=send_wakeup_prompt,
read_timeout=5,
swing_support=True,
)

View File

@@ -12,7 +12,13 @@ from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.core import callback
from .const import CONF_SUPPORTED_MODES, CONF_SWING_SUPPORT, DEFAULT_PORT, DOMAIN
from .const import (
CONF_SEND_WAKEUP_PROMPT,
CONF_SUPPORTED_MODES,
CONF_SWING_SUPPORT,
DEFAULT_PORT,
DOMAIN,
)
AVAILABLE_MODES = [
HVACMode.OFF.value,
@@ -25,17 +31,15 @@ AVAILABLE_MODES = [
MODES_SCHEMA = {vol.Required(mode, default=True): bool for mode in AVAILABLE_MODES}
DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
**MODES_SCHEMA,
vol.Required(CONF_SWING_SUPPORT, default=False): bool,
}
)
DATA_SCHEMA = {
vol.Required(CONF_HOST): str,
**MODES_SCHEMA,
vol.Required(CONF_SWING_SUPPORT, default=False): bool,
}
async def _validate_connection(host: str) -> bool:
cool = CoolMasterNet(host, DEFAULT_PORT)
async def _validate_connection(host: str, send_wakeup_prompt: bool) -> bool:
cool = CoolMasterNet(host, DEFAULT_PORT, send_initial_line_feed=send_wakeup_prompt)
units = await cool.status()
return bool(units)
@@ -45,6 +49,14 @@ class CoolmasterConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 1
def _get_data_schema(self) -> vol.Schema:
schema_dict = DATA_SCHEMA.copy()
if self.show_advanced_options:
schema_dict[vol.Required(CONF_SEND_WAKEUP_PROMPT, default=False)] = bool
return vol.Schema(schema_dict)
@callback
def _async_get_entry(self, data: dict[str, Any]) -> ConfigFlowResult:
supported_modes = [
@@ -57,6 +69,7 @@ class CoolmasterConfigFlow(ConfigFlow, domain=DOMAIN):
CONF_PORT: DEFAULT_PORT,
CONF_SUPPORTED_MODES: supported_modes,
CONF_SWING_SUPPORT: data[CONF_SWING_SUPPORT],
CONF_SEND_WAKEUP_PROMPT: data.get(CONF_SEND_WAKEUP_PROMPT, False),
},
)
@@ -64,15 +77,19 @@ class CoolmasterConfigFlow(ConfigFlow, domain=DOMAIN):
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a flow initialized by the user."""
data_schema = self._get_data_schema()
if user_input is None:
return self.async_show_form(step_id="user", data_schema=DATA_SCHEMA)
return self.async_show_form(step_id="user", data_schema=data_schema)
errors = {}
host = user_input[CONF_HOST]
try:
result = await _validate_connection(host)
result = await _validate_connection(
host, user_input.get(CONF_SEND_WAKEUP_PROMPT, False)
)
if not result:
errors["base"] = "no_units"
except OSError:
@@ -80,7 +97,7 @@ class CoolmasterConfigFlow(ConfigFlow, domain=DOMAIN):
if errors:
return self.async_show_form(
step_id="user", data_schema=DATA_SCHEMA, errors=errors
step_id="user", data_schema=data_schema, errors=errors
)
return self._async_get_entry(user_input)

View File

@@ -6,5 +6,6 @@ DEFAULT_PORT = 10102
CONF_SUPPORTED_MODES = "supported_modes"
CONF_SWING_SUPPORT = "swing_support"
CONF_SEND_WAKEUP_PROMPT = "send_wakeup_prompt"
MAX_RETRIES = 3
BACKOFF_BASE_DELAY = 2

View File

@@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["pycoolmasternet_async"],
"requirements": ["pycoolmasternet-async==0.2.2"]
"requirements": ["pycoolmasternet-async==0.2.4"]
}

View File

@@ -14,10 +14,12 @@
"heat_cool": "Support automatic heat/cool mode",
"host": "[%key:common::config_flow::data::host%]",
"off": "Can be turned off",
"send_wakeup_prompt": "Send wakeup prompt",
"swing_support": "Control swing mode"
},
"data_description": {
"host": "The hostname or IP address of your CoolMasterNet device."
"host": "The hostname or IP address of your CoolMasterNet device.",
"send_wakeup_prompt": "Send the coolmaster unit an empty commaand before issuing any actual command. This is required for serial models."
},
"description": "Set up your CoolMasterNet connection details."
}

2
requirements_all.txt generated
View File

@@ -1946,7 +1946,7 @@ pycmus==0.1.1
pycomfoconnect==0.5.1
# homeassistant.components.coolmaster
pycoolmasternet-async==0.2.2
pycoolmasternet-async==0.2.4
# homeassistant.components.radio_browser
pycountry==24.6.1

View File

@@ -1653,7 +1653,7 @@ pycfdns==3.0.0
pycomfoconnect==0.5.1
# homeassistant.components.coolmaster
pycoolmasternet-async==0.2.2
pycoolmasternet-async==0.2.4
# homeassistant.components.radio_browser
pycountry==24.6.1

View File

@@ -9,18 +9,34 @@ from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
def _flow_data():
def _flow_data(advanced=False):
options = {"host": "1.1.1.1"}
for mode in AVAILABLE_MODES:
options[mode] = True
options["swing_support"] = False
if advanced:
options["send_wakeup_prompt"] = True
return options
async def test_form(hass: HomeAssistant) -> None:
async def test_form_non_advanced(hass: HomeAssistant) -> None:
"""Test we get the form in non-advanced mode."""
await form_base(hass, advanced=False)
async def test_form_advanced(hass: HomeAssistant) -> None:
"""Test we get the form in advanced mode."""
await form_base(hass, advanced=True)
async def form_base(hass: HomeAssistant, advanced: bool) -> None:
"""Test we get the form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
DOMAIN,
context={
"source": config_entries.SOURCE_USER,
"show_advanced_options": advanced,
},
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] is None
@@ -36,18 +52,22 @@ async def test_form(hass: HomeAssistant) -> None:
) as mock_setup_entry,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"], _flow_data()
result["flow_id"], _flow_data(advanced)
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["title"] == "1.1.1.1"
assert result2["data"] == {
_expected_data = {
"host": "1.1.1.1",
"port": 10102,
"supported_modes": AVAILABLE_MODES,
"swing_support": False,
"send_wakeup_prompt": False,
}
if advanced:
_expected_data["send_wakeup_prompt"] = True
assert result2["data"] == _expected_data
assert len(mock_setup_entry.mock_calls) == 1