Skip to content

Commit

Permalink
Merge pull request #18 from mill1000/ng/config_flow_discover
Browse files Browse the repository at this point in the history
Implement msmart-ng support with device discovery in config flow
  • Loading branch information
mill1000 authored Aug 29, 2023
2 parents 428896c + d430e10 commit cc04a4b
Show file tree
Hide file tree
Showing 8 changed files with 345 additions and 196 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Midea is an OEM for many brands including:
Hualing, Senville, Klimaire, AirCon, Century, Pridiom, Thermocore, Comfee, Alpine Home Air, Artel, Beko, Electrolux, Galactic, Idea, Inventor, Kaisai, Mitsui, Mr. Cool, Neoclima, Olimpia Splendid, Pioneer, QLIMA, Rotenso, Royal Clima, Qzen, Toshiba, Carrier, Goodman, Friedrich, Samsung, Kenmore, Trane, Lennox, LG and more.

## Features
* Automatic device discovery and configuration via the GUI.
* Device capability detection. Only supported modes and functions are available.
* Support for sleep, eco, boost (turbo) and away (freeze protection) presets.
* Switch entity for device display.
Expand All @@ -29,7 +30,13 @@ Hualing, Senville, Klimaire, AirCon, Century, Pridiom, Thermocore, Comfee, Alpin
## Configuration & Options
Midea Smart AC is configured via the GUI. See [the HA docs](https://www.home-assistant.io/getting-started/integration/) for more details.

The device ID, IP, and port are required for all devices. V3 devices require an additional token and K1 parameter. Currently this needs to be [acquired manually](#getting-device-info).
Devices can be automatically discovered and configured or manually configured.

### Automatic Configuration
For automatic configuration, select "Discover devices". Leave the host field blank to search the local network, or provide an IP/hostname to configure a specific device.

### Manual Configuration
For manual configuration, select "Configure manually". Enter the device ID, IP, and port. V3 devices require the token and key parameter. This information must be [acquired manually](#getting-device-info).

#### Integration Configuration
---
Expand All @@ -39,13 +46,13 @@ Name | Description | Required | Example
**Host** | Device IP address | Yes| 192.168.1.100
**Port** | Device port | Yes | 6444
**Token** | Device token | For V3 devices | ACEDDA53831AE5DC... (Length 128)
**K1** | Device K1 | For V3 devices | CFFA10FC... (Length 64)
**Key** | Device key | For V3 devices | CFFA10FC... (Length 64)

#### Integration Options
---
Name | Description
:--- | :---
**Prompt Tone** | Enable beep on setting changes.
**Beep** | Enable beep on setting changes.
**Temperature Step** | Step size for temperature set point.
**Include "Off" State** | Include "Off" as a valid device state.
**Use Fan-only Workaround** | Enable this option if device updates cause the device to turn on and switch to fan-only.
Expand Down
33 changes: 16 additions & 17 deletions custom_components/midea_ac/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,12 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_ID, CONF_PORT, CONF_TOKEN
from homeassistant.core import HomeAssistant
from msmart.device import air_conditioning as ac
from msmart import __version__ as MSMART_VERISON
from msmart.device import AirConditioner as AC

try:
# Try to import newer __version__ attribute
from msmart import __version__ as MSMART_VERISON
except ImportError:
# Fallback to older VERSION attribute
from msmart.device import VERSION as MSMART_VERISON


# Local constants
from . import helpers
from .const import CONF_K1, DOMAIN
# Local constants
from .const import CONF_KEY, DOMAIN

_LOGGER = logging.getLogger(__name__)

Expand All @@ -45,20 +38,23 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
id = config.get(CONF_ID)
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
device = ac(host, int(id), port)
device = AC(ip=host, port=port, device_id=int(id))

# Configure token and k1 as needed
token = config.get(CONF_TOKEN)
k1 = config.get(CONF_K1)
if token and k1:
await hass.async_add_executor_job(device.authenticate, k1, token)
key = config.get(CONF_KEY)
if token and key:
success = await device.authenticate(token, key)
if not success:
_LOGGER.error("Failed to authenticate with device.")
return False

hass.data[DOMAIN][id] = device

# Query device capabilities
if helpers.method_exists(device, "get_capabilities"):
_LOGGER.info("Querying device capabilities.")
await hass.async_add_executor_job(device.get_capabilities)
await device.get_capabilities()

# Create platform entries
hass.async_create_task(
Expand All @@ -84,7 +80,10 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->

# Remove device from global data
id = config.get(CONF_ID)
hass.data[DOMAIN].pop(id)
try:
hass.data[DOMAIN].pop(id)
except KeyError:
_LOGGER.warning("Failed remove device from global data.")

await hass.config_entries.async_forward_entry_unload(config_entry, "climate")
await hass.config_entries.async_forward_entry_unload(config_entry, "sensor")
Expand Down
Loading

0 comments on commit cc04a4b

Please sign in to comment.