24 files
This commit is contained in:
@@ -30,9 +30,9 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from midealocal.device import DeviceType, MideaDevice, ProtocolVersion
|
from midealan.device import DeviceType, MideaDevice, ProtocolVersion
|
||||||
from midealocal.devices import device_selector
|
from midealan.devices import device_selector
|
||||||
from midealocal.discover import discover
|
from midealan.discover import discover
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ALL_PLATFORM,
|
ALL_PLATFORM,
|
||||||
@@ -52,31 +52,43 @@ from .midea_devices import MIDEA_DEVICES
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _close_device(device: MideaDevice) -> None:
|
||||||
|
"""Close a Midea device connection without failing unload/setup cleanup."""
|
||||||
|
try:
|
||||||
|
device.close()
|
||||||
|
except (OSError, ConnectionError, AttributeError) as e:
|
||||||
|
_LOGGER.warning("Failed to close Midea socket cleanly: %s", e)
|
||||||
|
|
||||||
|
|
||||||
|
def _device_store(hass: HomeAssistant) -> dict[int, MideaDevice]:
|
||||||
|
"""Return the integration's loaded device map.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Device id to Midea device mapping.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return cast(
|
||||||
|
"dict[int, MideaDevice]",
|
||||||
|
hass.data.setdefault(DOMAIN, {}).setdefault(DEVICES, {}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||||
"""Option flow signal update.
|
"""Option flow signal update.
|
||||||
|
|
||||||
register update listener for config entry that will be called when entry is updated.
|
Registered in `async_setup_entry` via
|
||||||
A listener is registered by adding the following to the `async_setup_entry`:
|
`config_entry.async_on_unload(config_entry.add_update_listener(...))`, so it
|
||||||
`config_entry.async_on_unload(config_entry.add_update_listener(update_listener))`
|
is attached when the entry loads and detached at unload. Reload the entry so
|
||||||
means the Listener is attached when the entry is loaded and detached at unload
|
the changed options (customize JSON, IP override, refresh interval, and the
|
||||||
|
extra sensor/switch selection) are re-applied through the normal setup path.
|
||||||
|
|
||||||
|
Reloading avoids the previous fire-and-forget re-setup, which awaited the
|
||||||
|
platform unload but then re-forwarded setup via an untracked
|
||||||
|
`async_create_task` — swallowing any setup error and racing the customize/
|
||||||
|
ip/refresh application that followed.
|
||||||
"""
|
"""
|
||||||
# Forward the unloading of an entry to platforms.
|
await hass.config_entries.async_reload(config_entry.entry_id)
|
||||||
await hass.config_entries.async_unload_platforms(config_entry, ALL_PLATFORM)
|
|
||||||
# forward the Config Entry to the platforms
|
|
||||||
hass.async_create_task(
|
|
||||||
hass.config_entries.async_forward_entry_setups(config_entry, ALL_PLATFORM),
|
|
||||||
)
|
|
||||||
device_id: int = cast("int", config_entry.data.get(CONF_DEVICE_ID))
|
|
||||||
customize = config_entry.options.get(CONF_CUSTOMIZE, "")
|
|
||||||
ip_address = config_entry.options.get(CONF_IP_ADDRESS, None)
|
|
||||||
refresh_interval = config_entry.options.get(CONF_REFRESH_INTERVAL, None)
|
|
||||||
dev: MideaDevice = hass.data[DOMAIN][DEVICES].get(device_id)
|
|
||||||
if dev:
|
|
||||||
dev.set_customize(customize)
|
|
||||||
if ip_address is not None:
|
|
||||||
dev.set_ip_address(ip_address)
|
|
||||||
if refresh_interval is not None:
|
|
||||||
dev.set_refresh_interval(refresh_interval)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # ruff:ignore[unused-function-argument]
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # ruff:ignore[unused-function-argument]
|
||||||
@@ -217,7 +229,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||||||
if protocol == ProtocolVersion.V3 and (key == "" or token == ""):
|
if protocol == ProtocolVersion.V3 and (key == "" or token == ""):
|
||||||
_LOGGER.error("For V3 devices, the key and the token is required")
|
_LOGGER.error("For V3 devices, the key and the token is required")
|
||||||
return False
|
return False
|
||||||
# device_selector in `midealocal/devices/__init__.py`
|
# device_selector in `midealan/devices/__init__.py`
|
||||||
# hass core version >= 2024.3
|
# hass core version >= 2024.3
|
||||||
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 3):
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 3):
|
||||||
device = await hass.async_add_import_executor_job(
|
device = await hass.async_add_import_executor_job(
|
||||||
@@ -257,13 +269,17 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||||||
if refresh_interval is not None:
|
if refresh_interval is not None:
|
||||||
device.set_refresh_interval(refresh_interval)
|
device.set_refresh_interval(refresh_interval)
|
||||||
device.open()
|
device.open()
|
||||||
if DOMAIN not in hass.data:
|
_device_store(hass)[device_id] = device
|
||||||
hass.data[DOMAIN] = {}
|
try:
|
||||||
if DEVICES not in hass.data[DOMAIN]:
|
|
||||||
hass.data[DOMAIN][DEVICES] = {}
|
|
||||||
hass.data[DOMAIN][DEVICES][device_id] = device
|
|
||||||
# Forward the setup of an entry to all platforms
|
# Forward the setup of an entry to all platforms
|
||||||
await hass.config_entries.async_forward_entry_setups(config_entry, ALL_PLATFORM)
|
await hass.config_entries.async_forward_entry_setups(
|
||||||
|
config_entry,
|
||||||
|
ALL_PLATFORM,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
_device_store(hass).pop(device_id, None)
|
||||||
|
_close_device(device)
|
||||||
|
raise
|
||||||
# Listener `update_listener` is
|
# Listener `update_listener` is
|
||||||
# attached when the entry is loaded
|
# attached when the entry is loaded
|
||||||
# and detached when it's unloaded
|
# and detached when it's unloaded
|
||||||
@@ -283,18 +299,22 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
|
|||||||
device_type = config_entry.data.get(CONF_TYPE)
|
device_type = config_entry.data.get(CONF_TYPE)
|
||||||
if device_type == CONF_ACCOUNT:
|
if device_type == CONF_ACCOUNT:
|
||||||
return True
|
return True
|
||||||
|
# Unload the platforms first; only tear the device down if that succeeded,
|
||||||
|
# and report the real result so a failed platform unload isn't masked.
|
||||||
|
# bool() keeps mypy happy: async_unload_platforms is typed to return Any.
|
||||||
|
unload_ok = bool(
|
||||||
|
await hass.config_entries.async_unload_platforms(
|
||||||
|
config_entry,
|
||||||
|
ALL_PLATFORM,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if unload_ok:
|
||||||
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
if device_id is not None:
|
if device_id is not None:
|
||||||
dm = hass.data[DOMAIN][DEVICES].get(device_id)
|
dm = _device_store(hass).pop(device_id, None)
|
||||||
if dm is not None:
|
if dm is not None:
|
||||||
try:
|
_close_device(dm)
|
||||||
dm.close()
|
return unload_ok
|
||||||
except (OSError, ConnectionError, AttributeError) as e:
|
|
||||||
_LOGGER.warning("Failed to close Midea socket cleanly: %s", e)
|
|
||||||
hass.data[DOMAIN][DEVICES].pop(device_id)
|
|
||||||
# Forward the unloading of an entry to platforms
|
|
||||||
await hass.config_entries.async_unload_platforms(config_entry, ALL_PLATFORM)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
|
|||||||
@@ -40,17 +40,17 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.device import DeviceType
|
from midealan.device import DeviceType
|
||||||
from midealocal.devices.ac import DeviceAttributes as ACAttributes
|
from midealan.devices.ac import DeviceAttributes as ACAttributes
|
||||||
from midealocal.devices.ac import MideaACDevice
|
from midealan.devices.ac import MideaACDevice
|
||||||
from midealocal.devices.c3 import DeviceAttributes as C3Attributes
|
from midealan.devices.c3 import DeviceAttributes as C3Attributes
|
||||||
from midealocal.devices.c3 import MideaC3Device
|
from midealan.devices.c3 import MideaC3Device
|
||||||
from midealocal.devices.cc import DeviceAttributes as CCAttributes
|
from midealan.devices.cc import DeviceAttributes as CCAttributes
|
||||||
from midealocal.devices.cc import MideaCCDevice
|
from midealan.devices.cc import MideaCCDevice
|
||||||
from midealocal.devices.cf import DeviceAttributes as CFAttributes
|
from midealan.devices.cf import DeviceAttributes as CFAttributes
|
||||||
from midealocal.devices.cf import MideaCFDevice
|
from midealan.devices.cf import MideaCFDevice
|
||||||
from midealocal.devices.fb import DeviceAttributes as FBAttributes
|
from midealan.devices.fb import DeviceAttributes as FBAttributes
|
||||||
from midealocal.devices.fb import MideaFBDevice
|
from midealan.devices.fb import MideaFBDevice
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN, FanSpeed
|
from .const import DEVICES, DOMAIN, FanSpeed
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
@@ -146,6 +146,9 @@ class MideaClimate(MideaEntity, ClimateEntity):
|
|||||||
"""Midea Climate hvac mode."""
|
"""Midea Climate hvac mode."""
|
||||||
if self._device.get_attribute("power"):
|
if self._device.get_attribute("power"):
|
||||||
mode = cast("int", self._device.get_attribute("mode"))
|
mode = cast("int", self._device.get_attribute("mode"))
|
||||||
|
# Guard against an out-of-range/undefined device mode so a malformed
|
||||||
|
# frame cannot raise IndexError on every state render.
|
||||||
|
if 0 <= mode < len(self.hvac_modes):
|
||||||
return self.hvac_modes[mode]
|
return self.hvac_modes[mode]
|
||||||
return HVACMode.OFF
|
return HVACMode.OFF
|
||||||
|
|
||||||
@@ -450,6 +453,9 @@ class MideaACClimate(MideaClimate):
|
|||||||
"""Midea AC Climate hvac mode (device mode int -> fixed map)."""
|
"""Midea AC Climate hvac mode (device mode int -> fixed map)."""
|
||||||
if self._device.get_attribute("power"):
|
if self._device.get_attribute("power"):
|
||||||
mode = cast("int", self._device.get_attribute("mode"))
|
mode = cast("int", self._device.get_attribute("mode"))
|
||||||
|
# The AC `mode` field is a 3-bit value (0-7) but `_mode_index` only
|
||||||
|
# maps 0-5; guard so an out-of-spec 6/7 cannot raise IndexError.
|
||||||
|
if 0 <= mode < len(self._mode_index):
|
||||||
return self._mode_index[mode]
|
return self._mode_index[mode]
|
||||||
return HVACMode.OFF
|
return HVACMode.OFF
|
||||||
|
|
||||||
@@ -814,7 +820,11 @@ class MideaC3Climate(MideaClimate):
|
|||||||
def hvac_mode(self) -> HVACMode:
|
def hvac_mode(self) -> HVACMode:
|
||||||
"""Midea C3 Climate hvac mode."""
|
"""Midea C3 Climate hvac mode."""
|
||||||
mode = self._device.get_attribute(C3Attributes.mode)
|
mode = self._device.get_attribute(C3Attributes.mode)
|
||||||
if self._device.get_attribute(self._power_attr) and isinstance(mode, int):
|
if (
|
||||||
|
self._device.get_attribute(self._power_attr)
|
||||||
|
and isinstance(mode, int)
|
||||||
|
and 0 <= mode < len(self.hvac_modes)
|
||||||
|
):
|
||||||
return self.hvac_modes[mode]
|
return self.hvac_modes[mode]
|
||||||
return HVACMode.OFF
|
return HVACMode.OFF
|
||||||
|
|
||||||
|
|||||||
@@ -47,15 +47,14 @@ from homeassistant.core import callback
|
|||||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||||
from homeassistant.helpers.json import save_json
|
from homeassistant.helpers.json import save_json
|
||||||
from homeassistant.util.json import load_json
|
from homeassistant.util.json import load_json
|
||||||
from midealocal.cloud import (
|
from midealan.cloud import (
|
||||||
PRESET_ACCOUNT_DATA,
|
PRESET_ACCOUNT_DATA,
|
||||||
SUPPORTED_CLOUDS,
|
SUPPORTED_CLOUDS,
|
||||||
MideaCloud,
|
MideaCloud,
|
||||||
get_midea_cloud,
|
get_midea_cloud,
|
||||||
)
|
)
|
||||||
from midealocal.device import AuthException, MideaDevice, ProtocolVersion
|
from midealan.device import MideaDevice, ProtocolVersion
|
||||||
from midealocal.discover import discover
|
from midealan.discover import discover
|
||||||
from midealocal.exceptions import SocketException
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
@@ -144,7 +143,7 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
record_file = storage_path.joinpath(f"{data[CONF_DEVICE_ID]!s}.json")
|
record_file = storage_path.joinpath(f"{data[CONF_DEVICE_ID]!s}.json")
|
||||||
save_json(str(record_file), data)
|
save_json(str(record_file), data)
|
||||||
|
|
||||||
def _load_device_config(self, device_id: str) -> Any: # ruff:ignore[any-type]
|
def _load_device_config(self, device_id: int | str) -> Any: # ruff:ignore[any-type]
|
||||||
"""Load device config from json file with device id.
|
"""Load device config from json file with device id.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@@ -356,7 +355,7 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
# get all devices list
|
# get all devices list
|
||||||
all_devices = discover()
|
all_devices = await self.hass.async_add_executor_job(discover)
|
||||||
# available devices exist
|
# available devices exist
|
||||||
if len(all_devices) > 0:
|
if len(all_devices) > 0:
|
||||||
table = (
|
table = (
|
||||||
@@ -402,8 +401,10 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
# ip exist
|
# ip exist
|
||||||
else:
|
else:
|
||||||
ip_address = discovery_info[CONF_IP_ADDRESS]
|
ip_address = discovery_info[CONF_IP_ADDRESS]
|
||||||
# use midea-local discover() to get devices list with ip_address
|
# use midea-lan discover() to get devices list with ip_address
|
||||||
self.devices = discover(list(self.supports.keys()), ip_address=ip_address)
|
self.devices = await self.hass.async_add_executor_job(
|
||||||
|
lambda: discover(list(self.supports.keys()), ip_address=ip_address),
|
||||||
|
)
|
||||||
self.available_device = {}
|
self.available_device = {}
|
||||||
for device_id, device in self.devices.items():
|
for device_id, device in self.devices.items():
|
||||||
# remove exist devices and only return new devices
|
# remove exist devices and only return new devices
|
||||||
@@ -512,16 +513,7 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
subtype=0,
|
subtype=0,
|
||||||
attributes={},
|
attributes={},
|
||||||
)
|
)
|
||||||
if dm.connect():
|
if await self.hass.async_add_executor_job(self._try_connect_device, dm):
|
||||||
try:
|
|
||||||
dm.authenticate()
|
|
||||||
except AuthException:
|
|
||||||
_LOGGER.debug("Unable to authenticate.")
|
|
||||||
dm.close_socket()
|
|
||||||
except SocketException:
|
|
||||||
_LOGGER.debug("Socket closed.")
|
|
||||||
else:
|
|
||||||
dm.close_socket()
|
|
||||||
return value
|
return value
|
||||||
# return debug log with failed key
|
# return debug log with failed key
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
@@ -533,6 +525,23 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
)
|
)
|
||||||
return {"error": "connect_error"}
|
return {"error": "connect_error"}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _try_connect_device(dm: MideaDevice) -> bool:
|
||||||
|
"""Connect to a device, closing the socket afterwards.
|
||||||
|
|
||||||
|
Runs the blocking socket I/O in an executor so it never blocks the
|
||||||
|
event loop. V3 authentication is handled inside midea-lan's connect().
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if the device connected successfully.
|
||||||
|
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return dm.connect()
|
||||||
|
finally:
|
||||||
|
dm.close_socket()
|
||||||
|
|
||||||
async def async_step_auto(
|
async def async_step_auto(
|
||||||
self,
|
self,
|
||||||
user_input: dict[str, Any] | None = None,
|
user_input: dict[str, Any] | None = None,
|
||||||
@@ -559,7 +568,10 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
CONF_PORT: device.get(CONF_PORT),
|
CONF_PORT: device.get(CONF_PORT),
|
||||||
CONF_MODEL: device.get(CONF_MODEL),
|
CONF_MODEL: device.get(CONF_MODEL),
|
||||||
}
|
}
|
||||||
storage_device = self._load_device_config(device_id)
|
storage_device = await self.hass.async_add_executor_job(
|
||||||
|
self._load_device_config,
|
||||||
|
device_id,
|
||||||
|
)
|
||||||
# device config already exist, load from local json without cloud
|
# device config already exist, load from local json without cloud
|
||||||
if self._check_storage_device(device, storage_device):
|
if self._check_storage_device(device, storage_device):
|
||||||
self.found_device = {
|
self.found_device = {
|
||||||
@@ -697,9 +709,8 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
if len(self.devices) < 1:
|
if len(self.devices) < 1:
|
||||||
ip = user_input[CONF_IP_ADDRESS]
|
ip = user_input[CONF_IP_ADDRESS]
|
||||||
# discover device
|
# discover device
|
||||||
self.devices = discover(
|
self.devices = await self.hass.async_add_executor_job(
|
||||||
list(self.supports.keys()),
|
lambda: discover(list(self.supports.keys()), ip_address=ip),
|
||||||
ip_address=ip,
|
|
||||||
)
|
)
|
||||||
# discover result MUST exist
|
# discover result MUST exist
|
||||||
if len(self.devices) != 1:
|
if len(self.devices) != 1:
|
||||||
@@ -778,19 +789,10 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
subtype=0,
|
subtype=0,
|
||||||
attributes={},
|
attributes={},
|
||||||
)
|
)
|
||||||
if dm.connect():
|
if await self.hass.async_add_executor_job(
|
||||||
try:
|
self._try_connect_device,
|
||||||
if user_input[CONF_PROTOCOL] == ProtocolVersion.V3:
|
dm,
|
||||||
dm.authenticate()
|
):
|
||||||
except SocketException:
|
|
||||||
_LOGGER.exception("Socket closed.")
|
|
||||||
except AuthException:
|
|
||||||
_LOGGER.exception(
|
|
||||||
"Unable to authenticate with provided key and token.",
|
|
||||||
)
|
|
||||||
dm.close_socket()
|
|
||||||
else:
|
|
||||||
dm.close_socket()
|
|
||||||
data = {
|
data = {
|
||||||
CONF_NAME: user_input[CONF_NAME],
|
CONF_NAME: user_input[CONF_NAME],
|
||||||
CONF_DEVICE_ID: user_input[CONF_DEVICE_ID],
|
CONF_DEVICE_ID: user_input[CONF_DEVICE_ID],
|
||||||
@@ -806,7 +808,7 @@ class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
|||||||
CONF_SN: device.get(CONF_SN),
|
CONF_SN: device.get(CONF_SN),
|
||||||
}
|
}
|
||||||
# save device json config when adding new device
|
# save device json config when adding new device
|
||||||
self._save_device_config(data)
|
await self.hass.async_add_executor_job(self._save_device_config, data)
|
||||||
# finish add device entry
|
# finish add device entry
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=f"{user_input[CONF_NAME]}",
|
title=f"{user_input[CONF_NAME]}",
|
||||||
@@ -917,14 +919,12 @@ class MideaLanOptionsFlowHandler(OptionsFlow):
|
|||||||
self._device_type = config_entry.data.get(CONF_TYPE)
|
self._device_type = config_entry.data.get(CONF_TYPE)
|
||||||
if self._device_type is None:
|
if self._device_type is None:
|
||||||
self._device_type = 0xAC
|
self._device_type = 0xAC
|
||||||
if CONF_SENSORS in self._config_entry.options:
|
# Stale keys (attributes no longer in MIDEA_DEVICES) are filtered out
|
||||||
for key in self._config_entry.options[CONF_SENSORS]:
|
# downstream in async_step_init, where the multi-select defaults are
|
||||||
if key not in MIDEA_DEVICES[self._device_type]["entities"]:
|
# computed as `set(sensors) & set(options)` / `set(switches) & ...` —
|
||||||
self._config_entry.options[CONF_SENSORS].remove(key)
|
# both `sensors` and `switches` are built only from valid entities. No
|
||||||
if CONF_SWITCHES in self._config_entry.options:
|
# pruning is needed here; doing it in place mutated the list while
|
||||||
for key in self._config_entry.options[CONF_SWITCHES]:
|
# iterating (skipping elements) and mutated HA-owned entry state.
|
||||||
if key not in MIDEA_DEVICES[self._device_type]["entities"]:
|
|
||||||
self._config_entry.options[CONF_SWITCHES].remove(key)
|
|
||||||
|
|
||||||
async def async_step_init(
|
async def async_step_init(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.device import DeviceType
|
from midealan.device import DeviceType
|
||||||
from midealocal.devices.ac import DeviceAttributes as ACAttributes
|
from midealan.devices.ac import DeviceAttributes as ACAttributes
|
||||||
from midealocal.devices.ac import MideaACDevice
|
from midealan.devices.ac import MideaACDevice
|
||||||
from midealocal.devices.b6 import MideaB6Device
|
from midealan.devices.b6 import MideaB6Device
|
||||||
from midealocal.devices.ce import DeviceAttributes as CEAttributes
|
from midealan.devices.ce import DeviceAttributes as CEAttributes
|
||||||
from midealocal.devices.ce import MideaCEDevice
|
from midealan.devices.ce import MideaCEDevice
|
||||||
from midealocal.devices.fa import MideaFADevice
|
from midealan.devices.fa import MideaFADevice
|
||||||
from midealocal.devices.x40 import DeviceAttributes as X40Attributes
|
from midealan.devices.x40 import DeviceAttributes as X40Attributes
|
||||||
from midealocal.devices.x40 import MideaX40Device
|
from midealan.devices.x40 import MideaX40Device
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN
|
from .const import DEVICES, DOMAIN
|
||||||
from .midea_devices import (
|
from .midea_devices import (
|
||||||
@@ -122,7 +122,13 @@ class MideaFan(MideaEntity, FanEntity):
|
|||||||
|
|
||||||
def set_preset_mode(self, preset_mode: str) -> None:
|
def set_preset_mode(self, preset_mode: str) -> None:
|
||||||
"""Midea Fan set preset mode."""
|
"""Midea Fan set preset mode."""
|
||||||
self._device.set_attribute(attr="mode", value=preset_mode.capitalize())
|
# Pass the preset value through unchanged. `preset_modes` already
|
||||||
|
# returns the device's own strings and HA only ever hands one of them
|
||||||
|
# back, so the value is guaranteed valid. Do NOT `.capitalize()` it:
|
||||||
|
# that corrupts multi-word / mixed-case names such as the CE fan's
|
||||||
|
# "ECO mode" -> "Eco mode", which the device matches case-sensitively
|
||||||
|
# and silently drops, making the ECO preset unselectable.
|
||||||
|
self._device.set_attribute(attr="mode", value=preset_mode)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def percentage(self) -> int | None:
|
def percentage(self) -> int | None:
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.device import DeviceType
|
from midealan.device import DeviceType
|
||||||
from midealocal.devices.a1 import MideaA1Device
|
from midealan.devices.a1 import MideaA1Device
|
||||||
from midealocal.devices.fd import MideaFDDevice
|
from midealan.devices.fd import MideaFDDevice
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN
|
from .const import DEVICES, DOMAIN
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"entity": {
|
||||||
|
"climate": {
|
||||||
|
"climate_key": {
|
||||||
|
"state_attributes": {
|
||||||
|
"fan_mode": {
|
||||||
|
"state": {
|
||||||
|
"silent": "mdi:fan-clock",
|
||||||
|
"full": "mdi:fan-alert"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,8 +15,8 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.devices.x13 import DeviceAttributes as X13Attributes
|
from midealan.devices.x13 import DeviceAttributes as X13Attributes
|
||||||
from midealocal.devices.x13 import Midea13Device
|
from midealan.devices.x13 import Midea13Device
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN
|
from .const import DEVICES, DOMAIN
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
@@ -73,18 +73,32 @@ def _calc_supported_color_modes(device: Midea13Device) -> set[ColorMode]:
|
|||||||
class MideaLight(MideaEntity, LightEntity):
|
class MideaLight(MideaEntity, LightEntity):
|
||||||
"""Midea Light Entries."""
|
"""Midea Light Entries."""
|
||||||
|
|
||||||
_attr_color_mode: ColorMode | str | None = None
|
|
||||||
_attr_supported_color_modes: set[ColorMode] | set[str] | None = None
|
|
||||||
_attr_supported_features: LightEntityFeature = LightEntityFeature(0)
|
|
||||||
|
|
||||||
_device: Midea13Device
|
_device: Midea13Device
|
||||||
|
|
||||||
def __init__(self, device: Midea13Device, entity_key: str) -> None:
|
# NOTE: supported_features / supported_color_modes / color_mode are computed
|
||||||
"""Midea Light entity init."""
|
# as properties (not latched in __init__). The device starts its socket
|
||||||
super().__init__(device, entity_key)
|
# refresh on a background thread, so at construction time brightness,
|
||||||
self._attr_supported_features = _calc_supported_features(device)
|
# color_temperature and rgb_color are all still None. Latching these in
|
||||||
self._attr_supported_color_modes = _calc_supported_color_modes(device)
|
# __init__ would lock a dimmable/color-temp light to ONOFF forever, because
|
||||||
self._attr_color_mode = self._calc_color_mode(self._attr_supported_color_modes)
|
# update_state never recomputes them. Recomputing per access reflects the
|
||||||
|
# capabilities once the first status arrives.
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> LightEntityFeature:
|
||||||
|
"""Midea Light supported features."""
|
||||||
|
return _calc_supported_features(self._device)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_color_modes(self) -> set[ColorMode] | set[str] | None:
|
||||||
|
"""Midea Light supported color modes."""
|
||||||
|
return _calc_supported_color_modes(self._device)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color_mode(self) -> ColorMode | str | None:
|
||||||
|
"""Midea Light current color mode."""
|
||||||
|
# Call the concrete helper (returns set[ColorMode]) rather than the
|
||||||
|
# supported_color_modes property, whose type is widened to
|
||||||
|
# set[ColorMode] | set[str] | None to match LightEntity's base override.
|
||||||
|
return self._calc_color_mode(_calc_supported_color_modes(self._device))
|
||||||
|
|
||||||
def _calc_color_mode(self, supported: set[ColorMode]) -> ColorMode:
|
def _calc_color_mode(self, supported: set[ColorMode]) -> ColorMode:
|
||||||
"""Midea Light calculate color mode.
|
"""Midea Light calculate color mode.
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
{
|
{
|
||||||
"domain": "midea_ac_lan",
|
"domain": "midea_ac_lan",
|
||||||
"name": "Midea AC LAN",
|
"name": "Midea AC LAN",
|
||||||
"codeowners": ["@wuwentao", "@rokam", "@chemelli74", "@Necroneco"],
|
"codeowners": [
|
||||||
|
"@wuwentao",
|
||||||
|
"@rokam",
|
||||||
|
"@chemelli74",
|
||||||
|
"@caibinqing"
|
||||||
|
],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"documentation": "https://github.com/wuwentao/midea_ac_lan#readme",
|
"documentation": "https://github.com/wuwentao/midea_ac_lan#readme",
|
||||||
"integration_type": "device",
|
"integration_type": "device",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"issue_tracker": "https://github.com/wuwentao/midea_ac_lan/issues",
|
"issue_tracker": "https://github.com/wuwentao/midea_ac_lan/issues",
|
||||||
"loggers": ["midealocal"],
|
"loggers": [
|
||||||
"requirements": ["midea-local==6.11.1"],
|
"midealan"
|
||||||
"version": "0.7.1"
|
],
|
||||||
|
"requirements": [
|
||||||
|
"midea-lan==2026.8.0"
|
||||||
|
],
|
||||||
|
"version": "2026.8.0"
|
||||||
}
|
}
|
||||||
@@ -5,8 +5,8 @@ from typing import Any
|
|||||||
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
|
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
|
||||||
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
|
from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
MAJOR_VERSION,
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
MINOR_VERSION,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
REVOLUTIONS_PER_MINUTE,
|
REVOLUTIONS_PER_MINUTE,
|
||||||
Platform,
|
Platform,
|
||||||
@@ -19,40 +19,61 @@ from homeassistant.const import (
|
|||||||
UnitOfTime,
|
UnitOfTime,
|
||||||
UnitOfVolume,
|
UnitOfVolume,
|
||||||
)
|
)
|
||||||
from midealocal.devices.a1 import DeviceAttributes as A1Attributes
|
|
||||||
from midealocal.devices.ac import DeviceAttributes as ACAttributes
|
# HA 2026.7 added UnitOfDensity/UnitOfRatio, and HA 2026.8 started deprecating
|
||||||
from midealocal.devices.ad import DeviceAttributes as ADAttributes
|
# CONCENTRATION_MICROGRAMS_PER_CUBIC_METER / CONCENTRATION_PARTS_PER_MILLION in favor of
|
||||||
from midealocal.devices.b0 import DeviceAttributes as B0Attributes
|
# them (scheduled for removal in HA 2027.8). Both old and new names resolve to the
|
||||||
from midealocal.devices.b1 import DeviceAttributes as B1Attributes
|
# identical runtime string ("μg/m³" / "ppm"), so this is purely cosmetic. This
|
||||||
from midealocal.devices.b3 import DeviceAttributes as B3Attributes
|
# integration's floor is HA 2024.4.1, where UnitOfDensity/UnitOfRatio do not exist yet,
|
||||||
from midealocal.devices.b4 import DeviceAttributes as B4Attributes
|
# so branch on the HA version like the rest of this codebase does for newer HA APIs (see
|
||||||
from midealocal.devices.b6 import DeviceAttributes as B6Attributes
|
# other MAJOR_VERSION/MINOR_VERSION usages, e.g. midea_entity.py).
|
||||||
from midealocal.devices.bf import DeviceAttributes as BFAttributes
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2026, 7):
|
||||||
from midealocal.devices.c2 import DeviceAttributes as C2Attributes
|
from homeassistant.const import ( # pylint: disable=E0611
|
||||||
from midealocal.devices.c3 import DeviceAttributes as C3Attributes
|
UnitOfDensity,
|
||||||
from midealocal.devices.ca import DeviceAttributes as CAAttributes
|
UnitOfRatio,
|
||||||
from midealocal.devices.cc import DeviceAttributes as CCAttributes
|
)
|
||||||
from midealocal.devices.cd import DeviceAttributes as CDAttributes
|
|
||||||
from midealocal.devices.ce import DeviceAttributes as CEAttributes
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER = UnitOfDensity.MICROGRAMS_PER_CUBIC_METER
|
||||||
from midealocal.devices.cf import DeviceAttributes as CFAttributes
|
CONCENTRATION_PARTS_PER_MILLION = UnitOfRatio.PARTS_PER_MILLION
|
||||||
from midealocal.devices.da import DeviceAttributes as DAAttributes
|
else:
|
||||||
from midealocal.devices.db import DeviceAttributes as DBAttributes
|
from homeassistant.const import ( # type: ignore[no-redef]
|
||||||
from midealocal.devices.dc import DeviceAttributes as DCAttributes
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
from midealocal.devices.e1 import DeviceAttributes as E1Attributes
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
from midealocal.devices.e2 import DeviceAttributes as E2Attributes
|
)
|
||||||
from midealocal.devices.e3 import DeviceAttributes as E3Attributes
|
from midealan.devices.a1 import DeviceAttributes as A1Attributes
|
||||||
from midealocal.devices.e6 import DeviceAttributes as E6Attributes
|
from midealan.devices.ac import DeviceAttributes as ACAttributes
|
||||||
from midealocal.devices.e8 import DeviceAttributes as E8Attributes
|
from midealan.devices.ad import DeviceAttributes as ADAttributes
|
||||||
from midealocal.devices.ea import DeviceAttributes as EAAttributes
|
from midealan.devices.b0 import DeviceAttributes as B0Attributes
|
||||||
from midealocal.devices.ec import DeviceAttributes as ECAttributes
|
from midealan.devices.b1 import DeviceAttributes as B1Attributes
|
||||||
from midealocal.devices.ed import DeviceAttributes as EDAttributes
|
from midealan.devices.b3 import DeviceAttributes as B3Attributes
|
||||||
from midealocal.devices.fa import DeviceAttributes as FAAttributes
|
from midealan.devices.b4 import DeviceAttributes as B4Attributes
|
||||||
from midealocal.devices.fb import DeviceAttributes as FBAttributes
|
from midealan.devices.b6 import DeviceAttributes as B6Attributes
|
||||||
from midealocal.devices.fc import DeviceAttributes as FCAttributes
|
from midealan.devices.bf import DeviceAttributes as BFAttributes
|
||||||
from midealocal.devices.fd import DeviceAttributes as FDAttributes
|
from midealan.devices.c2 import DeviceAttributes as C2Attributes
|
||||||
from midealocal.devices.x26 import DeviceAttributes as X26Attributes
|
from midealan.devices.c3 import DeviceAttributes as C3Attributes
|
||||||
from midealocal.devices.x34 import DeviceAttributes as X34Attributes
|
from midealan.devices.ca import DeviceAttributes as CAAttributes
|
||||||
from midealocal.devices.x40 import DeviceAttributes as X40Attributes
|
from midealan.devices.cc import DeviceAttributes as CCAttributes
|
||||||
|
from midealan.devices.cd import DeviceAttributes as CDAttributes
|
||||||
|
from midealan.devices.ce import DeviceAttributes as CEAttributes
|
||||||
|
from midealan.devices.cf import DeviceAttributes as CFAttributes
|
||||||
|
from midealan.devices.da import DeviceAttributes as DAAttributes
|
||||||
|
from midealan.devices.db import DeviceAttributes as DBAttributes
|
||||||
|
from midealan.devices.dc import DeviceAttributes as DCAttributes
|
||||||
|
from midealan.devices.e1 import DeviceAttributes as E1Attributes
|
||||||
|
from midealan.devices.e2 import DeviceAttributes as E2Attributes
|
||||||
|
from midealan.devices.e3 import DeviceAttributes as E3Attributes
|
||||||
|
from midealan.devices.e6 import DeviceAttributes as E6Attributes
|
||||||
|
from midealan.devices.e8 import DeviceAttributes as E8Attributes
|
||||||
|
from midealan.devices.ea import DeviceAttributes as EAAttributes
|
||||||
|
from midealan.devices.ec import DeviceAttributes as ECAttributes
|
||||||
|
from midealan.devices.ed import DeviceAttributes as EDAttributes
|
||||||
|
from midealan.devices.fa import DeviceAttributes as FAAttributes
|
||||||
|
from midealan.devices.fb import DeviceAttributes as FBAttributes
|
||||||
|
from midealan.devices.fc import DeviceAttributes as FCAttributes
|
||||||
|
from midealan.devices.fd import DeviceAttributes as FDAttributes
|
||||||
|
from midealan.devices.x26 import DeviceAttributes as X26Attributes
|
||||||
|
from midealan.devices.x34 import DeviceAttributes as X34Attributes
|
||||||
|
from midealan.devices.x40 import DeviceAttributes as X40Attributes
|
||||||
|
|
||||||
FRESH_AIR_EXHAUST = "fresh_air_exhaust"
|
FRESH_AIR_EXHAUST = "fresh_air_exhaust"
|
||||||
FRESH_AIR_EXHAUST_MODE = "fresh_air_exhaust_mode"
|
FRESH_AIR_EXHAUST_MODE = "fresh_air_exhaust_mode"
|
||||||
@@ -647,28 +668,28 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"unit": UnitOfElectricPotential.VOLT,
|
"unit": UnitOfElectricPotential.VOLT,
|
||||||
"state_class": SensorStateClass.MEASUREMENT,
|
"state_class": SensorStateClass.MEASUREMENT,
|
||||||
},
|
},
|
||||||
ACAttributes.indoor_coil_temperature: {
|
ACAttributes.indoor_ambient_temperature: {
|
||||||
"type": Platform.SENSOR,
|
"type": Platform.SENSOR,
|
||||||
"required_attribute": ACAttributes.indoor_coil_temperature,
|
"required_attribute": ACAttributes.indoor_ambient_temperature,
|
||||||
"translation_key": "indoor_coil_temperature",
|
"translation_key": "indoor_ambient_temperature",
|
||||||
"name": "Indoor Coil Temperature (T1)",
|
"name": "Indoor Coil Temperature (T1)",
|
||||||
"device_class": SensorDeviceClass.TEMPERATURE,
|
"device_class": SensorDeviceClass.TEMPERATURE,
|
||||||
"unit": UnitOfTemperature.CELSIUS,
|
"unit": UnitOfTemperature.CELSIUS,
|
||||||
"state_class": SensorStateClass.MEASUREMENT,
|
"state_class": SensorStateClass.MEASUREMENT,
|
||||||
},
|
},
|
||||||
ACAttributes.evaporator_temperature: {
|
ACAttributes.indoor_coil_temperature: {
|
||||||
"type": Platform.SENSOR,
|
"type": Platform.SENSOR,
|
||||||
"required_attribute": ACAttributes.evaporator_temperature,
|
"required_attribute": ACAttributes.indoor_coil_temperature,
|
||||||
"translation_key": "evaporator_temperature",
|
"translation_key": "indoor_coil_temperature",
|
||||||
"name": "Evaporator Temperature (T2)",
|
"name": "Evaporator Temperature (T2)",
|
||||||
"device_class": SensorDeviceClass.TEMPERATURE,
|
"device_class": SensorDeviceClass.TEMPERATURE,
|
||||||
"unit": UnitOfTemperature.CELSIUS,
|
"unit": UnitOfTemperature.CELSIUS,
|
||||||
"state_class": SensorStateClass.MEASUREMENT,
|
"state_class": SensorStateClass.MEASUREMENT,
|
||||||
},
|
},
|
||||||
ACAttributes.condenser_temperature: {
|
ACAttributes.outdoor_coil_temperature: {
|
||||||
"type": Platform.SENSOR,
|
"type": Platform.SENSOR,
|
||||||
"required_attribute": ACAttributes.condenser_temperature,
|
"required_attribute": ACAttributes.outdoor_coil_temperature,
|
||||||
"translation_key": "condenser_temperature",
|
"translation_key": "outdoor_coil_temperature",
|
||||||
"name": "Condenser Temperature (T3)",
|
"name": "Condenser Temperature (T3)",
|
||||||
"device_class": SensorDeviceClass.TEMPERATURE,
|
"device_class": SensorDeviceClass.TEMPERATURE,
|
||||||
"unit": UnitOfTemperature.CELSIUS,
|
"unit": UnitOfTemperature.CELSIUS,
|
||||||
@@ -904,6 +925,14 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"icon": "mdi:box-shadow",
|
"icon": "mdi:box-shadow",
|
||||||
"device_class": BinarySensorDeviceClass.DOOR,
|
"device_class": BinarySensorDeviceClass.DOOR,
|
||||||
},
|
},
|
||||||
|
# Deliberately NO device_class here. BinarySensorDeviceClass.LOCK
|
||||||
|
# defines on = UNLOCKED, but this attribute is True when the child
|
||||||
|
# lock is ENGAGED, so that device class would display it inverted.
|
||||||
|
B0Attributes.child_lock: {
|
||||||
|
"type": Platform.BINARY_SENSOR,
|
||||||
|
"name": "Child Lock",
|
||||||
|
"icon": "mdi:lock",
|
||||||
|
},
|
||||||
B0Attributes.tank_ejected: {
|
B0Attributes.tank_ejected: {
|
||||||
"type": Platform.BINARY_SENSOR,
|
"type": Platform.BINARY_SENSOR,
|
||||||
"translation_key": "tank_ejected",
|
"translation_key": "tank_ejected",
|
||||||
@@ -938,6 +967,16 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"name": "Status",
|
"name": "Status",
|
||||||
"icon": "mdi:information",
|
"icon": "mdi:information",
|
||||||
},
|
},
|
||||||
|
B0Attributes.mode: {
|
||||||
|
"type": Platform.SENSOR,
|
||||||
|
"name": "Mode",
|
||||||
|
"icon": "mdi:chef-hat",
|
||||||
|
},
|
||||||
|
B0Attributes.fire_power: {
|
||||||
|
"type": Platform.SENSOR,
|
||||||
|
"name": "Fire Power",
|
||||||
|
"icon": "mdi:fire",
|
||||||
|
},
|
||||||
B0Attributes.time_remaining: {
|
B0Attributes.time_remaining: {
|
||||||
"type": Platform.SENSOR,
|
"type": Platform.SENSOR,
|
||||||
"translation_key": "time_remaining",
|
"translation_key": "time_remaining",
|
||||||
@@ -1022,7 +1061,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"type": Platform.BINARY_SENSOR,
|
"type": Platform.BINARY_SENSOR,
|
||||||
"translation_key": "top_compartment_cooling",
|
"translation_key": "top_compartment_cooling",
|
||||||
"name": "Top Compartment Cooling",
|
"name": "Top Compartment Cooling",
|
||||||
"icon": "snowflake-variant",
|
"icon": "mdi:snowflake-variant",
|
||||||
"device_class": BinarySensorDeviceClass.RUNNING,
|
"device_class": BinarySensorDeviceClass.RUNNING,
|
||||||
},
|
},
|
||||||
B3Attributes.middle_compartment_door: {
|
B3Attributes.middle_compartment_door: {
|
||||||
@@ -1043,7 +1082,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"type": Platform.BINARY_SENSOR,
|
"type": Platform.BINARY_SENSOR,
|
||||||
"translation_key": "middle_compartment_cooling",
|
"translation_key": "middle_compartment_cooling",
|
||||||
"name": "Middle Compartment Cooling",
|
"name": "Middle Compartment Cooling",
|
||||||
"icon": "snowflake-variant",
|
"icon": "mdi:snowflake-variant",
|
||||||
"device_class": BinarySensorDeviceClass.RUNNING,
|
"device_class": BinarySensorDeviceClass.RUNNING,
|
||||||
},
|
},
|
||||||
B3Attributes.bottom_compartment_door: {
|
B3Attributes.bottom_compartment_door: {
|
||||||
@@ -1064,7 +1103,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"type": Platform.BINARY_SENSOR,
|
"type": Platform.BINARY_SENSOR,
|
||||||
"translation_key": "bottom_compartment_cooling",
|
"translation_key": "bottom_compartment_cooling",
|
||||||
"name": "Bottom Compartment Cooling",
|
"name": "Bottom Compartment Cooling",
|
||||||
"icon": "snowflake-variant",
|
"icon": "mdi:snowflake-variant",
|
||||||
"device_class": BinarySensorDeviceClass.RUNNING,
|
"device_class": BinarySensorDeviceClass.RUNNING,
|
||||||
},
|
},
|
||||||
B3Attributes.top_compartment_status: {
|
B3Attributes.top_compartment_status: {
|
||||||
@@ -1434,7 +1473,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"name": "Silent Mode",
|
"name": "Silent Mode",
|
||||||
"icon": "mdi:fan-remove",
|
"icon": "mdi:fan-remove",
|
||||||
},
|
},
|
||||||
C3Attributes.SILENT_LEVEL: {
|
C3Attributes.silent_level: {
|
||||||
"type": Platform.SELECT,
|
"type": Platform.SELECT,
|
||||||
"translation_key": "silent_level",
|
"translation_key": "silent_level",
|
||||||
"name": "Silent Level",
|
"name": "Silent Level",
|
||||||
@@ -1750,7 +1789,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"entities": {
|
"entities": {
|
||||||
"climate": {
|
"climate": {
|
||||||
"type": Platform.CLIMATE,
|
"type": Platform.CLIMATE,
|
||||||
"icon": "hass:air-conditioner",
|
"icon": "mdi:air-conditioner",
|
||||||
"default": True,
|
"default": True,
|
||||||
},
|
},
|
||||||
CCAttributes.aux_heating: {
|
CCAttributes.aux_heating: {
|
||||||
@@ -2161,7 +2200,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"entities": {
|
"entities": {
|
||||||
"climate": {
|
"climate": {
|
||||||
"type": Platform.CLIMATE,
|
"type": Platform.CLIMATE,
|
||||||
"icon": "hass:air-conditioner",
|
"icon": "mdi:air-conditioner",
|
||||||
"default": True,
|
"default": True,
|
||||||
},
|
},
|
||||||
CFAttributes.aux_heating: {
|
CFAttributes.aux_heating: {
|
||||||
@@ -2247,7 +2286,7 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
DAAttributes.wash_level: {
|
DAAttributes.wash_level: {
|
||||||
"type": Platform.SENSOR,
|
"type": Platform.SENSOR,
|
||||||
"translation_key": "wash_level",
|
"translation_key": "wash_level",
|
||||||
"name": "Rinse count",
|
"name": "Wash level",
|
||||||
"icon": "mdi:hydraulic-oil-level",
|
"icon": "mdi:hydraulic-oil-level",
|
||||||
},
|
},
|
||||||
DAAttributes.wash_strength: {
|
DAAttributes.wash_strength: {
|
||||||
@@ -2922,7 +2961,6 @@ MIDEA_DEVICES: dict[int, dict[str, dict[str, Any] | str]] = {
|
|||||||
"type": Platform.BINARY_SENSOR,
|
"type": Platform.BINARY_SENSOR,
|
||||||
"translation_key": "finished",
|
"translation_key": "finished",
|
||||||
"name": "Finished",
|
"name": "Finished",
|
||||||
"icon": "",
|
|
||||||
},
|
},
|
||||||
E8Attributes.water_shortage: {
|
E8Attributes.water_shortage: {
|
||||||
"type": Platform.BINARY_SENSOR,
|
"type": Platform.BINARY_SENSOR,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ else:
|
|||||||
)
|
)
|
||||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
|
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from midealocal.device import MideaDevice
|
from midealan.device import MideaDevice
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
@@ -79,13 +79,15 @@ class MideaEntity(Entity):
|
|||||||
# Example: device_class = temperature -> "Temperature".
|
# Example: device_class = temperature -> "Temperature".
|
||||||
elif "device_class" in self._config:
|
elif "device_class" in self._config:
|
||||||
self._attr_name = None # Let HA generate from device_class
|
self._attr_name = None # Let HA generate from device_class
|
||||||
# Step 4: Nothing available,
|
# Step 4: Nothing available (no translation_key, no name, no
|
||||||
|
# device_class). With has_entity_name=True HA already prepends the
|
||||||
|
# device name, so the entity's own name must be None — the entity then
|
||||||
|
# represents the device's main feature and shows just the device name.
|
||||||
|
# (The previous fallback embedded the device name itself, yielding a
|
||||||
|
# doubled "DeviceName DeviceName", or "DeviceName None" when a null
|
||||||
|
# "name" key was present.)
|
||||||
else:
|
else:
|
||||||
self._attr_name = (
|
self._attr_name = None
|
||||||
f"{self._device_name} {self._config.get('name')}"
|
|
||||||
if "name" in self._config
|
|
||||||
else f"{self._device_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device(self) -> MideaDevice:
|
def device(self) -> MideaDevice:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.device import MideaDevice
|
from midealan.device import MideaDevice
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN
|
from .const import DEVICES, DOMAIN
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
@@ -44,53 +44,41 @@ class MideaNumber(MideaEntity, NumberEntity):
|
|||||||
self._min_value = self._config.get("min")
|
self._min_value = self._config.get("min")
|
||||||
self._step_value = self._config.get("step")
|
self._step_value = self._config.get("step")
|
||||||
|
|
||||||
|
def _resolve_bound(self, bound: Any) -> float: # ruff:ignore[any-type]
|
||||||
|
"""Resolve a min/max/step config value to a concrete number.
|
||||||
|
|
||||||
|
A numeric literal is used as-is. Otherwise the value is treated as an
|
||||||
|
attribute name: prefer the device attribute of that name, falling back
|
||||||
|
to a same-named device property populated by ``set_customize``.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The resolved bound as a float.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if isinstance(bound, (int, float)):
|
||||||
|
return cast("float", bound)
|
||||||
|
# `bound` is an attribute name. Use `is not None` (not truthiness) so a
|
||||||
|
# legitimate 0 is not treated as "missing", and read the attribute once.
|
||||||
|
value = self._device.get_attribute(attr=bound)
|
||||||
|
if value is None:
|
||||||
|
value = getattr(self._device, bound)
|
||||||
|
return cast("float", value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_min_value(self) -> float:
|
def native_min_value(self) -> float:
|
||||||
"""Minimum value allowed."""
|
"""Minimum value allowed."""
|
||||||
return cast(
|
return self._resolve_bound(self._min_value)
|
||||||
"float",
|
|
||||||
(
|
|
||||||
self._min_value
|
|
||||||
if isinstance(self._min_value, int)
|
|
||||||
else (
|
|
||||||
self._device.get_attribute(attr=self._min_value)
|
|
||||||
if self._device.get_attribute(attr=self._min_value)
|
|
||||||
else getattr(self._device, self._min_value)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_max_value(self) -> float:
|
def native_max_value(self) -> float:
|
||||||
"""Maximum value allowed."""
|
"""Maximum value allowed."""
|
||||||
return cast(
|
return self._resolve_bound(self._max_value)
|
||||||
"float",
|
|
||||||
(
|
|
||||||
self._max_value
|
|
||||||
if isinstance(self._max_value, int)
|
|
||||||
else (
|
|
||||||
self._device.get_attribute(attr=self._max_value)
|
|
||||||
if self._device.get_attribute(attr=self._max_value)
|
|
||||||
else getattr(self._device, self._max_value)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_step(self) -> float:
|
def native_step(self) -> float:
|
||||||
"""Step value between allowed values."""
|
"""Step value between allowed values."""
|
||||||
return cast(
|
return self._resolve_bound(self._step_value)
|
||||||
"float",
|
|
||||||
(
|
|
||||||
self._step_value
|
|
||||||
if isinstance(self._step_value, int)
|
|
||||||
else (
|
|
||||||
self._device.get_attribute(attr=self._step_value)
|
|
||||||
if self._device.get_attribute(attr=self._step_value)
|
|
||||||
else getattr(self._device, self._step_value)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> float:
|
def native_value(self) -> float:
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.device import MideaDevice
|
from midealan.device import MideaDevice
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN, supports_model
|
from .const import DEVICES, DOMAIN, supports_model
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
from .midea_entity import MideaEntity
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from midealocal.devices.e1 import MideaE1Device
|
from midealan.devices.e1 import MideaE1Device
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
@@ -94,7 +94,7 @@ class MideaSelect(MideaEntity, SelectEntity):
|
|||||||
self._device.set_attribute(self._attribute_key, option)
|
self._device.set_attribute(self._attribute_key, option)
|
||||||
|
|
||||||
def _get_options_dict(self) -> dict[int, str]:
|
def _get_options_dict(self) -> dict[int, str]:
|
||||||
"""Return option dict from the backing midea-local device.
|
"""Return option dict from the backing midea-lan device.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@@ -104,7 +104,7 @@ class MideaSelect(MideaEntity, SelectEntity):
|
|||||||
return cast("dict[int, str]", getattr(self._device, self._options_dict_name))
|
return cast("dict[int, str]", getattr(self._device, self._options_dict_name))
|
||||||
|
|
||||||
def _select_e1_work_mode(self, option: str) -> None:
|
def _select_e1_work_mode(self, option: str) -> None:
|
||||||
"""Set dishwasher work mode via midea-local's public E1 API.
|
"""Set dishwasher work mode via midea-lan's public E1 API.
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
------
|
------
|
||||||
@@ -125,10 +125,9 @@ class MideaSelect(MideaEntity, SelectEntity):
|
|||||||
if (
|
if (
|
||||||
power_attribute
|
power_attribute
|
||||||
and self.hass
|
and self.hass
|
||||||
and not self.hass.is_stopping
|
|
||||||
and (self._attribute_key in status or power_attribute in status)
|
and (self._attribute_key in status or power_attribute in status)
|
||||||
):
|
):
|
||||||
self.schedule_update_ha_state()
|
self.schedule_update_if_running()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_dict_key_by_value(source: dict[int, str], value: str) -> int | None:
|
def _get_dict_key_by_value(source: dict[int, str], value: str) -> int | None:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.restore_state import RestoreEntity
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
from midealocal.device import MideaDevice
|
from midealan.device import MideaDevice
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN, supports_model
|
from .const import DEVICES, DOMAIN, supports_model
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
@@ -185,9 +185,7 @@ class MideaEstimatedUsageSensor(MideaSensor, RestoreEntity):
|
|||||||
|
|
||||||
self._last_progress = current_progress
|
self._last_progress = current_progress
|
||||||
super().update_state(status)
|
super().update_state(status)
|
||||||
if (
|
if self.hass and (
|
||||||
self.hass
|
"progress" in status or "status" in status or "mode" in status
|
||||||
and not self.hass.is_stopping
|
|
||||||
and ("progress" in status or "status" in status or "mode" in status)
|
|
||||||
):
|
):
|
||||||
self.schedule_update_ha_state()
|
self.schedule_update_if_running()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"error": {
|
"error": {
|
||||||
"preset_account": "Anmeldung mit voreingestelltem Konto fehlgeschlagen, bitte melden Sie dieses Problem",
|
"preset_account": "Anmeldung mit voreingestelltem Konto fehlgeschlagen, bitte dieses Problem melden",
|
||||||
"login_failed": "Anmeldung fehlgeschlagen, Konto oder Passwort ist falsch",
|
"login_failed": "Anmeldung fehlgeschlagen, Konto oder Passwort ist falsch",
|
||||||
"no_devices": "Keine neuen verfügbaren Geräte im Netzwerk gefunden",
|
"no_devices": "Keine neuen verfügbaren Geräte im Netzwerk gefunden",
|
||||||
"device_exist": "Das Gerät ist bereits konfiguriert",
|
"device_exist": "Das Gerät ist bereits konfiguriert",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"way": "Hinzufügen von Geräten"
|
"way": "Hinzufügen von Geräten"
|
||||||
},
|
},
|
||||||
"description": "Wählen Sie die Art des Hinzufügens eines Geräts",
|
"description": "Die Art des Hinzufügens eines Geräts wählen",
|
||||||
"title": "Neues Gerät hinzufügen"
|
"title": "Neues Gerät hinzufügen"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
@@ -22,11 +22,11 @@
|
|||||||
"account": "Konto",
|
"account": "Konto",
|
||||||
"password": "Passwort"
|
"password": "Passwort"
|
||||||
},
|
},
|
||||||
"description": "Melden Sie sich mit Ihrem Midea-Konto an. Ihr Konto wird nur verwendet, um die Geräteinformationen zu erhalten.\nSie können die Konfiguration entfernen, nachdem alle Geräte konfiguriert wurden.",
|
"description": "Mit dem Midea-Konto anmelden. Das Konto wird nur verwendet, um die Geräteinformationen zu erhalten.\nDie Konfiguration kann wieder entfernt werden, nachdem alle Geräte konfiguriert wurden.",
|
||||||
"title": "Login"
|
"title": "Login"
|
||||||
},
|
},
|
||||||
"discovery": {
|
"discovery": {
|
||||||
"description": "IP-Adresse des Geräts, geben Sie \"auto\" ein, um es automatisch zu finden.\nSie können auch eine IP-Adresse verwenden, um innerhalb eines bestimmten Netzwerks zu suchen, z.B. \"192.168.1.255\".",
|
"description": "IP-Adresse des Geräts, \"auto\" eingeben, um es automatisch zu finden.\nEs kann auch eine IP-Adresse verwendet werden, um innerhalb eines bestimmten Netzwerks zu suchen, z.B. \"192.168.1.255\".",
|
||||||
"title": "Suche",
|
"title": "Suche",
|
||||||
"data": {
|
"data": {
|
||||||
"ip_address": "IP-Adresse"
|
"ip_address": "IP-Adresse"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"device": "Geräte"
|
"device": "Geräte"
|
||||||
},
|
},
|
||||||
"description": "Wählen Sie ein Gerät zum Hinzufügen",
|
"description": "Gerät auswählen um es hinzufügen",
|
||||||
"title": "Neues Gerät gefunden"
|
"title": "Neues Gerät gefunden"
|
||||||
},
|
},
|
||||||
"manually": {
|
"manually": {
|
||||||
@@ -64,85 +64,85 @@
|
|||||||
"entity": {
|
"entity": {
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"bar_door": {
|
"bar_door": {
|
||||||
"name": "Bar Door"
|
"name": "Bar-Tür"
|
||||||
},
|
},
|
||||||
"bar_door_overtime": {
|
"bar_door_overtime": {
|
||||||
"name": "Bar Door Overtime"
|
"name": "Bar-Tür Overtime"
|
||||||
},
|
},
|
||||||
"bathing_working": {
|
"bathing_working": {
|
||||||
"name": "Bathing Working Status"
|
"name": "Bathing Working Status"
|
||||||
},
|
},
|
||||||
"bottom_compartment_cooling": {
|
"bottom_compartment_cooling": {
|
||||||
"name": "Bottom Compartment Cooling"
|
"name": "Bodenfach Kühlung"
|
||||||
},
|
},
|
||||||
"bottom_compartment_door": {
|
"bottom_compartment_door": {
|
||||||
"name": "Bottom Compartment Door"
|
"name": "Bodenfach Tür"
|
||||||
},
|
},
|
||||||
"bottom_compartment_preheating": {
|
"bottom_compartment_preheating": {
|
||||||
"name": "Bottom Compartment Preheating"
|
"name": "Bodenfach Vorheizer"
|
||||||
},
|
},
|
||||||
"burning_state": {
|
"burning_state": {
|
||||||
"name": "Burning State"
|
"name": "Brenner-Status"
|
||||||
},
|
},
|
||||||
"cleaning_reminder": {
|
"cleaning_reminder": {
|
||||||
"name": "Cleaning Reminder"
|
"name": "Reinigungs-Erinnerung"
|
||||||
},
|
},
|
||||||
"compressor_status": {
|
"compressor_status": {
|
||||||
"name": "Compressor Status"
|
"name": "Kompressor-Status"
|
||||||
},
|
},
|
||||||
"cooking": {
|
"cooking": {
|
||||||
"name": "Cooking"
|
"name": "Kochen"
|
||||||
},
|
},
|
||||||
"error_code": {
|
"error_code": {
|
||||||
"name": "Fehlercode"
|
"name": "Fehlercode"
|
||||||
},
|
},
|
||||||
"filter_change_reminder": {
|
"filter_change_reminder": {
|
||||||
"name": "Filter Change Reminder"
|
"name": "Filter-Wechsel-Erinnerung"
|
||||||
},
|
},
|
||||||
"filter_cleaning_reminder": {
|
"filter_cleaning_reminder": {
|
||||||
"name": "Filter Cleaning Reminder"
|
"name": "Filter-Reinigungs-Erinnerung"
|
||||||
},
|
},
|
||||||
"finished": {
|
"finished": {
|
||||||
"name": "Finished"
|
"name": "Fertig"
|
||||||
},
|
},
|
||||||
"flex_zone_door": {
|
"flex_zone_door": {
|
||||||
"name": "Flex Door"
|
"name": "Flex-Tür"
|
||||||
},
|
},
|
||||||
"flex_zone_door_overtime": {
|
"flex_zone_door_overtime": {
|
||||||
"name": "Flex Zone Door"
|
"name": "Flexzonen-Tür"
|
||||||
},
|
},
|
||||||
"freezer_door": {
|
"freezer_door": {
|
||||||
"name": "Freezer Door"
|
"name": "Gefrierfachtür"
|
||||||
},
|
},
|
||||||
"freezer_door_overtime": {
|
"freezer_door_overtime": {
|
||||||
"name": "Freezer Door Overtime"
|
"name": "Gefrierfachtür Overtime"
|
||||||
},
|
},
|
||||||
"full_dust": {
|
"full_dust": {
|
||||||
"name": "Full of Dust"
|
"name": "Voller Staub"
|
||||||
},
|
},
|
||||||
"heating": {
|
"heating": {
|
||||||
"name": "Heating"
|
"name": "Heizen"
|
||||||
},
|
},
|
||||||
"heating_working": {
|
"heating_working": {
|
||||||
"name": "Heating Working Status"
|
"name": "Heizen Arbeitsstatus"
|
||||||
},
|
},
|
||||||
"keep_warm": {
|
"keep_warm": {
|
||||||
"name": "Keep Warm"
|
"name": "Warmhalten"
|
||||||
},
|
},
|
||||||
"leak_water": {
|
"leak_water": {
|
||||||
"name": "Leckwasser"
|
"name": "Leckwasser"
|
||||||
},
|
},
|
||||||
"lid_status": {
|
"lid_status": {
|
||||||
"name": "Lid Status"
|
"name": "Deckel-Status"
|
||||||
},
|
},
|
||||||
"middle_compartment_cooling": {
|
"middle_compartment_cooling": {
|
||||||
"name": "Middle Compartment Cooling"
|
"name": "Mittelfach-Kühlung"
|
||||||
},
|
},
|
||||||
"middle_compartment_door": {
|
"middle_compartment_door": {
|
||||||
"name": "Middle Compartment Door"
|
"name": "Mittelfach-Tür"
|
||||||
},
|
},
|
||||||
"middle_compartment_preheating": {
|
"middle_compartment_preheating": {
|
||||||
"name": "Middle Compartment Preheating"
|
"name": "Mittelfach Vorheizen"
|
||||||
},
|
},
|
||||||
"top_elec_heat": {
|
"top_elec_heat": {
|
||||||
"name": "Elektroheizung oben"
|
"name": "Elektroheizung oben"
|
||||||
@@ -160,28 +160,28 @@
|
|||||||
"name": "Multi-Terminal"
|
"name": "Multi-Terminal"
|
||||||
},
|
},
|
||||||
"oilcup_full": {
|
"oilcup_full": {
|
||||||
"name": "Oil-cup Full"
|
"name": "Ölbehälter voll"
|
||||||
},
|
},
|
||||||
"protection": {
|
"protection": {
|
||||||
"name": "Protection"
|
"name": "Schutz"
|
||||||
},
|
},
|
||||||
"refrigerator_door": {
|
"refrigerator_door": {
|
||||||
"name": "Refrigerator Door"
|
"name": "Kühlschranktür"
|
||||||
},
|
},
|
||||||
"refrigerator_door_overtime": {
|
"refrigerator_door_overtime": {
|
||||||
"name": "Refrigerator Door Overtime"
|
"name": "Kühlrschranktür Overtime"
|
||||||
},
|
},
|
||||||
"rinse_aid": {
|
"rinse_aid": {
|
||||||
"name": "Rinse Aid Shortage"
|
"name": "Spülhilfe leer"
|
||||||
},
|
},
|
||||||
"rsj_stand_by": {
|
"rsj_stand_by": {
|
||||||
"name": "Standby"
|
"name": "Standby"
|
||||||
},
|
},
|
||||||
"salt": {
|
"salt": {
|
||||||
"name": "Salt Shortage"
|
"name": "Salz leer"
|
||||||
},
|
},
|
||||||
"seat_status": {
|
"seat_status": {
|
||||||
"name": "Seat Status"
|
"name": "Sitz Status"
|
||||||
},
|
},
|
||||||
"smart_grid": {
|
"smart_grid": {
|
||||||
"name": "Smart Grid"
|
"name": "Smart Grid"
|
||||||
@@ -202,52 +202,52 @@
|
|||||||
"name": "Zeitplan 2 aktiv"
|
"name": "Zeitplan 2 aktiv"
|
||||||
},
|
},
|
||||||
"status_dhw": {
|
"status_dhw": {
|
||||||
"name": "DHW status"
|
"name": "DHW-Status"
|
||||||
},
|
},
|
||||||
"status_heating": {
|
"status_heating": {
|
||||||
"name": "Heating status"
|
"name": "Aufheiz-Status"
|
||||||
},
|
},
|
||||||
"status_ibh": {
|
"status_ibh": {
|
||||||
"name": "IBH status"
|
"name": "IBH-Status"
|
||||||
},
|
},
|
||||||
"status_tbh": {
|
"status_tbh": {
|
||||||
"name": "TBH status"
|
"name": "TBH-Status"
|
||||||
},
|
},
|
||||||
"tank_ejected": {
|
"tank_ejected": {
|
||||||
"name": "Tank Ejected"
|
"name": "Behälter ausgeworfen"
|
||||||
},
|
},
|
||||||
"tank_full": {
|
"tank_full": {
|
||||||
"name": "Tank status"
|
"name": "Behälter-Status"
|
||||||
},
|
},
|
||||||
"top_compartment_cooling": {
|
"top_compartment_cooling": {
|
||||||
"name": "Top Compartment Cooling"
|
"name": "Top Compartment Cooling"
|
||||||
},
|
},
|
||||||
"top_compartment_door": {
|
"top_compartment_door": {
|
||||||
"name": "Top Compartment Door"
|
"name": "Oberfach-Tür"
|
||||||
},
|
},
|
||||||
"top_compartment_preheating": {
|
"top_compartment_preheating": {
|
||||||
"name": "Top Compartment Preheating"
|
"name": "Oberfach Vorhzeizen"
|
||||||
},
|
},
|
||||||
"water_change_reminder": {
|
"water_change_reminder": {
|
||||||
"name": "Water Change Reminder"
|
"name": "Wasserwechsel-Erinnerung"
|
||||||
},
|
},
|
||||||
"water_shortage": {
|
"water_shortage": {
|
||||||
"name": "Water Shortage"
|
"name": "Wasser leer"
|
||||||
},
|
},
|
||||||
"with_pressure": {
|
"with_pressure": {
|
||||||
"name": "With Pressure"
|
"name": "Mit Druck"
|
||||||
},
|
},
|
||||||
"zone1_room_temp_mode": {
|
"zone1_room_temp_mode": {
|
||||||
"name": "Zone1 Room-temperature Mode"
|
"name": "Zone1 Taumtemperatur-Modus"
|
||||||
},
|
},
|
||||||
"zone1_water_temp_mode": {
|
"zone1_water_temp_mode": {
|
||||||
"name": "Zone1 Water-temperature Mode"
|
"name": "Zone1 Wassertemperatur-Modus"
|
||||||
},
|
},
|
||||||
"zone2_room_temp_mode": {
|
"zone2_room_temp_mode": {
|
||||||
"name": "Zone2 Room-temperature Mode"
|
"name": "Zone2 Zimmertemperatur-Modus"
|
||||||
},
|
},
|
||||||
"zone2_water_temp_mode": {
|
"zone2_water_temp_mode": {
|
||||||
"name": "Zone2 Water-temperature Mode"
|
"name": "Zone2 Wassertemperatur-Modus"
|
||||||
},
|
},
|
||||||
"microcrystal_fresh": {
|
"microcrystal_fresh": {
|
||||||
"name": "Mikrokristall-Frische"
|
"name": "Mikrokristall-Frische"
|
||||||
@@ -284,7 +284,7 @@
|
|||||||
},
|
},
|
||||||
"fan": {
|
"fan": {
|
||||||
"fresh_air": {
|
"fresh_air": {
|
||||||
"name": "Fresh Air"
|
"name": "Frischluft"
|
||||||
},
|
},
|
||||||
"fresh_air_exhaust": {
|
"fresh_air_exhaust": {
|
||||||
"name": "Frischluft-Abluft"
|
"name": "Frischluft-Abluft"
|
||||||
@@ -297,16 +297,16 @@
|
|||||||
},
|
},
|
||||||
"number": {
|
"number": {
|
||||||
"dry_level": {
|
"dry_level": {
|
||||||
"name": "Dry Level"
|
"name": "Trocken-Level"
|
||||||
},
|
},
|
||||||
"heating_level": {
|
"heating_level": {
|
||||||
"name": "Heating Level"
|
"name": "Heiz-Level"
|
||||||
},
|
},
|
||||||
"seat_temp_level": {
|
"seat_temp_level": {
|
||||||
"name": "Seat Temperature Level"
|
"name": "Sitztemperatur-Level"
|
||||||
},
|
},
|
||||||
"water_temp_level": {
|
"water_temp_level": {
|
||||||
"name": "Water Temperature Level"
|
"name": "Wassertemperatur-Level"
|
||||||
},
|
},
|
||||||
"fan_speed_percent": {
|
"fan_speed_percent": {
|
||||||
"name": "Lüftergeschwindigkeit (Prozent)"
|
"name": "Lüftergeschwindigkeit (Prozent)"
|
||||||
@@ -326,13 +326,13 @@
|
|||||||
},
|
},
|
||||||
"select": {
|
"select": {
|
||||||
"detect_mode": {
|
"detect_mode": {
|
||||||
"name": "Detect Mode"
|
"name": "Detektions-Modus"
|
||||||
},
|
},
|
||||||
"direction": {
|
"direction": {
|
||||||
"name": "Direction"
|
"name": "Richtung"
|
||||||
},
|
},
|
||||||
"fan_speed": {
|
"fan_speed": {
|
||||||
"name": "Fan Speed"
|
"name": "Lüftergeschwindigkeit"
|
||||||
},
|
},
|
||||||
"fresh_air_exhaust_mode": {
|
"fresh_air_exhaust_mode": {
|
||||||
"name": "Frischluft-Abluftgeschwindigkeit",
|
"name": "Frischluft-Abluftgeschwindigkeit",
|
||||||
@@ -354,31 +354,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mode": {
|
"mode": {
|
||||||
"name": "Mode"
|
"name": "Modus"
|
||||||
},
|
},
|
||||||
"oscillation_angle": {
|
"oscillation_angle": {
|
||||||
"name": "Oscillation Angle"
|
"name": "Oszillationswinkel"
|
||||||
},
|
},
|
||||||
"oscillation_mode": {
|
"oscillation_mode": {
|
||||||
"name": "Oscillation Mode"
|
"name": "Oszillationsmodus"
|
||||||
},
|
},
|
||||||
"rate_select": {
|
"rate_select": {
|
||||||
"name": "Power Rate Limit"
|
"name": "Leistungslimit"
|
||||||
},
|
},
|
||||||
"screen_display": {
|
"screen_display": {
|
||||||
"name": "Screen Display"
|
"name": "Bildschirmanzeige"
|
||||||
},
|
},
|
||||||
"silent_level": {
|
"silent_level": {
|
||||||
"name": "Silent Level"
|
"name": "Silent-Stufe"
|
||||||
},
|
},
|
||||||
"tilting_angle": {
|
"tilting_angle": {
|
||||||
"name": "Tilting Angle"
|
"name": "Kippwinkel"
|
||||||
},
|
},
|
||||||
"wash_mode": {
|
"wash_mode": {
|
||||||
"name": "Waschmodus"
|
"name": "Waschmodus"
|
||||||
},
|
},
|
||||||
"water_level_set": {
|
"water_level_set": {
|
||||||
"name": "Water Level Setting"
|
"name": "Einstellung Wasserhöhe"
|
||||||
},
|
},
|
||||||
"wind_lr_angle": {
|
"wind_lr_angle": {
|
||||||
"name": "Luftstrom horizontal",
|
"name": "Luftstrom horizontal",
|
||||||
@@ -425,19 +425,19 @@
|
|||||||
"name": "Bottom Temperature"
|
"name": "Bottom Temperature"
|
||||||
},
|
},
|
||||||
"bright": {
|
"bright": {
|
||||||
"name": "Bright Level"
|
"name": "Helligkeitsstufe"
|
||||||
},
|
},
|
||||||
"compressor_temperature": {
|
"compressor_temperature": {
|
||||||
"name": "Compressor Temperature"
|
"name": "Kompressor-Temperatur"
|
||||||
},
|
},
|
||||||
"condenser_temperature": {
|
"condenser_temperature": {
|
||||||
"name": "Condenser Temperature"
|
"name": "Kondensator-Temperature"
|
||||||
},
|
},
|
||||||
"current_energy_consumption": {
|
"current_energy_consumption": {
|
||||||
"name": "Current Energy Consumption"
|
"name": "Aktueller Energieverbrauch"
|
||||||
},
|
},
|
||||||
"current_temperature": {
|
"current_temperature": {
|
||||||
"name": "Current Temperature"
|
"name": "Aktuelle Temperatur"
|
||||||
},
|
},
|
||||||
"dehydration_speed": {
|
"dehydration_speed": {
|
||||||
"name": "dehydration speed"
|
"name": "dehydration speed"
|
||||||
@@ -461,7 +461,7 @@
|
|||||||
"name": "Verschmutzungsgrad"
|
"name": "Verschmutzungsgrad"
|
||||||
},
|
},
|
||||||
"detergent": {
|
"detergent": {
|
||||||
"name": "detergent"
|
"name": "Reinigungsmittel"
|
||||||
},
|
},
|
||||||
"intensity": {
|
"intensity": {
|
||||||
"name": "Intensität"
|
"name": "Intensität"
|
||||||
@@ -502,7 +502,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error_code": {
|
"error_code": {
|
||||||
"name": "Error Code"
|
"name": "Fehlercode"
|
||||||
},
|
},
|
||||||
"estimated_energy_consumption": {
|
"estimated_energy_consumption": {
|
||||||
"name": "Geschätzter Energieverbrauch"
|
"name": "Geschätzter Energieverbrauch"
|
||||||
@@ -511,7 +511,7 @@
|
|||||||
"name": "Geschätzter Wasserverbrauch"
|
"name": "Geschätzter Wasserverbrauch"
|
||||||
},
|
},
|
||||||
"fan_level": {
|
"fan_level": {
|
||||||
"name": "Fan level"
|
"name": "Lüfterstufe"
|
||||||
},
|
},
|
||||||
"filter_life": {
|
"filter_life": {
|
||||||
"name": "Filter Life"
|
"name": "Filter Life"
|
||||||
@@ -520,19 +520,19 @@
|
|||||||
"name": "Filter1 Verfügbare Tage"
|
"name": "Filter1 Verfügbare Tage"
|
||||||
},
|
},
|
||||||
"filter1_life": {
|
"filter1_life": {
|
||||||
"name": "Filter1 Lebensdauer Level"
|
"name": "Filter1 Lebensdauer Stufe"
|
||||||
},
|
},
|
||||||
"filter2_days": {
|
"filter2_days": {
|
||||||
"name": "Filter2 Verfügbare Tage"
|
"name": "Filter2 Verfügbare Tage"
|
||||||
},
|
},
|
||||||
"filter2_life": {
|
"filter2_life": {
|
||||||
"name": "Filter2 Lebensdauer Level"
|
"name": "Filter2 Lebensdauer Stufe"
|
||||||
},
|
},
|
||||||
"filter3_days": {
|
"filter3_days": {
|
||||||
"name": "Filter3 Verfügbare Tage"
|
"name": "Filter3 Verfügbare Tage"
|
||||||
},
|
},
|
||||||
"filter3_life": {
|
"filter3_life": {
|
||||||
"name": "Filter3 Lebensdauer Level"
|
"name": "Filter3 Lebensdauer Stufe"
|
||||||
},
|
},
|
||||||
"flex_zone_actual_temp": {
|
"flex_zone_actual_temp": {
|
||||||
"name": "Flex Zone Actual Temperature"
|
"name": "Flex Zone Actual Temperature"
|
||||||
@@ -562,10 +562,10 @@
|
|||||||
"name": "TDS-Wert rein"
|
"name": "TDS-Wert rein"
|
||||||
},
|
},
|
||||||
"indoor_humidity": {
|
"indoor_humidity": {
|
||||||
"name": "Indoor Humidity"
|
"name": "Innenraumluftfeuchtigkeit"
|
||||||
},
|
},
|
||||||
"indoor_temperature": {
|
"indoor_temperature": {
|
||||||
"name": "Indoor Temperature"
|
"name": "Innenraumtemperatur"
|
||||||
},
|
},
|
||||||
"keep_warm_remaining": {
|
"keep_warm_remaining": {
|
||||||
"name": "Keep Warm Remaining"
|
"name": "Keep Warm Remaining"
|
||||||
@@ -592,7 +592,7 @@
|
|||||||
"name": "TDS-Wert raus"
|
"name": "TDS-Wert raus"
|
||||||
},
|
},
|
||||||
"outdoor_temperature": {
|
"outdoor_temperature": {
|
||||||
"name": "Outdoor Temperature"
|
"name": "Außentemperatur"
|
||||||
},
|
},
|
||||||
"program": {
|
"program": {
|
||||||
"name": "Program"
|
"name": "Program"
|
||||||
@@ -601,7 +601,7 @@
|
|||||||
"name": "Progress"
|
"name": "Progress"
|
||||||
},
|
},
|
||||||
"realtime_power": {
|
"realtime_power": {
|
||||||
"name": "Realtime Power"
|
"name": "Echtzeitleistung"
|
||||||
},
|
},
|
||||||
"pmv": {
|
"pmv": {
|
||||||
"name": "PMV"
|
"name": "PMV"
|
||||||
@@ -661,10 +661,10 @@
|
|||||||
"name": "Tank Actual Temperature"
|
"name": "Tank Actual Temperature"
|
||||||
},
|
},
|
||||||
"target_temperature": {
|
"target_temperature": {
|
||||||
"name": "Target Temperature"
|
"name": "Temperaturziel"
|
||||||
},
|
},
|
||||||
"time_remaining": {
|
"time_remaining": {
|
||||||
"name": "Time Remaining"
|
"name": "Verbleibende Zeit"
|
||||||
},
|
},
|
||||||
"top_compartment_remaining": {
|
"top_compartment_remaining": {
|
||||||
"name": "Top Compartment Remaining"
|
"name": "Top Compartment Remaining"
|
||||||
@@ -679,16 +679,16 @@
|
|||||||
"name": "Top Temperature"
|
"name": "Top Temperature"
|
||||||
},
|
},
|
||||||
"total_energy_consumption": {
|
"total_energy_consumption": {
|
||||||
"name": "Total Energy Consumption"
|
"name": "Gesamter Energieverbrauch"
|
||||||
},
|
},
|
||||||
"total_produced_energy": {
|
"total_produced_energy": {
|
||||||
"name": "Total produced energy"
|
"name": "Gesamte produzierte Energie"
|
||||||
},
|
},
|
||||||
"tvoc": {
|
"tvoc": {
|
||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "rinse count"
|
"name": "Waschstufe"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "wash strength"
|
"name": "wash strength"
|
||||||
@@ -739,7 +739,7 @@
|
|||||||
"name": "Desinfektionstemperatur"
|
"name": "Desinfektionstemperatur"
|
||||||
},
|
},
|
||||||
"max_temperature": {
|
"max_temperature": {
|
||||||
"name": "Maximale Zieltemperatur"
|
"name": "Maximales Temperaturziel"
|
||||||
},
|
},
|
||||||
"vacation_start_year": {
|
"vacation_start_year": {
|
||||||
"name": "Urlaubsbeginn Jahr"
|
"name": "Urlaubsbeginn Jahr"
|
||||||
@@ -772,7 +772,7 @@
|
|||||||
"name": "Kompressorfrequenz"
|
"name": "Kompressorfrequenz"
|
||||||
},
|
},
|
||||||
"target_compressor_frequency": {
|
"target_compressor_frequency": {
|
||||||
"name": "Ziel-Kompressorfrequenz"
|
"name": "Kompressorfrequenz-Ziel"
|
||||||
},
|
},
|
||||||
"compressor_current": {
|
"compressor_current": {
|
||||||
"name": "Kompressorstrom"
|
"name": "Kompressorstrom"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Kompressorleistung"
|
"name": "Kompressorleistung"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Innenraum-Wärmetauschertemperatur (T1)"
|
"name": "Innenraum-Umgebungstemperatur(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Verdampfertemperatur (T2)"
|
"name": "Innentemperatur der Heizschlange(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Außentemperatur der Heizschlange(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Außenumgebungstemperatur(T4)"
|
"name": "Außenumgebungstemperatur(T4)"
|
||||||
@@ -796,10 +799,10 @@
|
|||||||
"name": "Druckleitungstemperatur(TP)"
|
"name": "Druckleitungstemperatur(TP)"
|
||||||
},
|
},
|
||||||
"indoor_fan_speed": {
|
"indoor_fan_speed": {
|
||||||
"name": "Innenlüftergeschwindigkeit"
|
"name": "Innengerät Lüftergeschwindigkeit"
|
||||||
},
|
},
|
||||||
"target_indoor_fan_speed": {
|
"target_indoor_fan_speed": {
|
||||||
"name": "Ziel-Innenlüftergeschwindigkeit"
|
"name": "Innengerät Lüftergeschwindigkeit-Ziel"
|
||||||
},
|
},
|
||||||
"velocity": {
|
"velocity": {
|
||||||
"name": "Durchflussgeschwindigkeit"
|
"name": "Durchflussgeschwindigkeit"
|
||||||
@@ -813,7 +816,7 @@
|
|||||||
"name": "Aux Heating"
|
"name": "Aux Heating"
|
||||||
},
|
},
|
||||||
"boost_mode": {
|
"boost_mode": {
|
||||||
"name": "Boost Mode"
|
"name": "Turbo-Modus"
|
||||||
},
|
},
|
||||||
"breezeless": {
|
"breezeless": {
|
||||||
"name": "Breezeless"
|
"name": "Breezeless"
|
||||||
@@ -825,19 +828,19 @@
|
|||||||
"name": "CL-Sterilisation"
|
"name": "CL-Sterilisation"
|
||||||
},
|
},
|
||||||
"comfort_mode": {
|
"comfort_mode": {
|
||||||
"name": "Comfort Mode"
|
"name": "Comfort-Modus"
|
||||||
},
|
},
|
||||||
"dhw_power": {
|
"dhw_power": {
|
||||||
"name": "DHW Power"
|
"name": "DHW Power"
|
||||||
},
|
},
|
||||||
"disinfect": {
|
"disinfect": {
|
||||||
"name": "Disinfect"
|
"name": "Desinfizieren"
|
||||||
},
|
},
|
||||||
"vacation_mode": {
|
"vacation_mode": {
|
||||||
"name": "Urlaubsmodus"
|
"name": "Urlaubsmodus"
|
||||||
},
|
},
|
||||||
"dry": {
|
"dry": {
|
||||||
"name": "Dry"
|
"name": "Trocknen"
|
||||||
},
|
},
|
||||||
"cold_water_single": {
|
"cold_water_single": {
|
||||||
"name": "Kaltwasser einzeln"
|
"name": "Kaltwasser einzeln"
|
||||||
@@ -846,7 +849,7 @@
|
|||||||
"name": "Kaltwasser Punkt"
|
"name": "Kaltwasser Punkt"
|
||||||
},
|
},
|
||||||
"eco_mode": {
|
"eco_mode": {
|
||||||
"name": "ECO Mode"
|
"name": "ECO-Modus"
|
||||||
},
|
},
|
||||||
"memory": {
|
"memory": {
|
||||||
"name": "Memo U"
|
"name": "Memo U"
|
||||||
@@ -858,13 +861,13 @@
|
|||||||
"name": "Foam Shield"
|
"name": "Foam Shield"
|
||||||
},
|
},
|
||||||
"frost_protect": {
|
"frost_protect": {
|
||||||
"name": "Frost Protect"
|
"name": "Frostschutz"
|
||||||
},
|
},
|
||||||
"heating_power": {
|
"heating_power": {
|
||||||
"name": "Heating Power"
|
"name": "Heizleistung"
|
||||||
},
|
},
|
||||||
"indirect_wind": {
|
"indirect_wind": {
|
||||||
"name": "Indirect Wind"
|
"name": "Indirekter Wind"
|
||||||
},
|
},
|
||||||
"leak_water_protection": {
|
"leak_water_protection": {
|
||||||
"name": "Leckschutz"
|
"name": "Leckschutz"
|
||||||
@@ -882,13 +885,13 @@
|
|||||||
"name": "Main Power"
|
"name": "Main Power"
|
||||||
},
|
},
|
||||||
"natural_wind": {
|
"natural_wind": {
|
||||||
"name": "Natural Wind"
|
"name": "Natürlicher Wind"
|
||||||
},
|
},
|
||||||
"night_light": {
|
"night_light": {
|
||||||
"name": "Night Light"
|
"name": "Nachtlicht"
|
||||||
},
|
},
|
||||||
"oscillate": {
|
"oscillate": {
|
||||||
"name": "Oscillate"
|
"name": "Oszillieren"
|
||||||
},
|
},
|
||||||
"power": {
|
"power": {
|
||||||
"name": "Strom"
|
"name": "Strom"
|
||||||
@@ -897,7 +900,7 @@
|
|||||||
"name": "Powerful Purification"
|
"name": "Powerful Purification"
|
||||||
},
|
},
|
||||||
"prompt_tone": {
|
"prompt_tone": {
|
||||||
"name": "Prompt Tone"
|
"name": "Bestätigungston"
|
||||||
},
|
},
|
||||||
"regeneration": {
|
"regeneration": {
|
||||||
"name": "Regeneration"
|
"name": "Regeneration"
|
||||||
@@ -909,19 +912,19 @@
|
|||||||
"name": "Wasserweg"
|
"name": "Wasserweg"
|
||||||
},
|
},
|
||||||
"screen_display": {
|
"screen_display": {
|
||||||
"name": "Screen Display"
|
"name": "Bildschirmanzeige"
|
||||||
},
|
},
|
||||||
"screen_display_alternate": {
|
"screen_display_alternate": {
|
||||||
"name": "Screen Display Alternate"
|
"name": "Bildschirmanzeige Alternative"
|
||||||
},
|
},
|
||||||
"sensor_light": {
|
"sensor_light": {
|
||||||
"name": "Sensor Light"
|
"name": "Sensor Light"
|
||||||
},
|
},
|
||||||
"silent_mode": {
|
"silent_mode": {
|
||||||
"name": "Silent Mode"
|
"name": "Silent-Modus"
|
||||||
},
|
},
|
||||||
"sleep_mode": {
|
"sleep_mode": {
|
||||||
"name": "Sleep Mode"
|
"name": "Sleep-Modus"
|
||||||
},
|
},
|
||||||
"out_silent": {
|
"out_silent": {
|
||||||
"name": "Außengerät Leisemodus"
|
"name": "Außengerät Leisemodus"
|
||||||
@@ -948,22 +951,22 @@
|
|||||||
"name": "Sterilisation"
|
"name": "Sterilisation"
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"name": "Storage"
|
"name": "Aufbewahrung"
|
||||||
},
|
},
|
||||||
"swing": {
|
"swing": {
|
||||||
"name": "swing"
|
"name": "Schwingen"
|
||||||
},
|
},
|
||||||
"swing_horizontal": {
|
"swing_horizontal": {
|
||||||
"name": "Swing Horizontal"
|
"name": "Horizontal schwingen"
|
||||||
},
|
},
|
||||||
"swing_vertical": {
|
"swing_vertical": {
|
||||||
"name": "Swing Vertical"
|
"name": "Vertikal schwingen"
|
||||||
},
|
},
|
||||||
"self_clean": {
|
"self_clean": {
|
||||||
"name": "Self Clean"
|
"name": "Selbstreinigung"
|
||||||
},
|
},
|
||||||
"sound": {
|
"sound": {
|
||||||
"name": "Sound"
|
"name": "Ton"
|
||||||
},
|
},
|
||||||
"tbh": {
|
"tbh": {
|
||||||
"name": "TBH"
|
"name": "TBH"
|
||||||
@@ -998,13 +1001,13 @@
|
|||||||
},
|
},
|
||||||
"water_heater": {
|
"water_heater": {
|
||||||
"domestic_hot_water": {
|
"domestic_hot_water": {
|
||||||
"name": "Domestic hot water"
|
"name": "Heimisches heißes Wasser"
|
||||||
},
|
},
|
||||||
"bathing": {
|
"bathing": {
|
||||||
"name": "Bathing"
|
"name": "Baden"
|
||||||
},
|
},
|
||||||
"heating": {
|
"heating": {
|
||||||
"name": "Heating"
|
"name": "Heizen"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "Rinse count"
|
"name": "Wash level"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "Wash strength"
|
"name": "Wash strength"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Compressor Power"
|
"name": "Compressor Power"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Indoor Coil Temperature (T1)"
|
"name": "Indoor Ambient Temperature(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Evaporator Temperature (T2)"
|
"name": "Indoor Coil Temperature(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Outdoor Coil Temperature(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Outdoor Ambient Temperature(T4)"
|
"name": "Outdoor Ambient Temperature(T4)"
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "COVT"
|
"name": "COVT"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "Recuento de aclarados"
|
"name": "Nivel de lavado"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "Potencia de lavado"
|
"name": "Potencia de lavado"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Potencia del compresor"
|
"name": "Potencia del compresor"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Temperatura del serpentín interior (T1)"
|
"name": "Temperatura ambiente interior(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Temperatura del evaporador (T2)"
|
"name": "Temperatura del serpentín interior(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Temperatura del serpentín exterior(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Temperatura ambiente exterior(T4)"
|
"name": "Temperatura ambiente exterior(T4)"
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "rinse count"
|
"name": "Niveau de lavage"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "wash strength"
|
"name": "wash strength"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Puissance du compresseur"
|
"name": "Puissance du compresseur"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Température de la batterie intérieure (T1)"
|
"name": "Température ambiante intérieure(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Température de l'évaporateur (T2)"
|
"name": "Température del'échangeur intérieur(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Température de l'échangeur extérieur(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Température ambiante extérieure(T4)"
|
"name": "Température ambiante extérieure(T4)"
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "rinse count"
|
"name": "Mosási szint"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "wash strength"
|
"name": "wash strength"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Kompresszor teljesítmény"
|
"name": "Kompresszor teljesítmény"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Beltéri hőcserélő hőmérséklet (T1)"
|
"name": "Beltéri környezeti hőmérséklet(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Párologtató hőmérséklet (T2)"
|
"name": "Beltéri hőcserélő hőmérséklet(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Kültéri hőcserélő hőmérséklet(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Kültéri környezeti hőmérséklet(T4)"
|
"name": "Kültéri környezeti hőmérséklet(T4)"
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "Numero Risciacqui"
|
"name": "Livello di lavaggio"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "Intensità Lavaggio"
|
"name": "Intensità Lavaggio"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Potenza Compressore"
|
"name": "Potenza Compressore"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Temperatura Batteria Interna (T1)"
|
"name": "Temperatura ambiente interna(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Temperatura Evaporatore (T2)"
|
"name": "Temperatura della serpentina interna(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Temperatura della serpentina esterna(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Temperatura Ambiente Esterna(T4)"
|
"name": "Temperatura Ambiente Esterna(T4)"
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "Количество полосканий"
|
"name": "Уровень стирки"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "Wash strength"
|
"name": "Wash strength"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Мощность компрессора"
|
"name": "Мощность компрессора"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Температура внутреннего теплообменника (T1)"
|
"name": "Комнатная температура(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Температура испарителя (T2)"
|
"name": "Температура внутреннего теплообменника(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Температура наружного теплообменника(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Наружная температура окружающей среды(T4)"
|
"name": "Наружная температура окружающей среды(T4)"
|
||||||
|
|||||||
@@ -688,7 +688,7 @@
|
|||||||
"name": "TVOC"
|
"name": "TVOC"
|
||||||
},
|
},
|
||||||
"wash_level": {
|
"wash_level": {
|
||||||
"name": "rinse count"
|
"name": "Úroveň prania"
|
||||||
},
|
},
|
||||||
"wash_strength": {
|
"wash_strength": {
|
||||||
"name": "wash strength"
|
"name": "wash strength"
|
||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "Výkon kompresora"
|
"name": "Výkon kompresora"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "Teplota vnútorného výmenníka (T1)"
|
"name": "Vnútorná teplota prostredia(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "Teplota výparníka (T2)"
|
"name": "Teplota vnútornej špirály(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "Teplota vonkajšej špirály(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "Vonkajšia teplota okolia(T4)"
|
"name": "Vonkajšia teplota okolia(T4)"
|
||||||
|
|||||||
@@ -783,11 +783,14 @@
|
|||||||
"compressor_power": {
|
"compressor_power": {
|
||||||
"name": "压缩机功率"
|
"name": "压缩机功率"
|
||||||
},
|
},
|
||||||
"indoor_coil_temperature": {
|
"indoor_ambient_temperature": {
|
||||||
"name": "室内盘管温度 (T1)"
|
"name": "室内环境温度(T1)"
|
||||||
},
|
},
|
||||||
"evaporator_temperature": {
|
"indoor_coil_temperature": {
|
||||||
"name": "蒸发器温度 (T2)"
|
"name": "室内盘管温度(T2)"
|
||||||
|
},
|
||||||
|
"outdoor_coil_temperature": {
|
||||||
|
"name": "室外盘管温度(T3)"
|
||||||
},
|
},
|
||||||
"outdoor_ambient_temperature": {
|
"outdoor_ambient_temperature": {
|
||||||
"name": "室外环境温度(T4)"
|
"name": "室外环境温度(T4)"
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from midealocal.device import DeviceType
|
from midealan.device import DeviceType
|
||||||
from midealocal.devices.c3 import DeviceAttributes as C3Attributes
|
from midealan.devices.c3 import DeviceAttributes as C3Attributes
|
||||||
from midealocal.devices.c3 import MideaC3Device
|
from midealan.devices.c3 import MideaC3Device
|
||||||
from midealocal.devices.cd import DeviceAttributes as CDAttributes
|
from midealan.devices.cd import DeviceAttributes as CDAttributes
|
||||||
from midealocal.devices.cd import MideaCDDevice
|
from midealan.devices.cd import MideaCDDevice
|
||||||
from midealocal.devices.e2 import DeviceAttributes as E2Attributes
|
from midealan.devices.e2 import DeviceAttributes as E2Attributes
|
||||||
from midealocal.devices.e2 import MideaE2Device
|
from midealan.devices.e2 import MideaE2Device
|
||||||
from midealocal.devices.e3 import MideaE3Device
|
from midealan.devices.e3 import MideaE3Device
|
||||||
from midealocal.devices.e6 import DeviceAttributes as E6Attributes
|
from midealan.devices.e6 import DeviceAttributes as E6Attributes
|
||||||
from midealocal.devices.e6 import MideaE6Device
|
from midealan.devices.e6 import MideaE6Device
|
||||||
|
|
||||||
from .const import DEVICES, DOMAIN
|
from .const import DEVICES, DOMAIN
|
||||||
from .midea_devices import MIDEA_DEVICES
|
from .midea_devices import MIDEA_DEVICES
|
||||||
@@ -242,6 +242,16 @@ class MideaE3WaterHeater(MideaWaterHeater):
|
|||||||
"""Midea E3 Water Heater entity init."""
|
"""Midea E3 Water Heater entity init."""
|
||||||
super().__init__(device, entity_key)
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WaterHeaterEntityFeature:
|
||||||
|
"""Midea E3 Water Heater supported features."""
|
||||||
|
# E3 implements turn_on/turn_off and reports on/off state, so advertise
|
||||||
|
# ON_OFF to self-document that support (matches E2).
|
||||||
|
return (
|
||||||
|
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||||
|
| WaterHeaterEntityFeature.ON_OFF
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_temp(self) -> float:
|
def min_temp(self) -> float:
|
||||||
"""Midea E3 Water Heater min temperature."""
|
"""Midea E3 Water Heater min temperature."""
|
||||||
@@ -276,6 +286,16 @@ class MideaC3WaterHeater(MideaWaterHeater):
|
|||||||
"""Midea C3 Water Heater entity init."""
|
"""Midea C3 Water Heater entity init."""
|
||||||
super().__init__(device, entity_key)
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WaterHeaterEntityFeature:
|
||||||
|
"""Midea C3 Water Heater supported features."""
|
||||||
|
# C3 implements turn_on/turn_off (dhw_power) and reports on/off state,
|
||||||
|
# so advertise ON_OFF to self-document that support (matches E2).
|
||||||
|
return (
|
||||||
|
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||||
|
| WaterHeaterEntityFeature.ON_OFF
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_operation(self) -> str:
|
def current_operation(self) -> str:
|
||||||
"""Midea C3 Water Heater current operation."""
|
"""Midea C3 Water Heater current operation."""
|
||||||
@@ -356,6 +376,16 @@ class MideaE6WaterHeater(MideaWaterHeater):
|
|||||||
self._use
|
self._use
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WaterHeaterEntityFeature:
|
||||||
|
"""Midea E6 Water Heater supported features."""
|
||||||
|
# E6 implements turn_on/turn_off and reports on/off state, so advertise
|
||||||
|
# ON_OFF to self-document that support (matches E2).
|
||||||
|
return (
|
||||||
|
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||||
|
| WaterHeaterEntityFeature.ON_OFF
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_operation(self) -> str:
|
def current_operation(self) -> str:
|
||||||
"""Midea E6 Water Heater current operation."""
|
"""Midea E6 Water Heater current operation."""
|
||||||
|
|||||||
+19
-19
@@ -30,7 +30,7 @@
|
|||||||
"power": 2.1,
|
"power": 2.1,
|
||||||
"current": 0.12,
|
"current": 0.12,
|
||||||
"energy": 28.33,
|
"energy": 28.33,
|
||||||
"power_factor": 0.16,
|
"power_factor": 0.13,
|
||||||
"update": {
|
"update": {
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
"installed_version": 268513381,
|
"installed_version": 268513381,
|
||||||
@@ -47,8 +47,8 @@
|
|||||||
"countdown_to_turn_off": 0,
|
"countdown_to_turn_off": 0,
|
||||||
"voltage": 121.5,
|
"voltage": 121.5,
|
||||||
"countdown_to_turn_on": 0,
|
"countdown_to_turn_on": 0,
|
||||||
"energy": 54.71,
|
"energy": 54.72,
|
||||||
"power_factor": 0.87,
|
"power_factor": 0.3,
|
||||||
"ac_frequency": 60,
|
"ac_frequency": 60,
|
||||||
"update": {
|
"update": {
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
@@ -58,8 +58,8 @@
|
|||||||
"latest_release_notes": null
|
"latest_release_notes": null
|
||||||
},
|
},
|
||||||
"linkquality": 134,
|
"linkquality": 134,
|
||||||
"power": 84.2,
|
"power": 0.2,
|
||||||
"current": 0.82,
|
"current": 0.01,
|
||||||
"power_on_behavior": "on"
|
"power_on_behavior": "on"
|
||||||
},
|
},
|
||||||
"0xb40e060fffe031e3": {
|
"0xb40e060fffe031e3": {
|
||||||
@@ -74,12 +74,12 @@
|
|||||||
"led_brightness": 100,
|
"led_brightness": 100,
|
||||||
"countdown_to_turn_off": 0,
|
"countdown_to_turn_off": 0,
|
||||||
"countdown_to_turn_on": 0,
|
"countdown_to_turn_on": 0,
|
||||||
"voltage": 119.8,
|
"voltage": 120.5,
|
||||||
"state": "ON",
|
"state": "ON",
|
||||||
"ac_frequency": 60,
|
"ac_frequency": 60,
|
||||||
"energy": 112.38,
|
"energy": 112.4,
|
||||||
"power": 98.7,
|
"power": 0.8,
|
||||||
"current": 0.89,
|
"current": 0.02,
|
||||||
"power_factor": 0.38,
|
"power_factor": 0.38,
|
||||||
"update": {
|
"update": {
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
@@ -96,10 +96,10 @@
|
|||||||
"countdown_to_turn_off": 0,
|
"countdown_to_turn_off": 0,
|
||||||
"countdown_to_turn_on": 0,
|
"countdown_to_turn_on": 0,
|
||||||
"voltage": 121.9,
|
"voltage": 121.9,
|
||||||
"energy": 49.6,
|
"energy": 49.61,
|
||||||
"state": "ON",
|
"state": "ON",
|
||||||
"power": 46.6,
|
"power": 41.4,
|
||||||
"current": 0.56,
|
"current": 0.47,
|
||||||
"ac_frequency": 60,
|
"ac_frequency": 60,
|
||||||
"power_factor": 0.74,
|
"power_factor": 0.74,
|
||||||
"update": {
|
"update": {
|
||||||
@@ -114,12 +114,12 @@
|
|||||||
},
|
},
|
||||||
"0xffffb40e060895b3": {
|
"0xffffb40e060895b3": {
|
||||||
"state": "ON",
|
"state": "ON",
|
||||||
"voltage": 121.8,
|
"voltage": 121.7,
|
||||||
"ac_frequency": 60,
|
"ac_frequency": 60,
|
||||||
"energy": 7.14,
|
"energy": 7.14,
|
||||||
"current": 0.01,
|
"current": 0.01,
|
||||||
"power": 0.1,
|
"power": 0.1,
|
||||||
"power_factor": 0.11,
|
"power_factor": 0.22,
|
||||||
"linkquality": 123,
|
"linkquality": 123,
|
||||||
"update": {
|
"update": {
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
@@ -136,13 +136,13 @@
|
|||||||
"0xffffb40e0608864e": {
|
"0xffffb40e0608864e": {
|
||||||
"led_brightness": 100,
|
"led_brightness": 100,
|
||||||
"countdown_to_turn_off": 0,
|
"countdown_to_turn_off": 0,
|
||||||
"voltage": 121.3,
|
"voltage": 121.8,
|
||||||
"energy": 17.5,
|
"energy": 17.5,
|
||||||
"countdown_to_turn_on": 0,
|
"countdown_to_turn_on": 0,
|
||||||
"state": "ON",
|
"state": "ON",
|
||||||
"current": 0.02,
|
"current": 0.02,
|
||||||
"ac_frequency": 60,
|
"ac_frequency": 60,
|
||||||
"power": 0.4,
|
"power": 0.3,
|
||||||
"power_factor": 0.14,
|
"power_factor": 0.14,
|
||||||
"update": {
|
"update": {
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
"0xffffb40e060893d8": {
|
"0xffffb40e060893d8": {
|
||||||
"state": "ON",
|
"state": "ON",
|
||||||
"led_brightness": 100,
|
"led_brightness": 100,
|
||||||
"voltage": 121.5,
|
"voltage": 122,
|
||||||
"countdown_to_turn_off": 0,
|
"countdown_to_turn_off": 0,
|
||||||
"countdown_to_turn_on": 0,
|
"countdown_to_turn_on": 0,
|
||||||
"energy": 3.11,
|
"energy": 3.11,
|
||||||
@@ -188,11 +188,11 @@
|
|||||||
"latest_release_notes": null
|
"latest_release_notes": null
|
||||||
},
|
},
|
||||||
"power_factor": 0.06,
|
"power_factor": 0.06,
|
||||||
"power": 0
|
"power": 0.1
|
||||||
},
|
},
|
||||||
"0xa4c1380d0679ffff": {
|
"0xa4c1380d0679ffff": {
|
||||||
"battery": 100,
|
"battery": 100,
|
||||||
"temperature": 27.7,
|
"temperature": 27.6,
|
||||||
"temperature_units": "celsius",
|
"temperature_units": "celsius",
|
||||||
"temperature_calibration": 0,
|
"temperature_calibration": 0,
|
||||||
"update": {
|
"update": {
|
||||||
|
|||||||
Reference in New Issue
Block a user