diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 34774ab8..240978f6 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -27,18 +27,18 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
- uses: github/codeql-action/autobuild@v2
+ uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
index fa783c06..6a2f092e 100755
--- a/.github/workflows/linter.yml
+++ b/.github/workflows/linter.yml
@@ -35,5 +35,5 @@ jobs:
VALIDATE_JSCPD: false
VALIDATE_PYTHON_PYLINT: false
VALIDATE_PYTHON_MYPY: false
- VALIDATE_PYTHON_BLACK: false
- VALIDATE_PYTHON_ISORT: false
+ # VALIDATE_PYTHON_BLACK: false
+ # VALIDATE_PYTHON_ISORT: false
diff --git a/custom_components/midea_ac_lan/__init__.py b/custom_components/midea_ac_lan/__init__.py
index a78ee2d0..014d7650 100644
--- a/custom_components/midea_ac_lan/__init__.py
+++ b/custom_components/midea_ac_lan/__init__.py
@@ -1,31 +1,32 @@
import logging
-import voluptuous as vol
+
import homeassistant.helpers.config_validation as cv
+import voluptuous as vol
+from homeassistant.const import (
+ CONF_CUSTOMIZE,
+ CONF_DEVICE_ID,
+ CONF_IP_ADDRESS,
+ CONF_NAME,
+ CONF_PORT,
+ CONF_PROTOCOL,
+ CONF_TOKEN,
+ CONF_TYPE,
+)
+from homeassistant.core import HomeAssistant
+
from .const import (
- DOMAIN,
+ ALL_PLATFORM,
CONF_ACCOUNT,
CONF_KEY,
CONF_MODEL,
- CONF_SUBTYPE,
CONF_REFRESH_INTERVAL,
+ CONF_SUBTYPE,
DEVICES,
+ DOMAIN,
EXTRA_SWITCH,
- ALL_PLATFORM,
-)
-from .midea_devices import MIDEA_DEVICES
-
-from homeassistant.core import HomeAssistant
-from homeassistant.const import (
- CONF_NAME,
- CONF_TOKEN,
- CONF_IP_ADDRESS,
- CONF_PORT,
- CONF_PROTOCOL,
- CONF_DEVICE_ID,
- CONF_TYPE,
- CONF_CUSTOMIZE,
)
from .midea.devices import async_device_selector
+from .midea_devices import MIDEA_DEVICES
_LOGGER = logging.getLogger(__name__)
@@ -34,18 +35,13 @@ async def update_listener(hass, config_entry):
for platform in ALL_PLATFORM:
await hass.config_entries.async_forward_entry_unload(config_entry, platform)
for platform in ALL_PLATFORM:
- hass.async_create_task(hass.config_entries.async_forward_entry_setup(
- config_entry, platform))
+ hass.async_create_task(
+ hass.config_entries.async_forward_entry_setup(config_entry, platform)
+ )
device_id = 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
- )
+ 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 = hass.data[DOMAIN][DEVICES].get(device_id)
if dev:
dev.set_customize(customize)
@@ -60,7 +56,10 @@ async def async_setup(hass: HomeAssistant, hass_config: dict):
attributes = []
for device_entities in MIDEA_DEVICES.values():
for attribute_name, attribute in device_entities.get("entities").items():
- if attribute.get("type") in EXTRA_SWITCH and attribute_name.value not in attributes:
+ if (
+ attribute.get("type") in EXTRA_SWITCH
+ and attribute_name.value not in attributes
+ ):
attributes.append(attribute_name.value)
def service_set_attribute(service):
@@ -72,11 +71,20 @@ def service_set_attribute(service):
if attr == "fan_speed" and value == "auto":
value = 102
item = MIDEA_DEVICES.get(dev.device_type).get("entities").get(attr)
- if (item and (item.get("type") in EXTRA_SWITCH) or
- (dev.device_type == 0xAC and attr == "fan_speed" and value in range(0, 103))):
+ if (
+ item
+ and (item.get("type") in EXTRA_SWITCH)
+ or (
+ dev.device_type == 0xAC
+ and attr == "fan_speed"
+ and value in range(0, 103)
+ )
+ ):
dev.set_attribute(attr=attr, value=value)
else:
- _LOGGER.error(f"Appliance [{device_id}] has no attribute {attr} or value is invalid")
+ _LOGGER.error(
+ f"Appliance [{device_id}] has no attribute {attr} or value is invalid"
+ )
def service_send_command(service):
device_id = service.data.get("device_id")
@@ -85,7 +93,9 @@ def service_send_command(service):
try:
cmd_body = bytearray.fromhex(cmd_body)
except ValueError:
- _LOGGER.error(f"Appliance [{device_id}] invalid cmd_body, a hexadecimal string required")
+ _LOGGER.error(
+ f"Appliance [{device_id}] invalid cmd_body, a hexadecimal string required"
+ )
return
dev = hass.data[DOMAIN][DEVICES].get(device_id)
if dev:
@@ -99,9 +109,9 @@ def service_send_command(service):
{
vol.Required("device_id"): vol.Coerce(int),
vol.Required("attribute"): vol.In(attributes),
- vol.Required("value"): vol.Any(int, cv.boolean, str)
+ vol.Required("value"): vol.Any(int, cv.boolean, str),
}
- )
+ ),
)
hass.services.async_register(
@@ -112,9 +122,9 @@ def service_send_command(service):
{
vol.Required("device_id"): vol.Coerce(int),
vol.Required("cmd_type"): vol.In([2, 3]),
- vol.Required("cmd_body"): str
+ vol.Required("cmd_body"): str,
}
- )
+ ),
)
return True
@@ -128,7 +138,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry):
if name is None:
name = f"{device_id}"
if device_type is None:
- device_type = 0xac
+ device_type = 0xAC
token = config_entry.data.get(CONF_TOKEN)
key = config_entry.data.get(CONF_KEY)
ip_address = config_entry.options.get(CONF_IP_ADDRESS, None)
@@ -167,8 +177,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry):
hass.data[DOMAIN][DEVICES] = {}
hass.data[DOMAIN][DEVICES][device_id] = device
for platform in ALL_PLATFORM:
- hass.async_create_task(hass.config_entries.async_forward_entry_setup(
- config_entry, platform))
+ hass.async_create_task(
+ hass.config_entries.async_forward_entry_setup(config_entry, platform)
+ )
config_entry.add_update_listener(update_listener)
return True
return False
diff --git a/custom_components/midea_ac_lan/binary_sensor.py b/custom_components/midea_ac_lan/binary_sensor.py
index 860ed591..2dcc4b3a 100644
--- a/custom_components/midea_ac_lan/binary_sensor.py
+++ b/custom_components/midea_ac_lan/binary_sensor.py
@@ -1,19 +1,15 @@
from homeassistant.components.binary_sensor import BinarySensorEntity
-from homeassistant.const import Platform, CONF_DEVICE_ID, CONF_SENSORS
-from .const import (
- DOMAIN,
- DEVICES
-)
-from .midea_entity import MideaEntity
+from homeassistant.const import CONF_DEVICE_ID, CONF_SENSORS, Platform
+
+from .const import DEVICES, DOMAIN
from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_sensors = config_entry.options.get(
- CONF_SENSORS, []
- )
+ extra_sensors = config_entry.options.get(CONF_SENSORS, [])
binary_sensors = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.BINARY_SENSOR and entity_key in extra_sensors:
diff --git a/custom_components/midea_ac_lan/climate.py b/custom_components/midea_ac_lan/climate.py
index 7c9bb525..1e0df6bc 100644
--- a/custom_components/midea_ac_lan/climate.py
+++ b/custom_components/midea_ac_lan/climate.py
@@ -1,12 +1,11 @@
+import logging
+
from homeassistant.components.climate import (
ATTR_HVAC_MODE,
- ClimateEntity,
- ClimateEntityFeature,
FAN_AUTO,
FAN_HIGH,
FAN_LOW,
FAN_MEDIUM,
- HVACMode,
PRESET_AWAY,
PRESET_BOOST,
PRESET_COMFORT,
@@ -18,23 +17,23 @@
SWING_OFF,
SWING_ON,
SWING_VERTICAL,
+ ClimateEntity,
+ ClimateEntityFeature,
+ HVACMode,
)
from homeassistant.const import (
+ ATTR_TEMPERATURE,
+ CONF_DEVICE_ID,
+ CONF_SWITCHES,
MAJOR_VERSION,
MINOR_VERSION,
+ PRECISION_HALVES,
+ PRECISION_WHOLE,
Platform,
UnitOfTemperature,
- PRECISION_WHOLE,
- PRECISION_HALVES,
- ATTR_TEMPERATURE,
- CONF_DEVICE_ID,
- CONF_SWITCHES,
)
-from .const import (
- DOMAIN,
- DEVICES,
-)
+from .const import DEVICES, DOMAIN
from .midea.devices.ac.device import DeviceAttributes as ACAttributes
from .midea.devices.c3.device import DeviceAttributes as C3Attributes
from .midea.devices.cc.device import DeviceAttributes as CCAttributes
@@ -43,7 +42,6 @@
from .midea_devices import MIDEA_DEVICES
from .midea_entity import MideaEntity
-import logging
_LOGGER = logging.getLogger(__name__)
@@ -57,12 +55,12 @@
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
devs = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
- if config["type"] == Platform.CLIMATE and (config.get("default") or entity_key in extra_switches):
+ if config["type"] == Platform.CLIMATE and (
+ config.get("default") or entity_key in extra_switches
+ ):
if device.device_type == 0xAC:
devs.append(MideaACClimate(device, entity_key))
elif device.device_type == 0xCC:
@@ -79,7 +77,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class MideaClimate(MideaEntity, ClimateEntity):
# https://developers.home-assistant.io/blog/2024/01/24/climate-climateentityfeatures-expanded
- _enable_turn_on_off_backwards_compatibility: bool = False # maybe remove after 2025.1
+ _enable_turn_on_off_backwards_compatibility: bool = (
+ False # maybe remove after 2025.1
+ )
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
@@ -87,10 +87,10 @@ def __init__(self, device, entity_key):
@property
def supported_features(self):
features = (
- ClimateEntityFeature.TARGET_TEMPERATURE |
- ClimateEntityFeature.FAN_MODE |
- ClimateEntityFeature.PRESET_MODE |
- ClimateEntityFeature.SWING_MODE
+ ClimateEntityFeature.TARGET_TEMPERATURE
+ | ClimateEntityFeature.FAN_MODE
+ | ClimateEntityFeature.PRESET_MODE
+ | ClimateEntityFeature.SWING_MODE
)
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
features |= ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
@@ -184,7 +184,8 @@ def set_temperature(self, **kwargs) -> None:
try:
mode = self._modes.index(hvac_mode.lower()) if hvac_mode else None
self._device.set_target_temperature(
- target_temperature=temperature, mode=mode)
+ target_temperature=temperature, mode=mode
+ )
except ValueError as e:
_LOGGER.error(f"set_temperature {e}, kwargs = {kwargs}")
@@ -223,28 +224,44 @@ def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
- _LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
+ _LOGGER.debug(
+ f"Entity {self.entity_id} update_state {repr(e)}, status = {status}"
+ )
class MideaACClimate(MideaClimate):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._modes = [HVACMode.OFF, HVACMode.AUTO, HVACMode.COOL, HVACMode.DRY, HVACMode.HEAT, HVACMode.FAN_ONLY]
+ self._modes = [
+ HVACMode.OFF,
+ HVACMode.AUTO,
+ HVACMode.COOL,
+ HVACMode.DRY,
+ HVACMode.HEAT,
+ HVACMode.FAN_ONLY,
+ ]
self._fan_speeds = {
FAN_SILENT.capitalize(): 20,
FAN_LOW.capitalize(): 40,
FAN_MEDIUM.capitalize(): 60,
FAN_HIGH.capitalize(): 80,
FAN_FULL_SPEED.capitalize(): 100,
- FAN_AUTO.capitalize(): 102
+ FAN_AUTO.capitalize(): 102,
}
self._swing_modes = [
SWING_OFF.capitalize(),
SWING_VERTICAL.capitalize(),
SWING_HORIZONTAL.capitalize(),
- SWING_BOTH.capitalize()
+ SWING_BOTH.capitalize(),
+ ]
+ self._preset_modes = [
+ PRESET_NONE,
+ PRESET_COMFORT,
+ PRESET_ECO,
+ PRESET_BOOST,
+ PRESET_SLEEP,
+ PRESET_AWAY,
]
- self._preset_modes = [PRESET_NONE, PRESET_COMFORT, PRESET_ECO, PRESET_BOOST, PRESET_SLEEP, PRESET_AWAY]
@property
def fan_modes(self):
@@ -268,12 +285,15 @@ def fan_mode(self) -> str:
@property
def target_temperature_step(self):
- return PRECISION_WHOLE if self._device.temperature_step == 1 else PRECISION_HALVES
+ return (
+ PRECISION_WHOLE if self._device.temperature_step == 1 else PRECISION_HALVES
+ )
@property
def swing_mode(self):
- swing_mode = (1 if self._device.get_attribute(ACAttributes.swing_vertical) else 0) + \
- (2 if self._device.get_attribute(ACAttributes.swing_horizontal) else 0)
+ swing_mode = (
+ 1 if self._device.get_attribute(ACAttributes.swing_vertical) else 0
+ ) + (2 if self._device.get_attribute(ACAttributes.swing_horizontal) else 0)
return self._swing_modes[swing_mode]
@property
@@ -289,17 +309,23 @@ def set_swing_mode(self, swing_mode: str) -> None:
swing = self._swing_modes.index(swing_mode.capitalize())
swing_vertical = swing & 1 > 0
swing_horizontal = swing & 2 > 0
- self._device.set_swing(swing_vertical=swing_vertical, swing_horizontal=swing_horizontal)
+ self._device.set_swing(
+ swing_vertical=swing_vertical, swing_horizontal=swing_horizontal
+ )
class MideaCCClimate(MideaClimate):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._modes = [HVACMode.OFF, HVACMode.FAN_ONLY, HVACMode.DRY, HVACMode.HEAT, HVACMode.COOL, HVACMode.AUTO]
- self._swing_modes = [
- SWING_OFF.capitalize(),
- SWING_ON.capitalize()
+ self._modes = [
+ HVACMode.OFF,
+ HVACMode.FAN_ONLY,
+ HVACMode.DRY,
+ HVACMode.HEAT,
+ HVACMode.COOL,
+ HVACMode.AUTO,
]
+ self._swing_modes = [SWING_OFF.capitalize(), SWING_ON.capitalize()]
self._preset_modes = [PRESET_NONE, PRESET_SLEEP, PRESET_ECO]
@property
@@ -316,7 +342,11 @@ def target_temperature_step(self):
@property
def swing_mode(self):
- return SWING_ON.capitalize() if self._device.get_attribute(CCAttributes.swing) else SWING_OFF.capitalize()
+ return (
+ SWING_ON.capitalize()
+ if self._device.get_attribute(CCAttributes.swing)
+ else SWING_OFF.capitalize()
+ )
def set_fan_mode(self, fan_mode: str) -> None:
self._device.set_attribute(attr=CCAttributes.fan_speed, value=fan_mode)
@@ -324,7 +354,7 @@ def set_fan_mode(self, fan_mode: str) -> None:
def set_swing_mode(self, swing_mode: str) -> None:
self._device.set_attribute(
attr=CCAttributes.swing,
- value=swing_mode.capitalize() == SWING_ON.capitalize()
+ value=swing_mode.capitalize() == SWING_ON.capitalize(),
)
@@ -386,8 +416,11 @@ def supported_features(self):
@property
def target_temperature_step(self):
- return PRECISION_WHOLE if \
- self._device.get_attribute(C3Attributes.zone_temp_type)[self._zone] else PRECISION_HALVES
+ return (
+ PRECISION_WHOLE
+ if self._device.get_attribute(C3Attributes.zone_temp_type)[self._zone]
+ else PRECISION_HALVES
+ )
@property
def min_temp(self):
@@ -437,7 +470,8 @@ def set_temperature(self, **kwargs) -> None:
try:
mode = self._modes.index(hvac_mode.lower()) if hvac_mode else None
self._device.set_target_temperature(
- zone=self._zone, target_temperature=temperature, mode=mode)
+ zone=self._zone, target_temperature=temperature, mode=mode
+ )
except ValueError as e:
_LOGGER.error(f"set_temperature {e}, kwargs = {kwargs}")
@@ -457,7 +491,9 @@ def __init__(self, device, entity_key):
@property
def supported_features(self):
- features = ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
+ features = (
+ ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
+ )
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
features |= ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
return features
@@ -492,7 +528,11 @@ def target_temperature_high(self):
@property
def hvac_mode(self) -> str:
- return HVACMode.HEAT if self._device.get_attribute(attr=FBAttributes.power) else HVACMode.OFF
+ return (
+ HVACMode.HEAT
+ if self._device.get_attribute(attr=FBAttributes.power)
+ else HVACMode.OFF
+ )
@property
def current_temperature(self):
@@ -506,7 +546,9 @@ def set_temperature(self, **kwargs) -> None:
if hvac_mode == HVACMode.OFF:
self.turn_off()
else:
- self._device.set_attribute(attr=FBAttributes.target_temperature, value=temperature)
+ self._device.set_attribute(
+ attr=FBAttributes.target_temperature, value=temperature
+ )
def set_hvac_mode(self, hvac_mode: str) -> None:
hvac_mode = hvac_mode.lower()
diff --git a/custom_components/midea_ac_lan/config_flow.py b/custom_components/midea_ac_lan/config_flow.py
index 900bd5ce..6c5b1ecc 100644
--- a/custom_components/midea_ac_lan/config_flow.py
+++ b/custom_components/midea_ac_lan/config_flow.py
@@ -1,48 +1,57 @@
-import voluptuous as vol
import os
+
+import voluptuous as vol
+
try:
from homeassistant.helpers.json import save_json
except ImportError:
from homeassistant.util.json import save_json
-from homeassistant.util.json import load_json
+
import logging
-from .const import (
- DOMAIN,
- EXTRA_SENSOR,
- EXTRA_CONTROL,
- CONF_ACCOUNT,
- CONF_SERVER,
- CONF_KEY,
- CONF_MODEL,
- CONF_SUBTYPE,
- CONF_REFRESH_INTERVAL
-)
+
+import homeassistant.helpers.config_validation as cv
from homeassistant import config_entries
-from homeassistant.core import callback
from homeassistant.const import (
- CONF_NAME,
+ CONF_CUSTOMIZE,
CONF_DEVICE,
- CONF_TOKEN,
CONF_DEVICE_ID,
- CONF_TYPE,
CONF_IP_ADDRESS,
- CONF_PROTOCOL,
+ CONF_NAME,
+ CONF_PASSWORD,
CONF_PORT,
- CONF_SWITCHES,
+ CONF_PROTOCOL,
CONF_SENSORS,
- CONF_CUSTOMIZE,
- CONF_PASSWORD,
+ CONF_SWITCHES,
+ CONF_TOKEN,
+ CONF_TYPE,
)
-import homeassistant.helpers.config_validation as cv
+from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_create_clientsession
-from .midea.core.discover import discover
+from homeassistant.util.json import load_json
+
+from .const import (
+ CONF_ACCOUNT,
+ CONF_KEY,
+ CONF_MODEL,
+ CONF_REFRESH_INTERVAL,
+ CONF_SERVER,
+ CONF_SUBTYPE,
+ DOMAIN,
+ EXTRA_CONTROL,
+ EXTRA_SENSOR,
+)
from .midea.core.cloud import get_midea_cloud
from .midea.core.device import MiedaDevice
+from .midea.core.discover import discover
from .midea_devices import MIDEA_DEVICES
_LOGGER = logging.getLogger(__name__)
-ADD_WAY = {"discovery": "Discover automatically", "manually": "Configure manually", "list": "List all appliances only"}
+ADD_WAY = {
+ "discovery": "Discover automatically",
+ "manually": "Configure manually",
+ "list": "List all appliances only",
+}
PROTOCOLS = {1: "V1", 2: "V2", 3: "V3"}
STORAGE_PATH = f".storage/{DOMAIN}"
@@ -57,7 +66,7 @@
PRESET_ACCOUNT = [
39182118275972017797890111985649342047468653967530949796945843010512,
29406100301096535908214728322278519471982973450672552249652548883645,
- 39182118275972017797890111985649342050088014265865102175083010656997
+ 39182118275972017797890111985649342050088014265865102175083010656997,
]
@@ -79,7 +88,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
def _save_device_config(self, data: dict):
os.makedirs(self.hass.config.path(STORAGE_PATH), exist_ok=True)
- record_file = self.hass.config.path(f"{STORAGE_PATH}/{data[CONF_DEVICE_ID]}.json")
+ record_file = self.hass.config.path(
+ f"{STORAGE_PATH}/{data[CONF_DEVICE_ID]}.json"
+ )
save_json(record_file, data)
def _load_device_config(self, device_id):
@@ -90,32 +101,46 @@ def _load_device_config(self, device_id):
def _save_account(self, account: dict):
os.makedirs(self.hass.config.path(STORAGE_PATH), exist_ok=True)
record_file = self.hass.config.path(f"{STORAGE_PATH}/account.json")
- account[CONF_PASSWORD] = format((int(account[CONF_ACCOUNT].encode("utf-8").hex(), 16) ^
- int(account[CONF_PASSWORD].encode("utf-8").hex(), 16)), 'x')
+ account[CONF_PASSWORD] = format(
+ (
+ int(account[CONF_ACCOUNT].encode("utf-8").hex(), 16)
+ ^ int(account[CONF_PASSWORD].encode("utf-8").hex(), 16)
+ ),
+ "x",
+ )
save_json(record_file, account)
def _load_account(self):
record_file = self.hass.config.path(f"{STORAGE_PATH}/account.json")
json_data = load_json(record_file, default={})
if CONF_ACCOUNT in json_data.keys():
- json_data[CONF_PASSWORD] = bytes.fromhex(format((
- int(json_data[CONF_PASSWORD], 16) ^
- int(json_data[CONF_ACCOUNT].encode("utf-8").hex(), 16)), 'X')
- ).decode('UTF-8')
+ json_data[CONF_PASSWORD] = bytes.fromhex(
+ format(
+ (
+ int(json_data[CONF_PASSWORD], 16)
+ ^ int(json_data[CONF_ACCOUNT].encode("utf-8").hex(), 16)
+ ),
+ "X",
+ )
+ ).decode("UTF-8")
return json_data
@staticmethod
def _check_storage_device(device: dict, storage_device: dict):
if storage_device.get(CONF_SUBTYPE) is None:
return False
- if (device.get(CONF_PROTOCOL) == 3 and
- (storage_device.get(CONF_TOKEN) is None or storage_device.get(CONF_KEY) is None)):
+ if device.get(CONF_PROTOCOL) == 3 and (
+ storage_device.get(CONF_TOKEN) is None
+ or storage_device.get(CONF_KEY) is None
+ ):
return False
return True
def _already_configured(self, device_id, ip_address):
for entry in self._async_current_entries():
- if device_id == entry.data.get(CONF_DEVICE_ID) or ip_address == entry.data.get(CONF_IP_ADDRESS):
+ if device_id == entry.data.get(
+ CONF_DEVICE_ID
+ ) or ip_address == entry.data.get(CONF_IP_ADDRESS):
return True
return False
@@ -130,10 +155,10 @@ async def async_step_user(self, user_input=None, error=None):
return await self.async_step_list()
return self.async_show_form(
step_id="user",
- data_schema=vol.Schema({
- vol.Required("action", default="discovery"): vol.In(ADD_WAY)
- }),
- errors={"base": error} if error else None
+ data_schema=vol.Schema(
+ {vol.Required("action", default="discovery"): vol.In(ADD_WAY)}
+ ),
+ errors={"base": error} if error else None,
)
async def async_step_login(self, user_input=None, error=None):
@@ -145,13 +170,13 @@ async def async_step_login(self, user_input=None, error=None):
session=self.session,
cloud_name=SERVERS[user_input[CONF_SERVER]],
account=user_input[CONF_ACCOUNT],
- password=user_input[CONF_PASSWORD]
+ password=user_input[CONF_PASSWORD],
)
if await self.cloud.login():
self.account = {
CONF_ACCOUNT: user_input[CONF_ACCOUNT],
CONF_PASSWORD: user_input[CONF_PASSWORD],
- CONF_SERVER: SERVERS[user_input[CONF_SERVER]]
+ CONF_SERVER: SERVERS[user_input[CONF_SERVER]],
}
self._save_account(self.account)
return await self.async_step_auto()
@@ -159,29 +184,35 @@ async def async_step_login(self, user_input=None, error=None):
return await self.async_step_login(error="login_failed")
return self.async_show_form(
step_id="login",
- data_schema=vol.Schema({
- vol.Required(CONF_ACCOUNT): str,
- vol.Required(CONF_PASSWORD): str,
- vol.Required(CONF_SERVER, default=1): vol.In(SERVERS)
- }),
- errors={"base": error} if error else None
+ data_schema=vol.Schema(
+ {
+ vol.Required(CONF_ACCOUNT): str,
+ vol.Required(CONF_PASSWORD): str,
+ vol.Required(CONF_SERVER, default=1): vol.In(SERVERS),
+ }
+ ),
+ errors={"base": error} if error else None,
)
async def async_step_list(self, user_input=None, error=None):
all_devices = discover()
if len(all_devices) > 0:
- table = "Appliance code|Type|IP address|SN|Supported\n:--:|:--:|:--:|:--:|:--:"
+ table = (
+ "Appliance code|Type|IP address|SN|Supported\n:--:|:--:|:--:|:--:|:--:"
+ )
for device_id, device in all_devices.items():
supported = device.get(CONF_TYPE) in self.supports.keys()
- table += f"\n{device_id}|{'%02X' % device.get(CONF_TYPE)}|{device.get(CONF_IP_ADDRESS)}|" \
- f"{device.get('sn')}|" \
- f"{'YES' if supported else 'NO'}"
+ table += (
+ f"\n{device_id}|{'%02X' % device.get(CONF_TYPE)}|{device.get(CONF_IP_ADDRESS)}|"
+ f"{device.get('sn')}|"
+ f"{'YES' if supported else 'NO'}"
+ )
else:
table = "Not found"
return self.async_show_form(
step_id="list",
description_placeholders={"table": table},
- errors={"base": error} if error else None
+ errors={"base": error} if error else None,
)
async def async_step_discovery(self, user_input=None, error=None):
@@ -194,18 +225,19 @@ async def async_step_discovery(self, user_input=None, error=None):
self.available_device = {}
for device_id, device in self.devices.items():
if not self._already_configured(device_id, device.get(CONF_IP_ADDRESS)):
- self.available_device[device_id] = \
+ self.available_device[device_id] = (
f"{device_id} ({self.supports.get(device.get(CONF_TYPE))})"
+ )
if len(self.available_device) > 0:
return await self.async_step_auto()
else:
return await self.async_step_discovery(error="no_devices")
return self.async_show_form(
step_id="discovery",
- data_schema=vol.Schema({
- vol.Required(CONF_IP_ADDRESS, default="auto"): str
- }),
- errors={"base": error} if error else None
+ data_schema=vol.Schema(
+ {vol.Required(CONF_IP_ADDRESS, default="auto"): str}
+ ),
+ errors={"base": error} if error else None,
)
async def async_step_auto(self, user_input=None, error=None):
@@ -224,9 +256,11 @@ async def async_step_auto(self, user_input=None, error=None):
CONF_NAME: storage_device.get(CONF_NAME),
CONF_SUBTYPE: storage_device.get(CONF_SUBTYPE),
CONF_TOKEN: storage_device.get(CONF_TOKEN),
- CONF_KEY: storage_device.get(CONF_KEY)
+ CONF_KEY: storage_device.get(CONF_KEY),
}
- _LOGGER.debug(f"Loaded configuration for device {device_id} from storage")
+ _LOGGER.debug(
+ f"Loaded configuration for device {device_id} from storage"
+ )
return await self.async_step_manually()
else:
if CONF_ACCOUNT not in self.account.keys():
@@ -237,8 +271,11 @@ async def async_step_auto(self, user_input=None, error=None):
self.session = async_create_clientsession(self.hass)
if self.cloud is None:
self.cloud = get_midea_cloud(
- self.account[CONF_SERVER], self.session, self.account[CONF_ACCOUNT],
- self.account[CONF_PASSWORD])
+ self.account[CONF_SERVER],
+ self.session,
+ self.account[CONF_ACCOUNT],
+ self.account[CONF_PASSWORD],
+ )
if not await self.cloud.login():
return await self.async_step_login()
self.found_device = {
@@ -254,12 +291,19 @@ async def async_step_auto(self, user_input=None, error=None):
self.found_device[CONF_SUBTYPE] = device_info.get("model_number")
if device.get(CONF_PROTOCOL) == 3:
if self.account[CONF_SERVER] == "美的美居":
- _LOGGER.debug("Try to get the Token and the Key use the preset MSmartHome account")
+ _LOGGER.debug(
+ "Try to get the Token and the Key use the preset MSmartHome account"
+ )
self.cloud = get_midea_cloud(
"MSmartHome",
self.session,
- bytes.fromhex(format((PRESET_ACCOUNT[0] ^ PRESET_ACCOUNT[1]), 'X')).decode('ASCII'),
- bytes.fromhex(format((PRESET_ACCOUNT[0] ^ PRESET_ACCOUNT[2]), 'X')).decode('ASCII'))
+ bytes.fromhex(
+ format((PRESET_ACCOUNT[0] ^ PRESET_ACCOUNT[1]), "X")
+ ).decode("ASCII"),
+ bytes.fromhex(
+ format((PRESET_ACCOUNT[0] ^ PRESET_ACCOUNT[2]), "X")
+ ).decode("ASCII"),
+ )
if not await self.cloud.login():
return await self.async_step_auto(error="preset_account")
keys = await self.cloud.get_keys(user_input[CONF_DEVICE])
@@ -275,7 +319,7 @@ async def async_step_auto(self, user_input=None, error=None):
protocol=3,
model=device.get(CONF_MODEL),
subtype=0,
- attributes={}
+ attributes={},
)
if dm.connect(refresh_status=False):
dm.close_socket()
@@ -288,11 +332,14 @@ async def async_step_auto(self, user_input=None, error=None):
return self.async_show_form(
step_id="auto",
- data_schema=vol.Schema({
- vol.Required(CONF_DEVICE, default=list(self.available_device.keys())[0]):
- vol.In(self.available_device),
- }),
- errors={"base": error} if error else None
+ data_schema=vol.Schema(
+ {
+ vol.Required(
+ CONF_DEVICE, default=list(self.available_device.keys())[0]
+ ): vol.In(self.available_device),
+ }
+ ),
+ errors={"base": error} if error else None,
)
async def async_step_manually(self, user_input=None, error=None):
@@ -305,14 +352,16 @@ async def async_step_manually(self, user_input=None, error=None):
CONF_PORT: user_input[CONF_PORT],
CONF_MODEL: user_input[CONF_MODEL],
CONF_TOKEN: user_input[CONF_TOKEN],
- CONF_KEY: user_input[CONF_KEY]
+ CONF_KEY: user_input[CONF_KEY],
}
try:
bytearray.fromhex(user_input[CONF_TOKEN])
bytearray.fromhex(user_input[CONF_KEY])
except ValueError:
return await self.async_step_manually(error="invalid_token")
- if user_input[CONF_PROTOCOL] == 3 and (len(user_input[CONF_TOKEN]) == 0 or len(user_input[CONF_KEY]) == 0):
+ if user_input[CONF_PROTOCOL] == 3 and (
+ len(user_input[CONF_TOKEN]) == 0 or len(user_input[CONF_KEY]) == 0
+ ):
return await self.async_step_manually(error="invalid_token")
dm = MiedaDevice(
name="",
@@ -325,7 +374,7 @@ async def async_step_manually(self, user_input=None, error=None):
protocol=user_input[CONF_PROTOCOL],
model=user_input[CONF_MODEL],
subtype=0,
- attributes={}
+ attributes={},
)
if dm.connect(refresh_status=False):
dm.close_socket()
@@ -340,61 +389,90 @@ async def async_step_manually(self, user_input=None, error=None):
CONF_SUBTYPE: user_input[CONF_SUBTYPE],
CONF_TOKEN: user_input[CONF_TOKEN],
CONF_KEY: user_input[CONF_KEY],
- }
+ }
self._save_device_config(data)
return self.async_create_entry(
- title=f"{user_input[CONF_NAME]}",
- data=data
+ title=f"{user_input[CONF_NAME]}", data=data
)
else:
return await self.async_step_manually(error="config_incorrect")
return self.async_show_form(
step_id="manually",
- data_schema=vol.Schema({
- vol.Required(
- CONF_NAME,
- default=(self.found_device.get(CONF_NAME)
- if self.found_device.get(CONF_NAME)
- else self.supports.get(self.found_device.get(CONF_TYPE)))
- ): str,
- vol.Required(
- CONF_DEVICE_ID,
- default=self.found_device.get(CONF_DEVICE_ID)
- ): int,
- vol.Required(
- CONF_TYPE,
- default=self.found_device.get(CONF_TYPE) if self.found_device.get(CONF_TYPE) else 0xac
- ): vol.In(self.supports),
- vol.Required(
- CONF_IP_ADDRESS,
- default=self.found_device.get(CONF_IP_ADDRESS)
- ): str,
- vol.Required(
- CONF_PORT,
- default=self.found_device.get(CONF_PORT) if self.found_device.get(CONF_PORT) else 6444
- ): int,
- vol.Required(
- CONF_PROTOCOL,
- default=self.found_device.get(CONF_PROTOCOL) if self.found_device.get(CONF_PROTOCOL) else 3
- ): vol.In(PROTOCOLS),
- vol.Required(
- CONF_MODEL,
- default=self.found_device.get(CONF_MODEL) if self.found_device.get(CONF_MODEL) else "Unknown"
- ): str,
- vol.Required(
- CONF_SUBTYPE,
- default=self.found_device.get(CONF_SUBTYPE) if self.found_device.get(CONF_SUBTYPE) else 0
- ): int,
- vol.Optional(
- CONF_TOKEN,
- default=self.found_device.get(CONF_TOKEN) if self.found_device.get(CONF_TOKEN) else ""
- ): str,
- vol.Optional(
- CONF_KEY,
- default=self.found_device.get(CONF_KEY) if self.found_device.get(CONF_KEY) else ""
- ): str,
- }),
- errors={"base": error} if error else None
+ data_schema=vol.Schema(
+ {
+ vol.Required(
+ CONF_NAME,
+ default=(
+ self.found_device.get(CONF_NAME)
+ if self.found_device.get(CONF_NAME)
+ else self.supports.get(self.found_device.get(CONF_TYPE))
+ ),
+ ): str,
+ vol.Required(
+ CONF_DEVICE_ID, default=self.found_device.get(CONF_DEVICE_ID)
+ ): int,
+ vol.Required(
+ CONF_TYPE,
+ default=(
+ self.found_device.get(CONF_TYPE)
+ if self.found_device.get(CONF_TYPE)
+ else 0xAC
+ ),
+ ): vol.In(self.supports),
+ vol.Required(
+ CONF_IP_ADDRESS, default=self.found_device.get(CONF_IP_ADDRESS)
+ ): str,
+ vol.Required(
+ CONF_PORT,
+ default=(
+ self.found_device.get(CONF_PORT)
+ if self.found_device.get(CONF_PORT)
+ else 6444
+ ),
+ ): int,
+ vol.Required(
+ CONF_PROTOCOL,
+ default=(
+ self.found_device.get(CONF_PROTOCOL)
+ if self.found_device.get(CONF_PROTOCOL)
+ else 3
+ ),
+ ): vol.In(PROTOCOLS),
+ vol.Required(
+ CONF_MODEL,
+ default=(
+ self.found_device.get(CONF_MODEL)
+ if self.found_device.get(CONF_MODEL)
+ else "Unknown"
+ ),
+ ): str,
+ vol.Required(
+ CONF_SUBTYPE,
+ default=(
+ self.found_device.get(CONF_SUBTYPE)
+ if self.found_device.get(CONF_SUBTYPE)
+ else 0
+ ),
+ ): int,
+ vol.Optional(
+ CONF_TOKEN,
+ default=(
+ self.found_device.get(CONF_TOKEN)
+ if self.found_device.get(CONF_TOKEN)
+ else ""
+ ),
+ ): str,
+ vol.Optional(
+ CONF_KEY,
+ default=(
+ self.found_device.get(CONF_KEY)
+ if self.found_device.get(CONF_KEY)
+ else ""
+ ),
+ ): str,
+ }
+ ),
+ errors={"base": error} if error else None,
)
@staticmethod
@@ -408,7 +486,7 @@ def __init__(self, config_entry: config_entries.ConfigEntry):
self._config_entry = config_entry
self._device_type = config_entry.data.get(CONF_TYPE)
if self._device_type is None:
- self._device_type = 0xac
+ self._device_type = 0xAC
if CONF_SENSORS in self._config_entry.options:
for key in self._config_entry.options[CONF_SENSORS]:
if key not in MIDEA_DEVICES[self._device_type]["entities"]:
@@ -425,66 +503,61 @@ async def async_step_init(self, user_input=None):
return self.async_create_entry(title="", data=user_input)
sensors = {}
switches = {}
- for attribute, attribute_config in MIDEA_DEVICES.get(self._device_type).get("entities").items():
- attribute_name = attribute if isinstance(attribute, str) else attribute.value
+ for attribute, attribute_config in (
+ MIDEA_DEVICES.get(self._device_type).get("entities").items()
+ ):
+ attribute_name = (
+ attribute if isinstance(attribute, str) else attribute.value
+ )
if attribute_config.get("type") in EXTRA_SENSOR:
sensors[attribute_name] = attribute_config.get("name")
- elif attribute_config.get("type") in EXTRA_CONTROL and not attribute_config.get("default"):
+ elif attribute_config.get(
+ "type"
+ ) in EXTRA_CONTROL and not attribute_config.get("default"):
switches[attribute_name] = attribute_config.get("name")
- ip_address = self._config_entry.options.get(
- CONF_IP_ADDRESS, None
- )
+ ip_address = self._config_entry.options.get(CONF_IP_ADDRESS, None)
if ip_address is None:
- ip_address = self._config_entry.data.get(
- CONF_IP_ADDRESS, None
- )
- refresh_interval = self._config_entry.options.get(
- CONF_REFRESH_INTERVAL, 30
+ ip_address = self._config_entry.data.get(CONF_IP_ADDRESS, None)
+ refresh_interval = self._config_entry.options.get(CONF_REFRESH_INTERVAL, 30)
+ extra_sensors = list(
+ set(sensors.keys()) & set(self._config_entry.options.get(CONF_SENSORS, []))
)
- extra_sensors = list(set(sensors.keys()) & set(self._config_entry.options.get(
- CONF_SENSORS, []
- )))
- extra_switches = list(set(switches.keys()) & set(self._config_entry.options.get(
- CONF_SWITCHES, []
- )))
- customize = self._config_entry.options.get(
- CONF_CUSTOMIZE, ""
+ extra_switches = list(
+ set(switches.keys())
+ & set(self._config_entry.options.get(CONF_SWITCHES, []))
+ )
+ customize = self._config_entry.options.get(CONF_CUSTOMIZE, "")
+ data_schema = vol.Schema(
+ {
+ vol.Required(CONF_IP_ADDRESS, default=ip_address): str,
+ vol.Required(CONF_REFRESH_INTERVAL, default=refresh_interval): int,
+ }
)
- data_schema = vol.Schema({
- vol.Required(
- CONF_IP_ADDRESS,
- default=ip_address
- ): str,
- vol.Required(
- CONF_REFRESH_INTERVAL,
- default=refresh_interval
- ): int
- })
if len(sensors) > 0:
- data_schema = data_schema.extend({
- vol.Required(
- CONF_SENSORS,
- default=extra_sensors,
- ):
- cv.multi_select(sensors)
- })
+ data_schema = data_schema.extend(
+ {
+ vol.Required(
+ CONF_SENSORS,
+ default=extra_sensors,
+ ): cv.multi_select(sensors)
+ }
+ )
if len(switches) > 0:
- data_schema = data_schema.extend({
- vol.Required(
- CONF_SWITCHES,
- default=extra_switches,
- ):
- cv.multi_select(switches)
- })
- data_schema = data_schema.extend({
- vol.Optional(
- CONF_CUSTOMIZE,
- default=customize,
- ):
- str
- })
-
- return self.async_show_form(
- step_id="init",
- data_schema=data_schema
+ data_schema = data_schema.extend(
+ {
+ vol.Required(
+ CONF_SWITCHES,
+ default=extra_switches,
+ ): cv.multi_select(switches)
+ }
+ )
+ data_schema = data_schema.extend(
+ {
+ vol.Optional(
+ CONF_CUSTOMIZE,
+ default=customize,
+ ): str
+ }
)
+
+ return self.async_show_form(step_id="init", data_schema=data_schema)
diff --git a/custom_components/midea_ac_lan/const.py b/custom_components/midea_ac_lan/const.py
index dc5439db..d6d89474 100644
--- a/custom_components/midea_ac_lan/const.py
+++ b/custom_components/midea_ac_lan/const.py
@@ -1,4 +1,5 @@
from homeassistant.const import Platform
+
DOMAIN = "midea_ac_lan"
COMPONENT = "component"
DEVICES = "devices"
@@ -10,6 +11,11 @@
CONF_REFRESH_INTERVAL = "refresh_interval"
EXTRA_SENSOR = [Platform.SENSOR, Platform.BINARY_SENSOR]
EXTRA_SWITCH = [Platform.SWITCH, Platform.LOCK, Platform.SELECT, Platform.NUMBER]
-EXTRA_CONTROL = [Platform.CLIMATE, Platform.WATER_HEATER, Platform.FAN, Platform.HUMIDIFIER, Platform.LIGHT] + \
- EXTRA_SWITCH
+EXTRA_CONTROL = [
+ Platform.CLIMATE,
+ Platform.WATER_HEATER,
+ Platform.FAN,
+ Platform.HUMIDIFIER,
+ Platform.LIGHT,
+] + EXTRA_SWITCH
ALL_PLATFORM = EXTRA_SENSOR + EXTRA_CONTROL
diff --git a/custom_components/midea_ac_lan/fan.py b/custom_components/midea_ac_lan/fan.py
index bc49c8f4..7ddd8614 100644
--- a/custom_components/midea_ac_lan/fan.py
+++ b/custom_components/midea_ac_lan/fan.py
@@ -1,36 +1,34 @@
+import logging
from typing import Any
from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.const import (
- Platform,
CONF_DEVICE_ID,
CONF_SWITCHES,
+ STATE_OFF,
STATE_ON,
- STATE_OFF
-)
-from .const import (
- DOMAIN,
- DEVICES,
+ Platform,
)
+
+from .const import DEVICES, DOMAIN
from .midea.devices.ac.device import DeviceAttributes as ACAttributes
from .midea.devices.ce.device import DeviceAttributes as CEAttributes
from .midea.devices.x40.device import DeviceAttributes as X40Attributes
from .midea_devices import MIDEA_DEVICES
from .midea_entity import MideaEntity
-import logging
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
devs = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
- if config["type"] == Platform.FAN and (config.get("default") or entity_key in extra_switches):
+ if config["type"] == Platform.FAN and (
+ config.get("default") or entity_key in extra_switches
+ ):
if device.device_type == 0xFA:
devs.append(MideaFAFan(device, entity_key))
elif device.device_type == 0xB6:
@@ -62,7 +60,9 @@ def turn_on(
@property
def preset_modes(self):
- return self._device.preset_modes if hasattr(self._device, "preset_modes") else None
+ return (
+ self._device.preset_modes if hasattr(self._device, "preset_modes") else None
+ )
@property
def is_on(self) -> bool:
@@ -111,27 +111,37 @@ def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
- _LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
+ _LOGGER.debug(
+ f"Entity {self.entity_id} update_state {repr(e)}, status = {status}"
+ )
class MideaFAFan(MideaFan):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.OSCILLATE | FanEntityFeature.PRESET_MODE
+ self._attr_supported_features = (
+ FanEntityFeature.SET_SPEED
+ | FanEntityFeature.OSCILLATE
+ | FanEntityFeature.PRESET_MODE
+ )
self._attr_speed_count = self._device.speed_count
class MideaB6Fan(MideaFan):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
+ self._attr_supported_features = (
+ FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
+ )
self._attr_speed_count = self._device.speed_count
class MideaACFreshAirFan(MideaFan):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
+ self._attr_supported_features = (
+ FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
+ )
self._attr_speed_count = 100
@property
@@ -140,7 +150,11 @@ def preset_modes(self):
@property
def state(self):
- return STATE_ON if self._device.get_attribute(ACAttributes.fresh_air_power) else STATE_OFF
+ return (
+ STATE_ON
+ if self._device.get_attribute(ACAttributes.fresh_air_power)
+ else STATE_OFF
+ )
@property
def is_on(self) -> bool:
@@ -162,7 +176,9 @@ def toggle(self):
def set_percentage(self, percentage: int):
fan_speed = int(percentage / self.percentage_step + 0.5)
- self._device.set_attribute(attr=ACAttributes.fresh_air_fan_speed, value=fan_speed)
+ self._device.set_attribute(
+ attr=ACAttributes.fresh_air_fan_speed, value=fan_speed
+ )
def set_preset_mode(self, preset_mode: str):
self._device.set_attribute(attr=ACAttributes.fresh_air_mode, value=preset_mode)
@@ -175,7 +191,9 @@ def preset_mode(self):
class MideaCEFan(MideaFan):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
+ self._attr_supported_features = (
+ FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
+ )
self._attr_speed_count = self._device.speed_count
def turn_on(self, percentage, preset_mode, **kwargs):
@@ -188,12 +206,18 @@ async def async_set_percentage(self, percentage: int):
class Midea40Fan(MideaFan):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
- self._attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.OSCILLATE
+ self._attr_supported_features = (
+ FanEntityFeature.SET_SPEED | FanEntityFeature.OSCILLATE
+ )
self._attr_speed_count = 2
@property
def state(self):
- return STATE_ON if self._device.get_attribute(attr=X40Attributes.fan_speed) > 0 else STATE_OFF
+ return (
+ STATE_ON
+ if self._device.get_attribute(attr=X40Attributes.fan_speed) > 0
+ else STATE_OFF
+ )
def turn_on(self, percentage, preset_mode, **kwargs):
self._device.set_attribute(attr=X40Attributes.fan_speed, value=1)
diff --git a/custom_components/midea_ac_lan/humidifier.py b/custom_components/midea_ac_lan/humidifier.py
index 35ec5a0a..1027b585 100644
--- a/custom_components/midea_ac_lan/humidifier.py
+++ b/custom_components/midea_ac_lan/humidifier.py
@@ -1,33 +1,28 @@
+import logging
+
from homeassistant.components.humidifier import (
HumidifierDeviceClass,
HumidifierEntity,
HumidifierEntityFeature,
)
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SWITCHES,
-)
-from .const import (
- DOMAIN,
- DEVICES,
-)
+from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
+
+from .const import DEVICES, DOMAIN
from .midea_devices import MIDEA_DEVICES
from .midea_entity import MideaEntity
-import logging
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
devs = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
- if config["type"] == Platform.HUMIDIFIER and (config.get("default") or entity_key in extra_switches):
+ if config["type"] == Platform.HUMIDIFIER and (
+ config.get("default") or entity_key in extra_switches
+ ):
if device.device_type == 0xA1:
devs.append(MideaA1Humidifier(device, entity_key))
if device.device_type == 0xFD:
@@ -79,7 +74,9 @@ def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
- _LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
+ _LOGGER.debug(
+ f"Entity {self.entity_id} update_state {repr(e)}, status = {status}"
+ )
class MideaA1Humidifier(MideaHumidifier):
diff --git a/custom_components/midea_ac_lan/light.py b/custom_components/midea_ac_lan/light.py
index 5834574d..91747b87 100644
--- a/custom_components/midea_ac_lan/light.py
+++ b/custom_components/midea_ac_lan/light.py
@@ -5,25 +5,19 @@
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_EFFECT,
- LightEntity,
- LightEntityFeature,
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR,
SUPPORT_COLOR_TEMP,
SUPPORT_EFFECT,
+ LightEntity,
+ LightEntityFeature,
)
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SWITCHES,
-)
-from .const import (
- DOMAIN,
- DEVICES
-)
+from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
+
+from .const import DEVICES, DOMAIN
from .midea.devices.x13.device import DeviceAttributes as X13Attributes
-from .midea_entity import MideaEntity
from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
_LOGGER = logging.getLogger(__name__)
@@ -31,12 +25,12 @@
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
devs = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
- if config["type"] == Platform.LIGHT and (config.get("default") or entity_key in extra_switches):
+ if config["type"] == Platform.LIGHT and (
+ config.get("default") or entity_key in extra_switches
+ ):
devs.append(MideaLight(device, entity_key))
async_add_entities(devs)
@@ -110,7 +104,9 @@ def turn_on(self, **kwargs: Any):
if key == ATTR_BRIGHTNESS:
self._device.set_attribute(attr=X13Attributes.brightness, value=value)
if key == ATTR_COLOR_TEMP:
- self._device.set_attribute(attr=X13Attributes.color_temperature, value=round(1000000 / value))
+ self._device.set_attribute(
+ attr=X13Attributes.color_temperature, value=round(1000000 / value)
+ )
if key == ATTR_EFFECT:
self._device.set_attribute(attr=X13Attributes.effect, value=value)
@@ -121,4 +117,6 @@ def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
- _LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
+ _LOGGER.debug(
+ f"Entity {self.entity_id} update_state {repr(e)}, status = {status}"
+ )
diff --git a/custom_components/midea_ac_lan/lock.py b/custom_components/midea_ac_lan/lock.py
index df43e084..f62eeb54 100644
--- a/custom_components/midea_ac_lan/lock.py
+++ b/custom_components/midea_ac_lan/lock.py
@@ -1,23 +1,15 @@
-from .midea_entity import MideaEntity
-from .midea_devices import MIDEA_DEVICES
from homeassistant.components.lock import LockEntity
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SWITCHES
-)
-from .const import (
- DOMAIN,
- DEVICES,
-)
+from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
+
+from .const import DEVICES, DOMAIN
+from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
locks = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.LOCK and entity_key in extra_switches:
diff --git a/custom_components/midea_ac_lan/midea/backports/myenum.py b/custom_components/midea_ac_lan/midea/backports/myenum.py
index e3ef7d54..c4de8762 100644
--- a/custom_components/midea_ac_lan/midea/backports/myenum.py
+++ b/custom_components/midea_ac_lan/midea/backports/myenum.py
@@ -1,4 +1,5 @@
"""Enum backports from standard lib."""
+
from __future__ import annotations
from enum import Enum
diff --git a/custom_components/midea_ac_lan/midea/core/cloud.py b/custom_components/midea_ac_lan/midea/core/cloud.py
index 286ea204..f4eb2eb0 100644
--- a/custom_components/midea_ac_lan/midea/core/cloud.py
+++ b/custom_components/midea_ac_lan/midea/core/cloud.py
@@ -1,12 +1,19 @@
-import logging
-import time
+import base64
import datetime
import json
-import base64
+import logging
+import time
+from secrets import token_hex
from threading import Lock
+
from aiohttp import ClientSession
-from secrets import token_hex
-from .security import CloudSecurity, MeijuCloudSecurity, MSmartCloudSecurity, MideaAirSecurity
+
+from .security import (
+ CloudSecurity,
+ MeijuCloudSecurity,
+ MideaAirSecurity,
+ MSmartCloudSecurity,
+)
_LOGGER = logging.getLogger(__name__)
@@ -16,16 +23,22 @@
"app_id": "900",
"app_key": "46579c15",
"login_key": "ad0ee21d48a64bf49f4fb583ab76e799",
- "iot_key": bytes.fromhex(format(9795516279659324117647275084689641883661667, 'x')).decode(),
- "hmac_key": bytes.fromhex(format(117390035944627627450677220413733956185864939010425, 'x')).decode(),
+ "iot_key": bytes.fromhex(
+ format(9795516279659324117647275084689641883661667, "x")
+ ).decode(),
+ "hmac_key": bytes.fromhex(
+ format(117390035944627627450677220413733956185864939010425, "x")
+ ).decode(),
"api_url": "https://mp-prod.smartmidea.net/mas/v5/app/proxy?alias=",
},
"MSmartHome": {
"class_name": "MSmartHomeCloud",
"app_id": "1010",
"app_key": "ac21b9f9cbfe4ca5a88562ef25e2b768",
- "iot_key": bytes.fromhex(format(7882822598523843940, 'x')).decode(),
- "hmac_key": bytes.fromhex(format(117390035944627627450677220413733956185864939010425, 'x')).decode(),
+ "iot_key": bytes.fromhex(format(7882822598523843940, "x")).decode(),
+ "hmac_key": bytes.fromhex(
+ format(117390035944627627450677220413733956185864939010425, "x")
+ ).decode(),
"api_url": "https://mp-prod.appsmb.com/mas/v5/app/proxy?alias=",
},
"Midea Air": {
@@ -45,28 +58,28 @@
"app_id": "1005",
"app_key": "434a209a5ce141c3b726de067835d7f0",
"api_url": "https://mapp.appsmb.com",
- }
+ },
}
default_keys = {
99: {
"token": "ee755a84a115703768bcc7c6c13d3d629aa416f1e2fd798beb9f78cbb1381d09"
- "1cc245d7b063aad2a900e5b498fbd936c811f5d504b2e656d4f33b3bbc6d1da3",
- "key": "ed37bd31558a4b039aaf4e7a7a59aa7a75fd9101682045f69baf45d28380ae5c"
+ "1cc245d7b063aad2a900e5b498fbd936c811f5d504b2e656d4f33b3bbc6d1da3",
+ "key": "ed37bd31558a4b039aaf4e7a7a59aa7a75fd9101682045f69baf45d28380ae5c",
}
}
class MideaCloud:
def __init__(
- self,
- session: ClientSession,
- security: CloudSecurity,
- app_id: str,
- app_key: str,
- account: str,
- password: str,
- api_url: str
+ self,
+ session: ClientSession,
+ security: CloudSecurity,
+ app_id: str,
+ app_key: str,
+ account: str,
+ password: str,
+ api_url: str,
):
self._device_id = CloudSecurity.get_deviceid(account)
self._session = session
@@ -87,38 +100,36 @@ def _make_general_data(self):
async def _api_request(self, endpoint: str, data: dict, header=None) -> dict | None:
header = header or {}
if not data.get("reqId"):
- data.update({
- "reqId": token_hex(16)
- })
+ data.update({"reqId": token_hex(16)})
if not data.get("stamp"):
- data.update({
- "stamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S")
- })
+ data.update({"stamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S")})
random = str(int(time.time()))
url = self._api_url + endpoint
dump_data = json.dumps(data)
sign = self._security.sign("", dump_data, random)
- header.update({
- "content-type": "application/json; charset=utf-8",
- "secretVersion": "1",
- "sign": sign,
- "random": random,
- })
+ header.update(
+ {
+ "content-type": "application/json; charset=utf-8",
+ "secretVersion": "1",
+ "sign": sign,
+ "random": random,
+ }
+ )
if self._uid is not None:
- header.update({
- "uid": self._uid
- })
+ header.update({"uid": self._uid})
if self._access_token is not None:
- header.update({
- "accessToken": self._access_token
- })
+ header.update({"accessToken": self._access_token})
response: dict = {"code": -1}
for i in range(0, 3):
try:
with self._api_lock:
- r = await self._session.request("POST", url, headers=header, data=dump_data, timeout=10)
+ r = await self._session.request(
+ "POST", url, headers=header, data=dump_data, timeout=10
+ )
raw = await r.read()
- _LOGGER.debug(f"Midea cloud API url: {url}, data: {data}, response: {raw}")
+ _LOGGER.debug(
+ f"Midea cloud API url: {url}, data: {data}, response: {raw}"
+ )
response = json.loads(raw)
break
except Exception as e:
@@ -129,12 +140,9 @@ async def _api_request(self, endpoint: str, data: dict, header=None) -> dict | N
async def _get_login_id(self) -> str | None:
data = self._make_general_data()
- data.update({
- "loginAccount": f"{self._account}"
- })
+ data.update({"loginAccount": f"{self._account}"})
if response := await self._api_request(
- endpoint="/v1/user/login/id/get",
- data=data
+ endpoint="/v1/user/login/id/get", data=data
):
return response.get("loginId")
return None
@@ -147,19 +155,16 @@ async def get_keys(self, appliance_id: int):
for method in [1, 2]:
udp_id = self._security.get_udp_id(appliance_id, method)
data = self._make_general_data()
- data.update({
- "udpid": udp_id
- })
+ data.update({"udpid": udp_id})
response = await self._api_request(
- endpoint="/v1/iot/secure/getToken",
- data=data
+ endpoint="/v1/iot/secure/getToken", data=data
)
if response and "tokenlist" in response:
for token in response["tokenlist"]:
if token["udpId"] == udp_id:
result[method] = {
"token": token["token"].lower(),
- "key": token["key"].lower()
+ "key": token["key"].lower(),
}
result.update(default_keys)
return result
@@ -177,22 +182,23 @@ async def get_device_info(self, device_id: int):
return None
async def download_lua(
- self, path: str,
- device_type: int,
- sn: str,
- model_number: str | None,
- manufacturer_code: str = "0000",
+ self,
+ path: str,
+ device_type: int,
+ sn: str,
+ model_number: str | None,
+ manufacturer_code: str = "0000",
):
raise NotImplementedError()
class MeijuCloud(MideaCloud):
def __init__(
- self,
- cloud_name: str,
- session: ClientSession,
- account: str,
- password: str,
+ self,
+ cloud_name: str,
+ session: ClientSession,
+ account: str,
+ password: str,
):
super().__init__(
session=session,
@@ -205,7 +211,7 @@ def __init__(
app_key=clouds[cloud_name]["app_key"],
account=account,
password=password,
- api_url=clouds[cloud_name]["api_url"]
+ api_url=clouds[cloud_name]["api_url"],
)
async def login(self) -> bool:
@@ -216,30 +222,31 @@ async def login(self) -> bool:
"iotData": {
"clientType": 1,
"deviceId": self._device_id,
- "iampwd": self._security.encrypt_iam_password(self._login_id, self._password),
+ "iampwd": self._security.encrypt_iam_password(
+ self._login_id, self._password
+ ),
"iotAppId": self._app_id,
"loginAccount": self._account,
- "password": self._security.encrypt_password(self._login_id, self._password),
+ "password": self._security.encrypt_password(
+ self._login_id, self._password
+ ),
"reqId": token_hex(16),
- "stamp": stamp
+ "stamp": stamp,
},
"data": {
"appKey": self._app_key,
"deviceId": self._device_id,
- "platform": 2
+ "platform": 2,
},
"timestamp": stamp,
- "stamp": stamp
+ "stamp": stamp,
}
if response := await self._api_request(
- endpoint="/mj/user/login",
- data=data
+ endpoint="/mj/user/login", data=data
):
self._access_token = response["mdata"]["accessToken"]
self._security.set_aes_keys(
- self._security.aes_decrypt_with_fixed_key(
- response["key"]
- ), None
+ self._security.aes_decrypt_with_fixed_key(response["key"]), None
)
return True
@@ -247,24 +254,18 @@ async def login(self) -> bool:
async def list_home(self):
if response := await self._api_request(
- endpoint="/v1/homegroup/list/get",
- data={}
+ endpoint="/v1/homegroup/list/get", data={}
):
homes = {}
for home in response["homeList"]:
- homes.update({
- int(home["homegroupId"]): home["name"]
- })
+ homes.update({int(home["homegroupId"]): home["name"]})
return homes
return None
async def list_appliances(self, home_id) -> dict | None:
- data = {
- "homegroupId": home_id
- }
+ data = {"homegroupId": home_id}
if response := await self._api_request(
- endpoint="/v1/appliance/home/list/get",
- data=data
+ endpoint="/v1/appliance/home/list/get", data=data
):
appliances = {}
for home in response.get("homeList") or []:
@@ -277,28 +278,37 @@ async def list_appliances(self, home_id) -> dict | None:
device_info = {
"name": appliance.get("name"),
"type": int(appliance.get("type"), 16),
- "sn": self._security.aes_decrypt(appliance.get("sn")) if appliance.get("sn") else "",
+ "sn": (
+ self._security.aes_decrypt(appliance.get("sn"))
+ if appliance.get("sn")
+ else ""
+ ),
"sn8": appliance.get("sn8", "00000000"),
"model_number": model_number,
- "manufacturer_code": appliance.get("enterpriseCode", "0000"),
+ "manufacturer_code": appliance.get(
+ "enterpriseCode", "0000"
+ ),
"model": appliance.get("productModel"),
"online": appliance.get("onlineStatus") == "1",
}
- if device_info.get("sn8") is None or len(device_info.get("sn8")) == 0:
+ if (
+ device_info.get("sn8") is None
+ or len(device_info.get("sn8")) == 0
+ ):
device_info["sn8"] = "00000000"
- if device_info.get("model") is None or len(device_info.get("model")) == 0:
+ if (
+ device_info.get("model") is None
+ or len(device_info.get("model")) == 0
+ ):
device_info["model"] = device_info["sn8"]
appliances[int(appliance["applianceCode"])] = device_info
return appliances
return None
async def get_device_info(self, device_id: int):
- data = {
- "applianceCode": device_id
- }
+ data = {"applianceCode": device_id}
if response := await self._api_request(
- endpoint="/v1/appliance/info/get",
- data=data
+ endpoint="/v1/appliance/info/get", data=data
):
try:
model_number = int(response.get("modelNumber", 0))
@@ -307,7 +317,11 @@ async def get_device_info(self, device_id: int):
device_info = {
"name": response.get("name"),
"type": int(response.get("type"), 16),
- "sn": self._security.aes_decrypt(response.get("sn")) if response.get("sn") else "",
+ "sn": (
+ self._security.aes_decrypt(response.get("sn"))
+ if response.get("sn")
+ else ""
+ ),
"sn8": response.get("sn8", "00000000"),
"model_number": model_number,
"manufacturer_code": response.get("enterpriseCode", "0000"),
@@ -322,30 +336,32 @@ async def get_device_info(self, device_id: int):
return None
async def download_lua(
- self, path: str,
- device_type: int,
- sn: str,
- model_number: str | None,
- manufacturer_code: str = "0000",
+ self,
+ path: str,
+ device_type: int,
+ sn: str,
+ model_number: str | None,
+ manufacturer_code: str = "0000",
):
data = {
"applianceSn": sn,
"applianceType": "0x%02X" % device_type,
"applianceMFCode": manufacturer_code,
- 'version': "0",
- "iotAppId": self._app_id
+ "version": "0",
+ "iotAppId": self._app_id,
}
fnm = None
if response := await self._api_request(
- endpoint="/v1/appliance/protocol/lua/luaGet",
- data=data
+ endpoint="/v1/appliance/protocol/lua/luaGet", data=data
):
res = await self._session.get(response["url"])
if res.status == 200:
lua = await res.text()
if lua:
- stream = ('local bit = require "bit"\n' +
- self._security.aes_decrypt_with_fixed_key(lua))
+ stream = (
+ 'local bit = require "bit"\n'
+ + self._security.aes_decrypt_with_fixed_key(lua)
+ )
stream = stream.replace("\r\n", "\n")
fnm = f"{path}/{response['fileName']}"
with open(fnm, "w") as fp:
@@ -355,11 +371,11 @@ async def download_lua(
class MSmartHomeCloud(MideaCloud):
def __init__(
- self,
- cloud_name: str,
- session: ClientSession,
- account: str,
- password: str,
+ self,
+ cloud_name: str,
+ session: ClientSession,
+ account: str,
+ password: str,
):
super().__init__(
session=session,
@@ -372,7 +388,7 @@ def __init__(
app_key=clouds[cloud_name]["app_key"],
account=account,
password=password,
- api_url=clouds[cloud_name]["api_url"]
+ api_url=clouds[cloud_name]["api_url"],
)
self._auth_base = base64.b64encode(
f"{self._app_key}:{clouds['MSmartHome']['iot_key']}".encode("ascii")
@@ -389,27 +405,22 @@ def _make_general_data(self):
"reqId": token_hex(16),
"uid": self._uid,
"clientType": "1",
- "appId": self._app_id
+ "appId": self._app_id,
}
async def _api_request(self, endpoint: str, data: dict, header=None) -> dict | None:
header = header or {}
- header.update({
- "x-recipe-app": self._app_id,
- "authorization": f"Basic {self._auth_base}"
- })
+ header.update(
+ {"x-recipe-app": self._app_id, "authorization": f"Basic {self._auth_base}"}
+ )
return await super()._api_request(endpoint, data, header)
async def _re_route(self):
data = self._make_general_data()
- data.update({
- "userType": "0",
- "userName": f"{self._account}"
- })
+ data.update({"userType": "0", "userName": f"{self._account}"})
if response := await self._api_request(
- endpoint="/v1/multicloud/platform/user/route",
- data=data
+ endpoint="/v1/multicloud/platform/user/route", data=data
):
if api_url := response.get("masUrl"):
self._api_url = api_url
@@ -421,36 +432,42 @@ async def login(self) -> bool:
iot_data = self._make_general_data()
iot_data.pop("uid")
stamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
- iot_data.update({
- "iampwd": self._security.encrypt_iam_password(self._login_id, self._password),
- "loginAccount": self._account,
- "password": self._security.encrypt_password(self._login_id, self._password),
- "stamp": stamp
- })
+ iot_data.update(
+ {
+ "iampwd": self._security.encrypt_iam_password(
+ self._login_id, self._password
+ ),
+ "loginAccount": self._account,
+ "password": self._security.encrypt_password(
+ self._login_id, self._password
+ ),
+ "stamp": stamp,
+ }
+ )
data = {
"iotData": iot_data,
"data": {
"appKey": self._app_key,
"deviceId": self._device_id,
- "platform": "2"
+ "platform": "2",
},
- "stamp": stamp
+ "stamp": stamp,
}
if response := await self._api_request(
- endpoint="/mj/user/login",
- data=data
+ endpoint="/mj/user/login", data=data
):
self._uid = response["uid"]
self._access_token = response["mdata"]["accessToken"]
- self._security.set_aes_keys(response["accessToken"], response["randomData"])
+ self._security.set_aes_keys(
+ response["accessToken"], response["randomData"]
+ )
return True
return False
async def list_appliances(self, home_id) -> dict | None:
data = self._make_general_data()
if response := await self._api_request(
- endpoint="/v1/appliance/user/list/get",
- data=data
+ endpoint="/v1/appliance/user/list/get", data=data
):
appliances = {}
for appliance in response["list"]:
@@ -461,21 +478,28 @@ async def list_appliances(self, home_id) -> dict | None:
device_info = {
"name": appliance.get("name"),
"type": int(appliance.get("type"), 16),
- "sn": self._security.aes_decrypt(appliance.get("sn")) if appliance.get("sn") else "",
+ "sn": (
+ self._security.aes_decrypt(appliance.get("sn"))
+ if appliance.get("sn")
+ else ""
+ ),
"sn8": "",
"model_number": model_number,
"manufacturer_code": appliance.get("enterpriseCode", "0000"),
"model": "",
"online": appliance.get("onlineStatus") == "1",
}
- device_info["sn8"] = device_info.get("sn")[9:17] if len(device_info["sn"]) > 17 else ""
+ device_info["sn8"] = (
+ device_info.get("sn")[9:17] if len(device_info["sn"]) > 17 else ""
+ )
device_info["model"] = device_info.get("sn8")
appliances[int(appliance["id"])] = device_info
return appliances
return None
async def download_lua(
- self, path: str,
+ self,
+ path: str,
device_type: int,
sn: str,
model_number: str | None,
@@ -490,21 +514,24 @@ async def download_lua(
"applianceMFCode": manufacturer_code,
"applianceType": "0x%02X" % device_type,
"modelNumber": model_number,
- "applianceSn": self._security.aes_encrypt_with_fixed_key(sn.encode("ascii")).hex(),
+ "applianceSn": self._security.aes_encrypt_with_fixed_key(
+ sn.encode("ascii")
+ ).hex(),
"version": "0",
- "encryptedType ": "2"
+ "encryptedType ": "2",
}
fnm = None
if response := await self._api_request(
- endpoint="/v2/luaEncryption/luaGet",
- data=data
+ endpoint="/v2/luaEncryption/luaGet", data=data
):
res = await self._session.get(response["url"])
if res.status == 200:
lua = await res.text()
if lua:
- stream = ('local bit = require "bit"\n' +
- self._security.aes_decrypt_with_fixed_key(lua))
+ stream = (
+ 'local bit = require "bit"\n'
+ + self._security.aes_decrypt_with_fixed_key(lua)
+ )
stream = stream.replace("\r\n", "\n")
fnm = f"{path}/{response['fileName']}"
with open(fnm, "w") as fp:
@@ -514,22 +541,20 @@ async def download_lua(
class MideaAirCloud(MideaCloud):
def __init__(
- self,
- cloud_name: str,
- session: ClientSession,
- account: str,
- password: str,
+ self,
+ cloud_name: str,
+ session: ClientSession,
+ account: str,
+ password: str,
):
super().__init__(
session=session,
- security=MideaAirSecurity(
- login_key=clouds[cloud_name]["app_key"]
- ),
+ security=MideaAirSecurity(login_key=clouds[cloud_name]["app_key"]),
app_id=clouds[cloud_name]["app_id"],
app_key=clouds[cloud_name]["app_key"],
account=account,
password=password,
- api_url=clouds[cloud_name]["api_url"]
+ api_url=clouds[cloud_name]["api_url"],
)
self._session_id = None
@@ -541,45 +566,37 @@ def _make_general_data(self):
"deviceId": self._device_id,
"reqId": token_hex(16),
"clientType": "1",
- "appId": self._app_id
+ "appId": self._app_id,
}
if self._session_id is not None:
- data.update({
- "sessionId": self._session_id
- })
+ data.update({"sessionId": self._session_id})
return data
async def _api_request(self, endpoint: str, data: dict, header=None) -> dict | None:
header = header or {}
if not data.get("reqId"):
- data.update({
- "reqId": token_hex(16)
- })
+ data.update({"reqId": token_hex(16)})
if not data.get("stamp"):
- data.update({
- "stamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S")
- })
+ data.update({"stamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S")})
url = self._api_url + endpoint
sign = self._security.sign(url, data, "")
- data.update({
- "sign": sign
- })
+ data.update({"sign": sign})
if self._uid is not None:
- header.update({
- "uid": self._uid
- })
+ header.update({"uid": self._uid})
if self._access_token is not None:
- header.update({
- "accessToken": self._access_token
- })
+ header.update({"accessToken": self._access_token})
response: dict = {"code": -1}
for i in range(0, 3):
try:
with self._api_lock:
- r = await self._session.request("POST", url, headers=header, data=data, timeout=10)
+ r = await self._session.request(
+ "POST", url, headers=header, data=data, timeout=10
+ )
raw = await r.read()
- _LOGGER.debug(f"Midea cloud API url: {url}, data: {data}, response: {raw}")
+ _LOGGER.debug(
+ f"Midea cloud API url: {url}, data: {data}, response: {raw}"
+ )
response = json.loads(raw)
break
except Exception as e:
@@ -592,13 +609,16 @@ async def login(self) -> bool:
if login_id := await self._get_login_id():
self._login_id = login_id
data = self._make_general_data()
- data.update({
- "loginAccount": self._account,
- "password": self._security.encrypt_password(self._login_id, self._password),
- })
+ data.update(
+ {
+ "loginAccount": self._account,
+ "password": self._security.encrypt_password(
+ self._login_id, self._password
+ ),
+ }
+ )
if response := await self._api_request(
- endpoint="/v1/user/login",
- data=data
+ endpoint="/v1/user/login", data=data
):
self._access_token = response["accessToken"]
self._uid = response["userId"]
@@ -609,8 +629,7 @@ async def login(self) -> bool:
async def list_appliances(self, home_id) -> dict | None:
data = self._make_general_data()
if response := await self._api_request(
- endpoint="/v1/appliance/user/list/get",
- data=data
+ endpoint="/v1/appliance/user/list/get", data=data
):
appliances = {}
for appliance in response["list"]:
@@ -628,20 +647,21 @@ async def list_appliances(self, home_id) -> dict | None:
"model": "",
"online": appliance.get("onlineStatus") == "1",
}
- device_info["sn8"] = device_info.get("sn")[9:17] if len(device_info["sn"]) > 17 else ""
+ device_info["sn8"] = (
+ device_info.get("sn")[9:17] if len(device_info["sn"]) > 17 else ""
+ )
device_info["model"] = device_info.get("sn8")
appliances[int(appliance["id"])] = device_info
return appliances
return None
-def get_midea_cloud(cloud_name: str, session: ClientSession, account: str, password: str) -> MideaCloud | None:
+def get_midea_cloud(
+ cloud_name: str, session: ClientSession, account: str, password: str
+) -> MideaCloud | None:
cloud = None
if cloud_name in clouds.keys():
cloud = globals()[clouds[cloud_name]["class_name"]](
- cloud_name=cloud_name,
- session=session,
- account=account,
- password=password
+ cloud_name=cloud_name, session=session, account=account, password=password
)
return cloud
diff --git a/custom_components/midea_ac_lan/midea/core/crc8.py b/custom_components/midea_ac_lan/midea/core/crc8.py
index 6d87d33c..8ce11bcf 100644
--- a/custom_components/midea_ac_lan/midea/core/crc8.py
+++ b/custom_components/midea_ac_lan/midea/core/crc8.py
@@ -1,36 +1,260 @@
crc8_854_table = [
- 0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
- 0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
- 0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E,
- 0x5F, 0x01, 0xE3, 0xBD, 0x3E, 0x60, 0x82, 0xDC,
- 0x23, 0x7D, 0x9F, 0xC1, 0x42, 0x1C, 0xFE, 0xA0,
- 0xE1, 0xBF, 0x5D, 0x03, 0x80, 0xDE, 0x3C, 0x62,
- 0xBE, 0xE0, 0x02, 0x5C, 0xDF, 0x81, 0x63, 0x3D,
- 0x7C, 0x22, 0xC0, 0x9E, 0x1D, 0x43, 0xA1, 0xFF,
- 0x46, 0x18, 0xFA, 0xA4, 0x27, 0x79, 0x9B, 0xC5,
- 0x84, 0xDA, 0x38, 0x66, 0xE5, 0xBB, 0x59, 0x07,
- 0xDB, 0x85, 0x67, 0x39, 0xBA, 0xE4, 0x06, 0x58,
- 0x19, 0x47, 0xA5, 0xFB, 0x78, 0x26, 0xC4, 0x9A,
- 0x65, 0x3B, 0xD9, 0x87, 0x04, 0x5A, 0xB8, 0xE6,
- 0xA7, 0xF9, 0x1B, 0x45, 0xC6, 0x98, 0x7A, 0x24,
- 0xF8, 0xA6, 0x44, 0x1A, 0x99, 0xC7, 0x25, 0x7B,
- 0x3A, 0x64, 0x86, 0xD8, 0x5B, 0x05, 0xE7, 0xB9,
- 0x8C, 0xD2, 0x30, 0x6E, 0xED, 0xB3, 0x51, 0x0F,
- 0x4E, 0x10, 0xF2, 0xAC, 0x2F, 0x71, 0x93, 0xCD,
- 0x11, 0x4F, 0xAD, 0xF3, 0x70, 0x2E, 0xCC, 0x92,
- 0xD3, 0x8D, 0x6F, 0x31, 0xB2, 0xEC, 0x0E, 0x50,
- 0xAF, 0xF1, 0x13, 0x4D, 0xCE, 0x90, 0x72, 0x2C,
- 0x6D, 0x33, 0xD1, 0x8F, 0x0C, 0x52, 0xB0, 0xEE,
- 0x32, 0x6C, 0x8E, 0xD0, 0x53, 0x0D, 0xEF, 0xB1,
- 0xF0, 0xAE, 0x4C, 0x12, 0x91, 0xCF, 0x2D, 0x73,
- 0xCA, 0x94, 0x76, 0x28, 0xAB, 0xF5, 0x17, 0x49,
- 0x08, 0x56, 0xB4, 0xEA, 0x69, 0x37, 0xD5, 0x8B,
- 0x57, 0x09, 0xEB, 0xB5, 0x36, 0x68, 0x8A, 0xD4,
- 0x95, 0xCB, 0x29, 0x77, 0xF4, 0xAA, 0x48, 0x16,
- 0xE9, 0xB7, 0x55, 0x0B, 0x88, 0xD6, 0x34, 0x6A,
- 0x2B, 0x75, 0x97, 0xC9, 0x4A, 0x14, 0xF6, 0xA8,
- 0x74, 0x2A, 0xC8, 0x96, 0x15, 0x4B, 0xA9, 0xF7,
- 0xB6, 0xE8, 0x0A, 0x54, 0xD7, 0x89, 0x6B, 0x35
+ 0x00,
+ 0x5E,
+ 0xBC,
+ 0xE2,
+ 0x61,
+ 0x3F,
+ 0xDD,
+ 0x83,
+ 0xC2,
+ 0x9C,
+ 0x7E,
+ 0x20,
+ 0xA3,
+ 0xFD,
+ 0x1F,
+ 0x41,
+ 0x9D,
+ 0xC3,
+ 0x21,
+ 0x7F,
+ 0xFC,
+ 0xA2,
+ 0x40,
+ 0x1E,
+ 0x5F,
+ 0x01,
+ 0xE3,
+ 0xBD,
+ 0x3E,
+ 0x60,
+ 0x82,
+ 0xDC,
+ 0x23,
+ 0x7D,
+ 0x9F,
+ 0xC1,
+ 0x42,
+ 0x1C,
+ 0xFE,
+ 0xA0,
+ 0xE1,
+ 0xBF,
+ 0x5D,
+ 0x03,
+ 0x80,
+ 0xDE,
+ 0x3C,
+ 0x62,
+ 0xBE,
+ 0xE0,
+ 0x02,
+ 0x5C,
+ 0xDF,
+ 0x81,
+ 0x63,
+ 0x3D,
+ 0x7C,
+ 0x22,
+ 0xC0,
+ 0x9E,
+ 0x1D,
+ 0x43,
+ 0xA1,
+ 0xFF,
+ 0x46,
+ 0x18,
+ 0xFA,
+ 0xA4,
+ 0x27,
+ 0x79,
+ 0x9B,
+ 0xC5,
+ 0x84,
+ 0xDA,
+ 0x38,
+ 0x66,
+ 0xE5,
+ 0xBB,
+ 0x59,
+ 0x07,
+ 0xDB,
+ 0x85,
+ 0x67,
+ 0x39,
+ 0xBA,
+ 0xE4,
+ 0x06,
+ 0x58,
+ 0x19,
+ 0x47,
+ 0xA5,
+ 0xFB,
+ 0x78,
+ 0x26,
+ 0xC4,
+ 0x9A,
+ 0x65,
+ 0x3B,
+ 0xD9,
+ 0x87,
+ 0x04,
+ 0x5A,
+ 0xB8,
+ 0xE6,
+ 0xA7,
+ 0xF9,
+ 0x1B,
+ 0x45,
+ 0xC6,
+ 0x98,
+ 0x7A,
+ 0x24,
+ 0xF8,
+ 0xA6,
+ 0x44,
+ 0x1A,
+ 0x99,
+ 0xC7,
+ 0x25,
+ 0x7B,
+ 0x3A,
+ 0x64,
+ 0x86,
+ 0xD8,
+ 0x5B,
+ 0x05,
+ 0xE7,
+ 0xB9,
+ 0x8C,
+ 0xD2,
+ 0x30,
+ 0x6E,
+ 0xED,
+ 0xB3,
+ 0x51,
+ 0x0F,
+ 0x4E,
+ 0x10,
+ 0xF2,
+ 0xAC,
+ 0x2F,
+ 0x71,
+ 0x93,
+ 0xCD,
+ 0x11,
+ 0x4F,
+ 0xAD,
+ 0xF3,
+ 0x70,
+ 0x2E,
+ 0xCC,
+ 0x92,
+ 0xD3,
+ 0x8D,
+ 0x6F,
+ 0x31,
+ 0xB2,
+ 0xEC,
+ 0x0E,
+ 0x50,
+ 0xAF,
+ 0xF1,
+ 0x13,
+ 0x4D,
+ 0xCE,
+ 0x90,
+ 0x72,
+ 0x2C,
+ 0x6D,
+ 0x33,
+ 0xD1,
+ 0x8F,
+ 0x0C,
+ 0x52,
+ 0xB0,
+ 0xEE,
+ 0x32,
+ 0x6C,
+ 0x8E,
+ 0xD0,
+ 0x53,
+ 0x0D,
+ 0xEF,
+ 0xB1,
+ 0xF0,
+ 0xAE,
+ 0x4C,
+ 0x12,
+ 0x91,
+ 0xCF,
+ 0x2D,
+ 0x73,
+ 0xCA,
+ 0x94,
+ 0x76,
+ 0x28,
+ 0xAB,
+ 0xF5,
+ 0x17,
+ 0x49,
+ 0x08,
+ 0x56,
+ 0xB4,
+ 0xEA,
+ 0x69,
+ 0x37,
+ 0xD5,
+ 0x8B,
+ 0x57,
+ 0x09,
+ 0xEB,
+ 0xB5,
+ 0x36,
+ 0x68,
+ 0x8A,
+ 0xD4,
+ 0x95,
+ 0xCB,
+ 0x29,
+ 0x77,
+ 0xF4,
+ 0xAA,
+ 0x48,
+ 0x16,
+ 0xE9,
+ 0xB7,
+ 0x55,
+ 0x0B,
+ 0x88,
+ 0xD6,
+ 0x34,
+ 0x6A,
+ 0x2B,
+ 0x75,
+ 0x97,
+ 0xC9,
+ 0x4A,
+ 0x14,
+ 0xF6,
+ 0xA8,
+ 0x74,
+ 0x2A,
+ 0xC8,
+ 0x96,
+ 0x15,
+ 0x4B,
+ 0xA9,
+ 0xF7,
+ 0xB6,
+ 0xE8,
+ 0x0A,
+ 0x54,
+ 0xD7,
+ 0x89,
+ 0x6B,
+ 0x35,
]
diff --git a/custom_components/midea_ac_lan/midea/core/device.py b/custom_components/midea_ac_lan/midea/core/device.py
index 7ba2fe30..f47c2955 100644
--- a/custom_components/midea_ac_lan/midea/core/device.py
+++ b/custom_components/midea_ac_lan/midea/core/device.py
@@ -1,20 +1,27 @@
import threading
+
try:
from enum import StrEnum
except ImportError:
from ..backports.myenum import StrEnum
+
+import logging
+import socket
+import time
from enum import IntEnum
-from .security import LocalSecurity, MSGTYPE_HANDSHAKE_REQUEST, MSGTYPE_ENCRYPTED_REQUEST
-from .packet_builder import PacketBuilder
+
from .message import (
- MessageType,
- MessageQuestCustom,
+ MessageApplianceResponse,
MessageQueryAppliance,
- MessageApplianceResponse
+ MessageQuestCustom,
+ MessageType,
+)
+from .packet_builder import PacketBuilder
+from .security import (
+ MSGTYPE_ENCRYPTED_REQUEST,
+ MSGTYPE_HANDSHAKE_REQUEST,
+ LocalSecurity,
)
-import socket
-import logging
-import time
_LOGGER = logging.getLogger(__name__)
@@ -42,18 +49,20 @@ class ParseMessageResult(IntEnum):
class MiedaDevice(threading.Thread):
- def __init__(self,
- name: str,
- device_id: int,
- device_type: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- attributes: dict):
+ def __init__(
+ self,
+ name: str,
+ device_id: int,
+ device_type: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ attributes: dict,
+ ):
threading.Thread.__init__(self)
self._attributes = attributes if attributes else {}
self._socket = None
@@ -122,7 +131,9 @@ def connect(self, refresh_status=True):
try:
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.settimeout(10)
- _LOGGER.debug(f"[{self._device_id}] Connecting to {self._ip_address}:{self._port}")
+ _LOGGER.debug(
+ f"[{self._device_id}] Connecting to {self._ip_address}:{self._port}"
+ )
self._socket.connect((self._ip_address, self._port))
_LOGGER.debug(f"[{self._device_id}] Connected")
if self._protocol == 3:
@@ -143,20 +154,21 @@ def connect(self, refresh_status=True):
except RefreshFailed:
_LOGGER.debug(f"[{self._device_id}] Refresh status is timed out")
except Exception as e:
- _LOGGER.error(f"[{self._device_id}] Unknown error: {e.__traceback__.tb_frame.f_globals['__file__']}, "
- f"{e.__traceback__.tb_lineno}, {repr(e)}")
+ _LOGGER.error(
+ f"[{self._device_id}] Unknown error: {e.__traceback__.tb_frame.f_globals['__file__']}, "
+ f"{e.__traceback__.tb_lineno}, {repr(e)}"
+ )
self.enable_device(False)
return False
def authenticate(self):
- request = self._security.encode_8370(
- self._token, MSGTYPE_HANDSHAKE_REQUEST)
+ request = self._security.encode_8370(self._token, MSGTYPE_HANDSHAKE_REQUEST)
_LOGGER.debug(f"[{self._device_id}] Handshaking")
self._socket.send(request)
response = self._socket.recv(512)
if len(response) < 20:
raise AuthException()
- response = response[8: 72]
+ response = response[8:72]
self._security.tcp_key(response, self._key)
def send_message(self, data):
@@ -169,7 +181,9 @@ def send_message_v2(self, data):
if self._socket is not None:
self._socket.send(data)
else:
- _LOGGER.debug(f"[{self._device_id}] Send failure, device disconnected, data: {data.hex()}")
+ _LOGGER.debug(
+ f"[{self._device_id}] Send failure, device disconnected, data: {data.hex()}"
+ )
def send_message_v3(self, data, msg_type=MSGTYPE_ENCRYPTED_REQUEST):
data = self._security.encode_8370(data, msg_type)
@@ -205,8 +219,10 @@ def refresh_status(self, wait_response=False):
except socket.timeout:
error_count += 1
self._unsupported_protocol.append(cmd.__class__.__name__)
- _LOGGER.debug(f"[{self._device_id}] Does not supports "
- f"the protocol {cmd.__class__.__name__}, ignored")
+ _LOGGER.debug(
+ f"[{self._device_id}] Does not supports "
+ f"the protocol {cmd.__class__.__name__}, ignored"
+ )
except ResponseException:
error_count += 1
else:
@@ -220,7 +236,9 @@ def pre_process_message(self, msg):
self._appliance_query = False
_LOGGER.debug(f"[{self.device_id}] Received: {message}")
self._protocol_version = message.protocol_version
- _LOGGER.debug(f"[{self._device_id}] Device protocol version: {self._protocol_version}")
+ _LOGGER.debug(
+ f"[{self._device_id}] Device protocol version: {self._protocol_version}"
+ )
return False
return True
@@ -252,9 +270,13 @@ def parse_message(self, msg):
if len(status) > 0:
self.update_all(status)
else:
- _LOGGER.debug(f"[{self._device_id}] Unidentified protocol")
+ _LOGGER.debug(
+ f"[{self._device_id}] Unidentified protocol"
+ )
except Exception as e:
- _LOGGER.error(f"[{self._device_id}] Error in process message: {e}, msg = {decrypted.hex()}")
+ _LOGGER.error(
+ f"[{self._device_id}] Error in process message: {e}, msg = {decrypted.hex()}"
+ )
else:
_LOGGER.warning(
f"[{self._device_id}] Illegal payload, "
@@ -278,12 +300,16 @@ def process_message(self, msg):
raise NotImplementedError
def send_command(self, cmd_type, cmd_body: bytearray):
- cmd = MessageQuestCustom(self._device_type, self._protocol_version, cmd_type, cmd_body)
+ cmd = MessageQuestCustom(
+ self._device_type, self._protocol_version, cmd_type, cmd_body
+ )
try:
self.build_send(cmd)
except socket.error as e:
- _LOGGER.debug(f"[{self._device_id}] Interface send_command failure, {repr(e)}, "
- f"cmd_type: {cmd_type}, cmd_body: {cmd_body.hex()}")
+ _LOGGER.debug(
+ f"[{self._device_id}] Interface send_command failure, {repr(e)}, "
+ f"cmd_type: {cmd_type}, cmd_body: {cmd_body.hex()}"
+ )
def send_heartbeat(self):
msg = PacketBuilder(self._device_id, bytearray([0x00])).finalize(msg_type=0)
@@ -373,8 +399,10 @@ def run(self):
self.close_socket()
break
except Exception as e:
- _LOGGER.error(f"[{self._device_id}] Unknown error :{e.__traceback__.tb_frame.f_globals['__file__']}, "
- f"{e.__traceback__.tb_lineno}, {repr(e)}")
+ _LOGGER.error(
+ f"[{self._device_id}] Unknown error :{e.__traceback__.tb_frame.f_globals['__file__']}, "
+ f"{e.__traceback__.tb_lineno}, {repr(e)}"
+ )
self.close_socket()
break
diff --git a/custom_components/midea_ac_lan/midea/core/discover.py b/custom_components/midea_ac_lan/midea/core/discover.py
index a4be3e26..0deb1790 100644
--- a/custom_components/midea_ac_lan/midea/core/discover.py
+++ b/custom_components/midea_ac_lan/midea/core/discover.py
@@ -1,8 +1,11 @@
import logging
import socket
-import ifaddr
from ipaddress import IPv4Network
+
+import ifaddr
+
from .security import LocalSecurity
+
try:
import xml.etree.cElementTree as ET
except ImportError:
@@ -10,27 +13,143 @@
_LOGGER = logging.getLogger(__name__)
-BROADCAST_MSG = bytearray([
- 0x5a, 0x5a, 0x01, 0x11, 0x48, 0x00, 0x92, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7f, 0x75, 0xbd, 0x6b, 0x3e, 0x4f, 0x8b, 0x76,
- 0x2e, 0x84, 0x9c, 0x6e, 0x57, 0x8d, 0x65, 0x90,
- 0x03, 0x6e, 0x9d, 0x43, 0x42, 0xa5, 0x0f, 0x1f,
- 0x56, 0x9e, 0xb8, 0xec, 0x91, 0x8e, 0x92, 0xe5
-])
-
-DEVICE_INFO_MSG = bytearray([
- 0x5a, 0x5a, 0x15, 0x00, 0x00, 0x38, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x33, 0x05,
- 0x13, 0x06, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xca, 0x8d, 0x9b, 0xf9, 0xa0, 0x30, 0x1a, 0xe3,
- 0xb7, 0xe4, 0x2d, 0x53, 0x49, 0x47, 0x62, 0xbe
-])
+BROADCAST_MSG = bytearray(
+ [
+ 0x5A,
+ 0x5A,
+ 0x01,
+ 0x11,
+ 0x48,
+ 0x00,
+ 0x92,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7F,
+ 0x75,
+ 0xBD,
+ 0x6B,
+ 0x3E,
+ 0x4F,
+ 0x8B,
+ 0x76,
+ 0x2E,
+ 0x84,
+ 0x9C,
+ 0x6E,
+ 0x57,
+ 0x8D,
+ 0x65,
+ 0x90,
+ 0x03,
+ 0x6E,
+ 0x9D,
+ 0x43,
+ 0x42,
+ 0xA5,
+ 0x0F,
+ 0x1F,
+ 0x56,
+ 0x9E,
+ 0xB8,
+ 0xEC,
+ 0x91,
+ 0x8E,
+ 0x92,
+ 0xE5,
+ ]
+)
+
+DEVICE_INFO_MSG = bytearray(
+ [
+ 0x5A,
+ 0x5A,
+ 0x15,
+ 0x00,
+ 0x00,
+ 0x38,
+ 0x00,
+ 0x04,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x27,
+ 0x33,
+ 0x05,
+ 0x13,
+ 0x06,
+ 0x14,
+ 0x14,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x03,
+ 0xE8,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xCA,
+ 0x8D,
+ 0x9B,
+ 0xF9,
+ 0xA0,
+ 0x30,
+ 0x1A,
+ 0xE3,
+ 0xB7,
+ 0xE4,
+ 0x2D,
+ 0x53,
+ 0x49,
+ 0x47,
+ 0x62,
+ 0xBE,
+ ]
+)
def discover(discover_type=None, ip_address=None):
@@ -57,7 +176,9 @@ def discover(discover_type=None, ip_address=None):
data, addr = sock.recvfrom(512)
ip = addr[0]
_LOGGER.debug(f"Received response from {addr}: {data.hex()}")
- if len(data) >= 104 and (data[:2].hex() == "5a5a" or data[8:10].hex() == "5a5a"):
+ if len(data) >= 104 and (
+ data[:2].hex() == "5a5a" or data[8:10].hex() == "5a5a"
+ ):
if data[:2].hex() == "5a5a":
protocol = 2
elif data[:2].hex() == "8370":
@@ -66,25 +187,29 @@ def discover(discover_type=None, ip_address=None):
data = data[8:-16]
else:
continue
- device_id = int.from_bytes(bytearray.fromhex(data[20:26].hex()), "little")
+ device_id = int.from_bytes(
+ bytearray.fromhex(data[20:26].hex()), "little"
+ )
if device_id in found_devices:
continue
encrypt_data = data[40:-16]
reply = security.aes_decrypt(encrypt_data)
_LOGGER.debug(f"Declassified reply: {reply.hex()}")
- ssid = reply[41:41 + reply[40]].decode("utf-8")
+ ssid = reply[41 : 41 + reply[40]].decode("utf-8")
device_type = ssid.split("_")[1]
port = bytes2port(reply[4:8])
model = reply[17:25].decode("utf-8")
sn = reply[8:40].decode("utf-8")
elif data[:6].hex() == "3c3f786d6c20":
protocol = 1
- root = ET.fromstring(data.decode(
- encoding="utf-8", errors="replace"))
+ root = ET.fromstring(data.decode(encoding="utf-8", errors="replace"))
child = root.find("body/device")
m = child.attrib
- port, sn, device_type = int(m["port"]), m["apc_sn"], str(
- hex(int(m["apc_type"])))[2:]
+ port, sn, device_type = (
+ int(m["port"]),
+ m["apc_sn"],
+ str(hex(int(m["apc_type"])))[2:],
+ )
response = get_device_info(ip, int(port))
device_id = get_id_from_response(response)
if len(sn) == 32:
@@ -102,7 +227,7 @@ def discover(discover_type=None, ip_address=None):
"port": port,
"model": model,
"sn": sn,
- "protocol": protocol
+ "protocol": protocol,
}
if len(discover_type) == 0 or device.get("type") in discover_type:
found_devices[device_id] = device
@@ -148,13 +273,16 @@ def get_device_info(device_ip, device_port: int):
sock.settimeout(8)
device_address = (device_ip, device_port)
sock.connect(device_address)
- _LOGGER.debug(f"Sending to {device_ip}:{device_port} {DEVICE_INFO_MSG.hex()}")
+ _LOGGER.debug(
+ f"Sending to {device_ip}:{device_port} {DEVICE_INFO_MSG.hex()}"
+ )
sock.sendall(DEVICE_INFO_MSG)
response = sock.recv(512)
except socket.timeout:
- _LOGGER.warning(f"Connect the device {device_ip}:{device_port} timed out for 8s. "
- f"Don't care about a small amount of this. if many maybe not support."
- )
+ _LOGGER.warning(
+ f"Connect the device {device_ip}:{device_port} timed out for 8s. "
+ f"Don't care about a small amount of this. if many maybe not support."
+ )
except socket.error:
_LOGGER.warning(f"Can't connect to Device {device_ip}:{device_port}")
return response
@@ -166,8 +294,14 @@ def enum_all_broadcast():
for adapter in adapters:
for ip in adapter.ips:
if ip.is_IPv4 and ip.network_prefix < 32:
- local_network = IPv4Network(f"{ip.ip}/{ip.network_prefix}", strict=False)
- if local_network.is_private and not local_network.is_loopback and not local_network.is_link_local:
+ local_network = IPv4Network(
+ f"{ip.ip}/{ip.network_prefix}", strict=False
+ )
+ if (
+ local_network.is_private
+ and not local_network.is_loopback
+ and not local_network.is_link_local
+ ):
addr = str(local_network.broadcast_address)
if addr not in nets:
nets.append(addr)
diff --git a/custom_components/midea_ac_lan/midea/core/message.py b/custom_components/midea_ac_lan/midea/core/message.py
index 4c744a45..91e485c6 100644
--- a/custom_components/midea_ac_lan/midea/core/message.py
+++ b/custom_components/midea_ac_lan/midea/core/message.py
@@ -18,12 +18,12 @@ class MessageCheckSumError(Exception):
class MessageType(IntEnum):
- set = 0x02,
- query = 0x03,
- notify1 = 0x04,
- notify2 = 0x05,
- exception = 0x06,
- exception2 = 0x0A,
+ set = (0x02,)
+ query = (0x03,)
+ notify1 = (0x04,)
+ notify2 = (0x05,)
+ exception = (0x06,)
+ exception2 = (0x0A,)
query_appliance = 0xA0
@@ -38,7 +38,7 @@ def __init__(self):
@staticmethod
def checksum(data):
- return (~ sum(data) + 1) & 0xff
+ return (~sum(data) + 1) & 0xFF
@property
def header(self):
@@ -85,7 +85,9 @@ def __str__(self) -> str:
"header": self.header.hex(),
"body": self.body.hex(),
"message type": "%02x" % self._message_type,
- "body type": ("%02x" % self._body_type) if self._body_type is not None else "None"
+ "body type": (
+ ("%02x" % self._body_type) if self._body_type is not None else "None"
+ ),
}
return str(output)
@@ -101,26 +103,29 @@ def __init__(self, device_type, protocol_version, message_type, body_type):
@property
def header(self):
length = self.HEADER_LENGTH + len(self.body)
- return bytearray([
- # flag
- 0xAA,
- # length
- length,
- # device type
- self.device_type,
- # frame checksum
- 0x00, # self._device_type ^ length,
- # unused
- 0x00, 0x00,
- # frame ID
- 0x00,
- # frame protocol version
- 0x00,
- # device protocol version
- self.protocol_version,
- # frame type
- self.message_type
- ])
+ return bytearray(
+ [
+ # flag
+ 0xAA,
+ # length
+ length,
+ # device type
+ self.device_type,
+ # frame checksum
+ 0x00, # self._device_type ^ length,
+ # unused
+ 0x00,
+ 0x00,
+ # frame ID
+ 0x00,
+ # frame protocol version
+ 0x00,
+ # device protocol version
+ self.protocol_version,
+ # frame type
+ self.message_type,
+ ]
+ )
@property
def _body(self):
@@ -147,7 +152,8 @@ def __init__(self, device_type, protocol_version, cmd_type, cmd_body):
device_type=device_type,
protocol_version=protocol_version,
message_type=cmd_type,
- body_type=None)
+ body_type=None,
+ )
self._cmd_body = cmd_body
@property
@@ -165,7 +171,8 @@ def __init__(self, device_type):
device_type=device_type,
protocol_version=0,
message_type=MessageType.query_appliance,
- body_type=None)
+ body_type=None,
+ )
@property
def _body(self):
@@ -196,7 +203,7 @@ def read_byte(body, byte, default_value=0):
class NewProtocolMessageBody(MessageBody):
def __init__(self, body, bt):
super().__init__(body)
- if bt == 0xb5:
+ if bt == 0xB5:
self._pack_len = 4
else:
self._pack_len = 5
@@ -220,9 +227,9 @@ def parse(self):
pos += 1
length = self.data[pos + 2]
if length > 0:
- value = self.data[pos + 3: pos + 3 + length]
+ value = self.data[pos + 3 : pos + 3 + length]
result[param] = value
- pos += (3 + length)
+ pos += 3 + length
except IndexError:
# Some device used non-standard new-protocol(美的乐享三代中央空调?)
_LOGGER.debug(f"Non-standard new-protocol {self.data.hex()}")
@@ -234,11 +241,11 @@ def __init__(self, message):
super().__init__()
if message is None or len(message) < self.HEADER_LENGTH + 1:
raise MessageLenError
- self._header = message[:self.HEADER_LENGTH]
+ self._header = message[: self.HEADER_LENGTH]
self.protocol_version = self._header[-2]
self.message_type = self._header[-1]
self.device_type = self._header[2]
- body = message[self.HEADER_LENGTH: -1]
+ body = message[self.HEADER_LENGTH : -1]
self._body = MessageBody(body)
self.body_type = self._body.body_type
diff --git a/custom_components/midea_ac_lan/midea/core/packet_builder.py b/custom_components/midea_ac_lan/midea/core/packet_builder.py
index 6fed16be..04780fee 100644
--- a/custom_components/midea_ac_lan/midea/core/packet_builder.py
+++ b/custom_components/midea_ac_lan/midea/core/packet_builder.py
@@ -1,6 +1,7 @@
-from .security import LocalSecurity
import datetime
+from .security import LocalSecurity
+
class PacketBuilder:
def __init__(self, device_id: int, command):
@@ -8,24 +9,58 @@ def __init__(self, device_id: int, command):
self.security = LocalSecurity()
# aa20ac00000000000003418100ff03ff000200000000000000000000000006f274
# Init the packet with the header data.
- self.packet = bytearray([
- # 2 bytes - StaicHeader
- 0x5a, 0x5a,
- # 2 bytes - mMessageType
- 0x01, 0x11,
- # 2 bytes - PacketLenght
- 0x00, 0x00,
- # 2 bytes
- 0x20, 0x00,
- # 4 bytes - MessageId
- 0x00, 0x00, 0x00, 0x00,
- # 8 bytes - Date&Time
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- # 6 bytes - mDeviceID
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- # 12 bytes
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- ])
+ self.packet = bytearray(
+ [
+ # 2 bytes - StaicHeader
+ 0x5A,
+ 0x5A,
+ # 2 bytes - mMessageType
+ 0x01,
+ 0x11,
+ # 2 bytes - PacketLenght
+ 0x00,
+ 0x00,
+ # 2 bytes
+ 0x20,
+ 0x00,
+ # 4 bytes - MessageId
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ # 8 bytes - Date&Time
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ # 6 bytes - mDeviceID
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ # 12 bytes
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
self.packet[12:20] = self.packet_time()
self.packet[20:28] = device_id.to_bytes(8, "little")
self.command = command
@@ -33,7 +68,7 @@ def __init__(self, device_id: int, command):
def finalize(self, msg_type=1):
if msg_type != 1:
self.packet[3] = 0x10
- self.packet[6] = 0x7b
+ self.packet[6] = 0x7B
else:
self.packet.extend(self.security.aes_encrypt(self.command))
# PacketLenght
@@ -47,14 +82,13 @@ def encode32(self, data: bytearray):
@staticmethod
def checksum(data):
- return (~ sum(data) + 1) & 0xff
+ return (~sum(data) + 1) & 0xFF
@staticmethod
def packet_time():
- t = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")[
- :16]
+ t = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")[:16]
b = bytearray()
for i in range(0, len(t), 2):
- d = int(t[i:i+2])
+ d = int(t[i : i + 2])
b.insert(0, d)
return b
diff --git a/custom_components/midea_ac_lan/midea/core/security.py b/custom_components/midea_ac_lan/midea/core/security.py
index 26cf0262..90166ea1 100644
--- a/custom_components/midea_ac_lan/midea/core/security.py
+++ b/custom_components/midea_ac_lan/midea/core/security.py
@@ -1,12 +1,12 @@
-from Crypto.Cipher import AES
-from Crypto.Util.Padding import pad, unpad
-from Crypto.Util.strxor import strxor
-from Crypto.Random import get_random_bytes
-from urllib.parse import unquote_plus, urlencode, urlparse
+import hmac
from hashlib import md5, sha256
from typing import Any
-import hmac
+from urllib.parse import unquote_plus, urlencode, urlparse
+from Crypto.Cipher import AES
+from Crypto.Random import get_random_bytes
+from Crypto.Util.Padding import pad, unpad
+from Crypto.Util.strxor import strxor
MSGTYPE_HANDSHAKE_REQUEST = 0x0
MSGTYPE_HANDSHAKE_RESPONSE = 0x1
@@ -21,8 +21,8 @@ def __init__(self, login_key, iot_key, hmac_key, fixed_key=None, fixed_iv=None):
self._hmac_key = hmac_key
self._aes_key = None
self._aes_iv = None
- self._fixed_key = format(fixed_key, 'x').encode("ascii") if fixed_key else None
- self._fixed_iv = format(fixed_iv, 'x').encode("ascii") if fixed_iv else None
+ self._fixed_key = format(fixed_key, "x").encode("ascii") if fixed_key else None
+ self._fixed_iv = format(fixed_iv, "x").encode("ascii") if fixed_iv else None
def sign(self, url: str, data: Any, random: str) -> str:
msg = self._iot_key
@@ -59,7 +59,7 @@ def get_udp_id(appliance_id, method=0):
data = bytearray(sha256(bytes_id).digest())
for i in range(0, 16):
data[i] ^= data[i + 16]
- return data[0: 16].hex()
+ return data[0:16].hex()
def set_aes_keys(self, key, iv):
if isinstance(key, str):
@@ -103,15 +103,18 @@ def aes_decrypt(self, data, key=None, iv=None):
if isinstance(data, str):
data = bytes.fromhex(data)
if aes_iv is None: # ECB
- return unpad(AES.new(aes_key, AES.MODE_ECB).decrypt(data), len(aes_key)).decode()
+ return unpad(
+ AES.new(aes_key, AES.MODE_ECB).decrypt(data), len(aes_key)
+ ).decode()
else: # CBC
- return unpad(AES.new(aes_key, AES.MODE_CBC, iv=aes_iv).decrypt(data), len(aes_key)).decode()
+ return unpad(
+ AES.new(aes_key, AES.MODE_CBC, iv=aes_iv).decrypt(data), len(aes_key)
+ ).decode()
class MeijuCloudSecurity(CloudSecurity):
def __init__(self, login_key, iot_key, hmac_key):
- super().__init__(login_key, iot_key, hmac_key,
- 10864842703515613082)
+ super().__init__(login_key, iot_key, hmac_key, 10864842703515613082)
def encrypt_iam_password(self, login_id, data) -> str:
md = md5()
@@ -123,9 +126,9 @@ def encrypt_iam_password(self, login_id, data) -> str:
class MSmartCloudSecurity(CloudSecurity):
def __init__(self, login_key, iot_key, hmac_key):
- super().__init__(login_key, iot_key, hmac_key,
- 13101328926877700970,
- 16429062708050928556)
+ super().__init__(
+ login_key, iot_key, hmac_key, 13101328926877700970, 16429062708050928556
+ )
def encrypt_iam_password(self, login_id, data) -> str:
md = md5()
@@ -141,8 +144,8 @@ def set_aes_keys(self, encrypted_key, encrypted_iv):
key_digest = sha256(self._login_key.encode("ascii")).hexdigest()
tmp_key = key_digest[:16].encode("ascii")
tmp_iv = key_digest[16:32].encode("ascii")
- self._aes_key = self.aes_decrypt(encrypted_key, tmp_key, tmp_iv).encode('ascii')
- self._aes_iv = self.aes_decrypt(encrypted_iv, tmp_key, tmp_iv).encode('ascii')
+ self._aes_key = self.aes_decrypt(encrypted_key, tmp_key, tmp_iv).encode("ascii")
+ self._aes_iv = self.aes_decrypt(encrypted_iv, tmp_key, tmp_iv).encode("ascii")
class MideaAirSecurity(CloudSecurity):
@@ -161,10 +164,13 @@ def __init__(self):
self.blockSize = 16
self.iv = b"\0" * 16
self.aes_key = bytes.fromhex(
- format(141661095494369103254425781617665632877, 'x')
+ format(141661095494369103254425781617665632877, "x")
)
self.salt = bytes.fromhex(
- format(233912452794221312800602098970898185176935770387238278451789080441632479840061417076563, 'x')
+ format(
+ 233912452794221312800602098970898185176935770387238278451789080441632479840061417076563,
+ "x",
+ )
)
self._tcp_key = None
self._request_count = 0
@@ -172,7 +178,9 @@ def __init__(self):
def aes_decrypt(self, raw):
try:
- return unpad(AES.new(self.aes_key, AES.MODE_ECB).decrypt(bytearray(raw)), 16)
+ return unpad(
+ AES.new(self.aes_key, AES.MODE_ECB).decrypt(bytearray(raw)), 16
+ )
except ValueError:
return bytearray(0)
@@ -208,7 +216,7 @@ def encode_8370(self, data, msgtype):
size, padding = len(data), 0
if msgtype in (MSGTYPE_ENCRYPTED_RESPONSE, MSGTYPE_ENCRYPTED_REQUEST):
if (size + 2) % 16 != 0:
- padding = 16 - (size + 2 & 0xf)
+ padding = 16 - (size + 2 & 0xF)
size += padding + 32
data += get_random_bytes(padding)
header += size.to_bytes(2, "big")
@@ -238,7 +246,7 @@ def decode_8370(self, data):
if header[4] != 0x20:
raise Exception("missing byte 4")
padding = header[5] >> 4
- msgtype = header[5] & 0xf
+ msgtype = header[5] & 0xF
data = data[6:]
if msgtype in (MSGTYPE_ENCRYPTED_RESPONSE, MSGTYPE_ENCRYPTED_REQUEST):
sign = data[-32:]
diff --git a/custom_components/midea_ac_lan/midea/devices/__init__.py b/custom_components/midea_ac_lan/midea/devices/__init__.py
index 4a732c88..6a908f26 100644
--- a/custom_components/midea_ac_lan/midea/devices/__init__.py
+++ b/custom_components/midea_ac_lan/midea/devices/__init__.py
@@ -1,7 +1,8 @@
-from homeassistant.core import HomeAssistant
from importlib import import_module
from types import ModuleType
+from homeassistant.core import HomeAssistant
+
async def async_device_selector(
hass: HomeAssistant,
@@ -15,7 +16,7 @@ async def async_device_selector(
protocol: int,
model: str,
subtype: int,
- customize: str
+ customize: str,
):
try:
@@ -29,6 +30,7 @@ async def async_device_selector(
def _load_device_module() -> None:
"""Load all service modules."""
modules.append(import_module(device_path, __package__))
+
await hass.async_add_import_executor_job(_load_device_module)
device = modules[0].MideaAppliance(
@@ -41,7 +43,7 @@ def _load_device_module() -> None:
protocol=protocol,
model=model,
subtype=subtype,
- customize=customize
+ customize=customize,
)
except ModuleNotFoundError:
device = None
diff --git a/custom_components/midea_ac_lan/midea/devices/a1/device.py b/custom_components/midea_ac_lan/midea/devices/a1/device.py
index 4cc990a4..cbff7675 100644
--- a/custom_components/midea_ac_lan/midea/devices/a1/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/a1/device.py
@@ -1,13 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageA1Response,
- MessageSet
-)
+
+from .message import MessageA1Response, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -30,28 +29,29 @@ class DeviceAttributes(StrEnum):
class MideaA1Device(MiedaDevice):
- _modes = [
- "Manual", "Continuous", "Auto", "Clothes-Dry", "Shoes-Dry"
- ]
+ _modes = ["Manual", "Continuous", "Auto", "Clothes-Dry", "Shoes-Dry"]
_speeds = {
- 1: "Lowest", 40: "Low", 60: "Medium", 80: "High", 102: "Auto", 127: "Off"
+ 1: "Lowest",
+ 40: "Low",
+ 60: "Medium",
+ 80: "High",
+ 102: "Auto",
+ 127: "Off",
}
- _water_level_sets = [
- "25", "50", "75", "100"
- ]
+ _water_level_sets = ["25", "50", "75", "100"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -77,8 +77,9 @@ def __init__(
DeviceAttributes.water_level_set: 50,
DeviceAttributes.tank_full: None,
DeviceAttributes.current_humidity: None,
- DeviceAttributes.current_temperature: None
- })
+ DeviceAttributes.current_temperature: None,
+ },
+ )
@property
def modes(self):
@@ -93,9 +94,7 @@ def water_level_sets(self):
return MideaA1Device._water_level_sets
def build_query(self):
- return [
- MessageQuery(self._protocol_version)
- ]
+ return [MessageQuery(self._protocol_version)]
def process_message(self, msg):
message = MessageA1Response(msg)
@@ -119,9 +118,13 @@ def process_message(self, msg):
self._attributes[status] = str(value)
else:
self._attributes[status] = value
- tank_full = (self._attributes[DeviceAttributes.tank] >=
- int(self._attributes[DeviceAttributes.water_level_set]))
- if self._attributes[DeviceAttributes.tank_full] is None or self._attributes[DeviceAttributes.tank_full] != tank_full:
+ tank_full = self._attributes[DeviceAttributes.tank] >= int(
+ self._attributes[DeviceAttributes.water_level_set]
+ )
+ if (
+ self._attributes[DeviceAttributes.tank_full] is None
+ or self._attributes[DeviceAttributes.tank_full] != tank_full
+ ):
self._attributes[DeviceAttributes.tank_full] = tank_full
new_status[str(DeviceAttributes.tank_full)] = tank_full
new_status[str(status)] = self._attributes[status]
@@ -133,17 +136,26 @@ def make_message_set(self):
message.prompt_tone = self._attributes[DeviceAttributes.prompt_tone]
message.child_lock = self._attributes[DeviceAttributes.child_lock]
if self._attributes[DeviceAttributes.mode] in MideaA1Device._modes:
- message.mode = MideaA1Device._modes.index(self._attributes[DeviceAttributes.mode]) + 1
+ message.mode = (
+ MideaA1Device._modes.index(self._attributes[DeviceAttributes.mode]) + 1
+ )
else:
message.mode = 1
- message.fan_speed = 40 if self._attributes[DeviceAttributes.fan_speed] is None else \
- list(MideaA1Device._speeds.keys())[list(MideaA1Device._speeds.values()).index(
- self._attributes[DeviceAttributes.fan_speed]
- )]
+ message.fan_speed = (
+ 40
+ if self._attributes[DeviceAttributes.fan_speed] is None
+ else list(MideaA1Device._speeds.keys())[
+ list(MideaA1Device._speeds.values()).index(
+ self._attributes[DeviceAttributes.fan_speed]
+ )
+ ]
+ )
message.target_humidity = self._attributes[DeviceAttributes.target_humidity]
message.swing = self._attributes[DeviceAttributes.swing]
message.anion = self._attributes[DeviceAttributes.anion]
- message.water_level_set = int(self._attributes[DeviceAttributes.water_level_set])
+ message.water_level_set = int(
+ self._attributes[DeviceAttributes.water_level_set]
+ )
return message
def set_attribute(self, attr, value):
diff --git a/custom_components/midea_ac_lan/midea/devices/a1/message.py b/custom_components/midea_ac_lan/midea/devices/a1/message.py
index e1dbe517..f6a43b7a 100644
--- a/custom_components/midea_ac_lan/midea/devices/a1/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/a1/message.py
@@ -1,11 +1,12 @@
from enum import IntEnum
+
from ...core.crc8 import calculate
from ...core.message import (
- MessageType,
+ MessageBody,
MessageRequest,
MessageResponse,
- MessageBody,
- NewProtocolMessageBody
+ MessageType,
+ NewProtocolMessageBody,
)
@@ -44,17 +45,34 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x41)
+ body_type=0x41,
+ )
@property
def _body(self):
- return bytearray([
- 0x81, 0x00, 0xFF, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
- ])
+ return bytearray(
+ [
+ 0x81,
+ 0x00,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessageNewProtocolQuery(MessageA1Base):
@@ -62,13 +80,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0xB1)
+ body_type=0xB1,
+ )
@property
def _body(self):
- query_params = [
- NewProtocolTags.light
- ]
+ query_params = [NewProtocolTags.light]
_body = bytearray([len(query_params)])
for param in query_params:
_body.extend([param & 0xFF, param >> 8])
@@ -80,7 +97,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x48)
+ body_type=0x48,
+ )
self.power = False
self.prompt_tone = False
self.mode = 1
@@ -110,20 +128,30 @@ def _body(self):
swing = 0x08 if self.swing else 0x00
# byte 13 water_level_set
water_level_set = self.water_level_set
- return bytearray([
- power | prompt_tone | 0x02,
- mode,
- fan_speed,
- 0x00, 0x00, 0x00,
- target_humidity,
- child_lock,
- anion,
- swing,
- 0x00, 0x00,
- water_level_set,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
- ])
+ return bytearray(
+ [
+ power | prompt_tone | 0x02,
+ mode,
+ fan_speed,
+ 0x00,
+ 0x00,
+ 0x00,
+ target_humidity,
+ child_lock,
+ anion,
+ swing,
+ 0x00,
+ 0x00,
+ water_level_set,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessageNewProtocolSet(MessageA1Base):
@@ -131,7 +159,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0xB0)
+ body_type=0xB0,
+ )
self.light = None
@property
@@ -143,8 +172,9 @@ def _body(self):
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.light,
- value=bytearray([0x01 if self.light else 0x00])
- ))
+ value=bytearray([0x01 if self.light else 0x00]),
+ )
+ )
payload[0] = pack_count
return payload
@@ -172,13 +202,17 @@ def __init__(self, body, bt):
super().__init__(body, bt)
params = self.parse()
if NewProtocolTags.light in params:
- self.light = (params[NewProtocolTags.light][0] > 0)
+ self.light = params[NewProtocolTags.light][0] > 0
class MessageA1Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set, MessageType.notify1]:
+ if self.message_type in [
+ MessageType.query,
+ MessageType.set,
+ MessageType.notify1,
+ ]:
if self.body_type in [0xB0, 0xB1, 0xB5]:
self.set_body(A1NewProtocolMessageBody(super().body, self.body_type))
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/ac/device.py b/custom_components/midea_ac_lan/midea/devices/ac/device.py
index 977c6050..87ccb1c2 100644
--- a/custom_components/midea_ac_lan/midea/devices/ac/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/ac/device.py
@@ -1,20 +1,23 @@
-import logging
import json
+import logging
+
from .message import (
- MessageQuery,
- MessageToggleDisplay,
- MessageNewProtocolQuery,
MessageACResponse,
MessageGeneralSet,
+ MessageNewProtocolQuery,
MessageNewProtocolSet,
MessagePowerQuery,
+ MessageQuery,
MessageSubProtocolQuery,
- MessageSubProtocolSet
+ MessageSubProtocolSet,
+ MessageToggleDisplay,
)
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -58,22 +61,27 @@ class DeviceAttributes(StrEnum):
class MideaACDevice(MiedaDevice):
_fresh_air_fan_speeds = {
- 0: "Off", 20: "Silent", 40: "Low", 60: "Medium", 80: "High", 100: "Full"
+ 0: "Off",
+ 20: "Silent",
+ 40: "Low",
+ 60: "Medium",
+ 80: "High",
+ 100: "Full",
}
_fresh_air_fan_speeds_rev = dict(reversed(_fresh_air_fan_speeds.items()))
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -120,7 +128,8 @@ def __init__(
DeviceAttributes.fresh_air_mode: None,
DeviceAttributes.fresh_air_1: None,
DeviceAttributes.fresh_air_2: None,
- })
+ },
+ )
self._fresh_air_version = None
self._default_temperature_step = 0.5
self._temperature_step = None
@@ -144,12 +153,12 @@ def build_query(self):
return [
MessageSubProtocolQuery(self._protocol_version, 0x10),
MessageSubProtocolQuery(self._protocol_version, 0x11),
- MessageSubProtocolQuery(self._protocol_version, 0x30)
+ MessageSubProtocolQuery(self._protocol_version, 0x30),
]
return [
MessageQuery(self._protocol_version),
MessageNewProtocolQuery(self._protocol_version),
- MessagePowerQuery(self._protocol_version)
+ MessagePowerQuery(self._protocol_version),
]
def process_message(self, msg):
@@ -179,9 +188,13 @@ def process_message(self, msg):
self._attributes[DeviceAttributes.fresh_air_mode] = v
else:
self._attributes[DeviceAttributes.fresh_air_mode] = "Off"
- new_status[DeviceAttributes.fresh_air_mode.value] = self._attributes[DeviceAttributes.fresh_air_mode]
- if not self._attributes[DeviceAttributes.power] or \
- (DeviceAttributes.swing_vertical in new_status and self._attributes[DeviceAttributes.swing_vertical]):
+ new_status[DeviceAttributes.fresh_air_mode.value] = self._attributes[
+ DeviceAttributes.fresh_air_mode
+ ]
+ if not self._attributes[DeviceAttributes.power] or (
+ DeviceAttributes.swing_vertical in new_status
+ and self._attributes[DeviceAttributes.swing_vertical]
+ ):
self._attributes[DeviceAttributes.indirect_wind] = False
new_status[DeviceAttributes.indirect_wind.value] = False
if not self._attributes[DeviceAttributes.power]:
@@ -198,7 +211,9 @@ def make_message_set(self):
message.power = self._attributes[DeviceAttributes.power]
message.prompt_tone = self._attributes[DeviceAttributes.prompt_tone]
message.mode = self._attributes[DeviceAttributes.mode]
- message.target_temperature = self._attributes[DeviceAttributes.target_temperature]
+ message.target_temperature = self._attributes[
+ DeviceAttributes.target_temperature
+ ]
message.fan_speed = self._attributes[DeviceAttributes.fan_speed]
message.swing_vertical = self._attributes[DeviceAttributes.swing_vertical]
message.swing_horizontal = self._attributes[DeviceAttributes.swing_horizontal]
@@ -220,7 +235,9 @@ def make_subptotocol_message_set(self):
message.prompt_tone = self._attributes[DeviceAttributes.prompt_tone]
message.aux_heating = self._attributes[DeviceAttributes.aux_heating]
message.mode = self._attributes[DeviceAttributes.mode]
- message.target_temperature = self._attributes[DeviceAttributes.target_temperature]
+ message.target_temperature = self._attributes[
+ DeviceAttributes.target_temperature
+ ]
message.fan_speed = self._attributes[DeviceAttributes.fan_speed]
message.boost_mode = self._attributes[DeviceAttributes.boost_mode]
message.dry = self._attributes[DeviceAttributes.dry]
@@ -240,13 +257,15 @@ def make_message_uniq_set(self):
def set_attribute(self, attr, value):
# if nat a sensor
message = None
- if attr not in [DeviceAttributes.indoor_temperature,
- DeviceAttributes.outdoor_temperature,
- DeviceAttributes.indoor_humidity,
- DeviceAttributes.full_dust,
- DeviceAttributes.total_energy_consumption,
- DeviceAttributes.current_energy_consumption,
- DeviceAttributes.realtime_power]:
+ if attr not in [
+ DeviceAttributes.indoor_temperature,
+ DeviceAttributes.outdoor_temperature,
+ DeviceAttributes.indoor_humidity,
+ DeviceAttributes.full_dust,
+ DeviceAttributes.total_energy_consumption,
+ DeviceAttributes.current_energy_consumption,
+ DeviceAttributes.realtime_power,
+ ]:
if attr == DeviceAttributes.prompt_tone:
self._attributes[DeviceAttributes.prompt_tone] = value
self.update_all({DeviceAttributes.prompt_tone.value: value})
@@ -254,9 +273,9 @@ def set_attribute(self, attr, value):
message = MessageToggleDisplay(self._protocol_version)
message.prompt_tone = self._attributes[DeviceAttributes.prompt_tone]
elif attr in [
- DeviceAttributes.indirect_wind,
- DeviceAttributes.breezeless,
- DeviceAttributes.screen_display_alternate
+ DeviceAttributes.indirect_wind,
+ DeviceAttributes.breezeless,
+ DeviceAttributes.screen_display_alternate,
]:
message = MessageNewProtocolSet(self._protocol_version)
setattr(message, str(attr), value)
@@ -267,38 +286,42 @@ def set_attribute(self, attr, value):
setattr(
message,
str(self._fresh_air_version),
- [value, self._attributes[DeviceAttributes.fresh_air_fan_speed]]
+ [value, self._attributes[DeviceAttributes.fresh_air_fan_speed]],
)
elif attr == DeviceAttributes.fresh_air_mode:
if value in MideaACDevice._fresh_air_fan_speeds.values():
speed = list(MideaACDevice._fresh_air_fan_speeds.keys())[
list(MideaACDevice._fresh_air_fan_speeds.values()).index(value)
]
- fresh_air = [True, speed] if speed > 0 else \
- [False, self._attributes[DeviceAttributes.fresh_air_fan_speed]]
- message = MessageNewProtocolSet(self._protocol_version)
- setattr(
- message,
- str(self._fresh_air_version),
- fresh_air
+ fresh_air = (
+ [True, speed]
+ if speed > 0
+ else [
+ False,
+ self._attributes[DeviceAttributes.fresh_air_fan_speed],
+ ]
)
+ message = MessageNewProtocolSet(self._protocol_version)
+ setattr(message, str(self._fresh_air_version), fresh_air)
elif not value:
message = MessageNewProtocolSet(self._protocol_version)
setattr(
message,
str(self._fresh_air_version),
- [False, self._attributes[DeviceAttributes.fresh_air_fan_speed]]
+ [False, self._attributes[DeviceAttributes.fresh_air_fan_speed]],
)
elif attr == DeviceAttributes.fresh_air_fan_speed:
if self._fresh_air_version is not None:
message = MessageNewProtocolSet(self._protocol_version)
- fresh_air = [True, value] if value > 0 else \
- [False, self._attributes[DeviceAttributes.fresh_air_fan_speed]]
- setattr(
- message,
- str(self._fresh_air_version),
- fresh_air
+ fresh_air = (
+ [True, value]
+ if value > 0
+ else [
+ False,
+ self._attributes[DeviceAttributes.fresh_air_fan_speed],
+ ]
)
+ setattr(message, str(self._fresh_air_version), fresh_air)
elif attr in self._attributes.keys():
message = self.make_message_uniq_set()
if attr in [
@@ -306,7 +329,7 @@ def set_attribute(self, attr, value):
DeviceAttributes.sleep_mode,
DeviceAttributes.frost_protect,
DeviceAttributes.comfort_mode,
- DeviceAttributes.eco_mode
+ DeviceAttributes.eco_mode,
]:
message.boost_mode = False
message.sleep_mode = False
diff --git a/custom_components/midea_ac_lan/midea/devices/ac/message.py b/custom_components/midea_ac_lan/midea/devices/ac/message.py
index 96037f1b..9c5816b3 100644
--- a/custom_components/midea_ac_lan/midea/devices/ac/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/ac/message.py
@@ -1,12 +1,13 @@
from enum import IntEnum
+
+from ...core.crc8 import calculate
from ...core.message import (
- MessageType,
+ MessageBody,
MessageRequest,
MessageResponse,
- MessageBody,
- NewProtocolMessageBody
+ MessageType,
+ NewProtocolMessageBody,
)
-from ...core.crc8 import calculate
BB_AC_MODES = [0, 3, 1, 2, 4, 5]
@@ -18,7 +19,7 @@ class NewProtocolTags(IntEnum):
prompt_tone = 0x001A
indirect_wind = 0x0042
fresh_air_1 = 0x0233
- fresh_air_2 = 0x004b
+ fresh_air_2 = 0x004B
class MessageACBase(MessageRequest):
@@ -29,7 +30,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xAC,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
MessageACBase._message_serial += 1
if MessageACBase._message_serial >= 254:
@@ -52,17 +53,34 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x41)
+ body_type=0x41,
+ )
@property
def _body(self):
- return bytearray([
- 0x81, 0x00, 0xFF, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- ])
+ return bytearray(
+ [
+ 0x81,
+ 0x00,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessagePowerQuery(MessageACBase):
@@ -70,13 +88,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x41)
+ body_type=0x41,
+ )
@property
def _body(self):
- return bytearray([
- 0x21, 0x01, 0x44, 0x00, 0x01
- ])
+ return bytearray([0x21, 0x01, 0x44, 0x00, 0x01])
@property
def body(self):
@@ -90,20 +107,36 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x41)
+ body_type=0x41,
+ )
self.prompt_tone = False
@property
def _body(self):
prompt_tone = 0x40 if self.prompt_tone else 0
- return bytearray([
- 0x02 | prompt_tone,
- 0x00, 0xFF, 0x02,
- 0x00, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
- ])
+ return bytearray(
+ [
+ 0x02 | prompt_tone,
+ 0x00,
+ 0xFF,
+ 0x02,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessageNewProtocolQuery(MessageACBase):
@@ -111,7 +144,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0xB1)
+ body_type=0xB1,
+ )
@property
def _body(self):
@@ -121,7 +155,7 @@ def _body(self):
NewProtocolTags.indoor_humidity,
NewProtocolTags.screen_display,
NewProtocolTags.fresh_air_1,
- NewProtocolTags.fresh_air_2
+ NewProtocolTags.fresh_air_2,
]
_body = bytearray([len(query_params)])
@@ -133,9 +167,8 @@ def _body(self):
class MessageSubProtocol(MessageACBase):
def __init__(self, protocol_version, message_type, subprotocol_query_type):
super().__init__(
- protocol_version=protocol_version,
- message_type=message_type,
- body_type=0xAA)
+ protocol_version=protocol_version, message_type=message_type, body_type=0xAA
+ )
self._subprotocol_query_type = subprotocol_query_type
@property
@@ -152,10 +185,17 @@ def body(self):
@property
def _body(self):
_subprotocol_body = self._subprotocol_body
- _body = bytearray([
- 6 + 2 + (len(_subprotocol_body) if _subprotocol_body is not None else 0),
- 0x00, 0xFF, 0xFF, self._subprotocol_query_type
- ])
+ _body = bytearray(
+ [
+ 6
+ + 2
+ + (len(_subprotocol_body) if _subprotocol_body is not None else 0),
+ 0x00,
+ 0xFF,
+ 0xFF,
+ self._subprotocol_query_type,
+ ]
+ )
if _subprotocol_body is not None:
_body.extend(_subprotocol_body)
return _body
@@ -166,7 +206,8 @@ def __init__(self, protocol_version, subprotocol_query_type):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- subprotocol_query_type=subprotocol_query_type)
+ subprotocol_query_type=subprotocol_query_type,
+ )
class MessageSubProtocolSet(MessageSubProtocol):
@@ -174,7 +215,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- subprotocol_query_type=0x20)
+ subprotocol_query_type=0x20,
+ )
self.power = False
self.mode = 0
self.target_temperature = 20.0
@@ -206,18 +248,47 @@ def _subprotocol_body(self):
prompt_tone = 0x01 if self.prompt_tone else 0
timer = 0x04 if (self.sn8_flag and self.timer) else 0
- return bytearray([
- 0x02 | boost_mode | power | dry, aux_heating, sleep_mode, 0x00,
- 0x00, mode, target_temperature, fan_speed,
- 0x32, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x00, 0x01, water_model_temperature_set,
- prompt_tone, target_temperature, 0x32, 0x66,
- 0x00, eco | timer, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x08
- ])
+ return bytearray(
+ [
+ 0x02 | boost_mode | power | dry,
+ aux_heating,
+ sleep_mode,
+ 0x00,
+ 0x00,
+ mode,
+ target_temperature,
+ fan_speed,
+ 0x32,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x01,
+ 0x01,
+ 0x00,
+ 0x01,
+ water_model_temperature_set,
+ prompt_tone,
+ target_temperature,
+ 0x32,
+ 0x66,
+ 0x00,
+ eco | timer,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x08,
+ ]
+ )
class MessageGeneralSet(MessageACBase):
@@ -225,7 +296,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x40)
+ body_type=0x40,
+ )
self.power = False
self.prompt_tone = True
self.mode = 0
@@ -250,14 +322,18 @@ def _body(self):
power = 0x01 if self.power else 0
prompt_tone = 0x40 if self.prompt_tone else 0
# Byte2, mode target_temperature
- mode = (self.mode << 5) & 0xe0
- target_temperature = (int(self.target_temperature) & 0xf) | \
- (0x10 if int(round(self.target_temperature * 2)) % 2 != 0 else 0)
+ mode = (self.mode << 5) & 0xE0
+ target_temperature = (int(self.target_temperature) & 0xF) | (
+ 0x10 if int(round(self.target_temperature * 2)) % 2 != 0 else 0
+ )
# Byte 3, fan_speed
- fan_speed = self.fan_speed & 0x7f
+ fan_speed = self.fan_speed & 0x7F
# Byte 7, swing_mode
- swing_mode = 0x30 | (0x0c if self.swing_vertical else 0) \
+ swing_mode = (
+ 0x30
+ | (0x0C if self.swing_vertical else 0)
| (0x03 if self.swing_horizontal else 0)
+ )
# Byte 8, turbo
boost_mode = 0x20 if self.boost_mode else 0
# Byte 9 aux_heating eco_mode
@@ -276,22 +352,32 @@ def _body(self):
# Byte 22 comfort_mode
comfort_mode = 0x01 if self.comfort_mode else 0
- return bytearray([
- power | prompt_tone,
- mode | target_temperature,
- fan_speed,
- 0x00, 0x00, 0x00,
- swing_mode,
- boost_mode,
- smart_eye | dry | aux_heating | eco_mode,
- temp_fahrenheit | sleep_mode | boost_mode_1,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- natural_wind,
- 0x00, 0x00, 0x00,
- frost_protect,
- comfort_mode
- ])
+ return bytearray(
+ [
+ power | prompt_tone,
+ mode | target_temperature,
+ fan_speed,
+ 0x00,
+ 0x00,
+ 0x00,
+ swing_mode,
+ boost_mode,
+ smart_eye | dry | aux_heating | eco_mode,
+ temp_fahrenheit | sleep_mode | boost_mode_1,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ natural_wind,
+ 0x00,
+ 0x00,
+ 0x00,
+ frost_protect,
+ comfort_mode,
+ ]
+ )
class MessageNewProtocolSet(MessageACBase):
@@ -299,7 +385,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0xB0)
+ body_type=0xB0,
+ )
self.indirect_wind = None
self.prompt_tone = None
self.breezeless = None
@@ -316,29 +403,33 @@ def _body(self):
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.breezeless,
- value=bytearray([0x01 if self.breezeless else 0x00])
- ))
+ value=bytearray([0x01 if self.breezeless else 0x00]),
+ )
+ )
if self.indirect_wind is not None:
pack_count += 1
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.indirect_wind,
- value=bytearray([0x02 if self.indirect_wind else 0x01])
- ))
+ value=bytearray([0x02 if self.indirect_wind else 0x01]),
+ )
+ )
if self.prompt_tone is not None:
pack_count += 1
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.prompt_tone,
- value=bytearray([0x01 if self.prompt_tone else 0x00])
- ))
+ value=bytearray([0x01 if self.prompt_tone else 0x00]),
+ )
+ )
if self.screen_display_alternate is not None:
pack_count += 1
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.screen_display,
- value=bytearray([0x64 if self.screen_display_alternate else 0x00])
- ))
+ value=bytearray([0x64 if self.screen_display_alternate else 0x00]),
+ )
+ )
if self.fresh_air_1 is not None and len(self.fresh_air_1) == 2:
pack_count += 1
fresh_air_power = 2 if self.fresh_air_1[0] > 0 else 1
@@ -346,13 +437,22 @@ def _body(self):
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.fresh_air_1,
- value=bytearray([
- fresh_air_power,
- fresh_air_fan_speed,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- ])
- ))
+ value=bytearray(
+ [
+ fresh_air_power,
+ fresh_air_fan_speed,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ ),
+ )
+ )
if self.fresh_air_2 is not None and len(self.fresh_air_2) == 2:
pack_count += 1
fresh_air_power = 1 if self.fresh_air_2[0] > 0 else 0
@@ -360,12 +460,9 @@ def _body(self):
payload.extend(
NewProtocolMessageBody.pack(
param=NewProtocolTags.fresh_air_2,
- value=bytearray([
- fresh_air_power,
- fresh_air_fan_speed,
- 0xFF
- ])
- ))
+ value=bytearray([fresh_air_power, fresh_air_fan_speed, 0xFF]),
+ )
+ )
payload[0] = pack_count
return payload
@@ -374,9 +471,11 @@ class XA0MessageBody(MessageBody):
def __init__(self, body):
super().__init__(body)
self.power = (body[1] & 0x1) > 0
- self.target_temperature = ((body[1] & 0x3E) >> 1) - 4 + 16.0 + (0.5 if body[1] & 0x40 > 0 else 0.0)
- self.mode = (body[2] & 0xe0) >> 5
- self.fan_speed = body[3] & 0x7f
+ self.target_temperature = (
+ ((body[1] & 0x3E) >> 1) - 4 + 16.0 + (0.5 if body[1] & 0x40 > 0 else 0.0)
+ )
+ self.mode = (body[2] & 0xE0) >> 5
+ self.fan_speed = body[3] & 0x7F
self.swing_vertical = (body[7] & 0xC) > 0
self.swing_horizontal = (body[7] & 0x3) > 0
self.boost_mode = ((body[8] & 0x20) > 0) or ((body[10] & 0x2) > 0)
@@ -417,13 +516,15 @@ def __init__(self, body, bt):
super().__init__(body, bt)
params = self.parse()
if NewProtocolTags.indirect_wind in params:
- self.indirect_wind = (params[NewProtocolTags.indirect_wind][0] == 0x02)
+ self.indirect_wind = params[NewProtocolTags.indirect_wind][0] == 0x02
if NewProtocolTags.indoor_humidity in params:
self.indoor_humidity = params[NewProtocolTags.indoor_humidity][0]
if NewProtocolTags.breezeless in params:
- self.breezeless = (params[NewProtocolTags.breezeless][0] == 1)
+ self.breezeless = params[NewProtocolTags.breezeless][0] == 1
if NewProtocolTags.screen_display in params:
- self.screen_display_alternate = (params[NewProtocolTags.screen_display][0] > 0)
+ self.screen_display_alternate = (
+ params[NewProtocolTags.screen_display][0] > 0
+ )
self.screen_display_new = True
if NewProtocolTags.fresh_air_1 in params:
self.fresh_air_1 = True
@@ -441,8 +542,10 @@ class XC0MessageBody(MessageBody):
def __init__(self, body):
super().__init__(body)
self.power = (body[1] & 0x1) > 0
- self.mode = (body[2] & 0xe0) >> 5
- self.target_temperature = (body[2] & 0x0F) + 16.0 + (0.5 if body[0x02] & 0x10 > 0 else 0.0)
+ self.mode = (body[2] & 0xE0) >> 5
+ self.target_temperature = (
+ (body[2] & 0x0F) + 16.0 + (0.5 if body[0x02] & 0x10 > 0 else 0.0)
+ )
self.fan_speed = body[3] & 0x7F
self.swing_vertical = (body[7] & 0x0C) > 0
self.swing_horizontal = (body[7] & 0x03) > 0
@@ -481,16 +584,13 @@ def __init__(self, body, analysis_method=3):
super().__init__(body)
if body[3] == 0x44:
self.total_energy_consumption = XC1MessageBody.parse_consumption(
- analysis_method,
- body[4], body[5], body[6], body[7]
+ analysis_method, body[4], body[5], body[6], body[7]
)
self.current_energy_consumption = XC1MessageBody.parse_consumption(
- analysis_method,
- body[12], body[13], body[14], body[15]
+ analysis_method, body[12], body[13], body[14], body[15]
)
self.realtime_power = XC1MessageBody.parse_power(
- analysis_method,
- body[16], body[17], body[18]
+ analysis_method, body[16], body[17], body[18]
)
elif body[3] == 0x40:
pass
@@ -502,9 +602,14 @@ def parse_value(byte):
@staticmethod
def parse_power(analysis_method, byte1, byte2, byte3):
if analysis_method == 1:
- return float(XC1MessageBody.parse_value(byte1) * 10000 +
- XC1MessageBody.parse_value(byte2) * 100 +
- XC1MessageBody.parse_value(byte3)) / 10
+ return (
+ float(
+ XC1MessageBody.parse_value(byte1) * 10000
+ + XC1MessageBody.parse_value(byte2) * 100
+ + XC1MessageBody.parse_value(byte3)
+ )
+ / 10
+ )
elif analysis_method == 2:
return float((byte1 << 16) + (byte2 << 8) + byte3) / 10
else:
@@ -513,10 +618,15 @@ def parse_power(analysis_method, byte1, byte2, byte3):
@staticmethod
def parse_consumption(analysis_method, byte1, byte2, byte3, byte4):
if analysis_method == 1:
- return float(XC1MessageBody.parse_value(byte1) * 1000000 +
- XC1MessageBody.parse_value(byte2) * 10000 +
- XC1MessageBody.parse_value(byte3) * 100 +
- XC1MessageBody.parse_value(byte4)) / 100
+ return (
+ float(
+ XC1MessageBody.parse_value(byte1) * 1000000
+ + XC1MessageBody.parse_value(byte2) * 10000
+ + XC1MessageBody.parse_value(byte3) * 100
+ + XC1MessageBody.parse_value(byte4)
+ )
+ / 100
+ )
elif analysis_method == 2:
return float((byte1 << 32) + (byte2 << 16) + (byte3 << 8) + byte4) / 10
else:
@@ -542,22 +652,40 @@ def __init__(self, body):
self.mode = 0
self.target_temperature = (subprotocol_body[6] - 30) / 2
self.fan_speed = subprotocol_body[7]
- self.timer = (subprotocol_body[25] & 0x04) > 0 if subprotocol_body_len > 27 else False
- self.eco_mode = (subprotocol_body[25] & 0x40) > 0 if subprotocol_body_len > 27 else False
+ self.timer = (
+ (subprotocol_body[25] & 0x04) > 0
+ if subprotocol_body_len > 27
+ else False
+ )
+ self.eco_mode = (
+ (subprotocol_body[25] & 0x40) > 0
+ if subprotocol_body_len > 27
+ else False
+ )
elif data_type == 0x10:
if subprotocol_body[8] & 0x80 == 0x80:
- self.indoor_temperature = (0 - (~(subprotocol_body[7] + subprotocol_body[8] * 256) + 1) & 0xffff) / 100
+ self.indoor_temperature = (
+ 0 - (~(subprotocol_body[7] + subprotocol_body[8] * 256) + 1)
+ & 0xFFFF
+ ) / 100
else:
- self.indoor_temperature = (subprotocol_body[7] + subprotocol_body[8] * 256) / 100
+ self.indoor_temperature = (
+ subprotocol_body[7] + subprotocol_body[8] * 256
+ ) / 100
self.indoor_humidity = subprotocol_body[30]
self.sn8_flag = subprotocol_body[80] == 0x31
elif data_type == 0x12:
pass
elif data_type == 0x30:
if subprotocol_body[6] & 0x80 == 0x80:
- self.outdoor_temperature = (0 - (~(subprotocol_body[5] + subprotocol_body[6] * 256) + 1) & 0xffff) / 100
+ self.outdoor_temperature = (
+ 0 - (~(subprotocol_body[5] + subprotocol_body[6] * 256) + 1)
+ & 0xFFFF
+ ) / 100
else:
- self.outdoor_temperature = (subprotocol_body[5] + subprotocol_body[6] * 256) / 100
+ self.outdoor_temperature = (
+ subprotocol_body[5] + subprotocol_body[6] * 256
+ ) / 100
elif data_type == 0x13 or data_type == 0x21:
pass
@@ -569,15 +697,25 @@ def __init__(self, message, power_analysis_method=3):
self.set_body(XA0MessageBody(super().body))
elif self.message_type == MessageType.notify1 and self.body_type == 0xA1:
self.set_body(XA1MessageBody(super().body))
- elif self.message_type in [MessageType.query, MessageType.set, MessageType.notify2] and \
- self.body_type in [0xB0, 0xB1, 0xB5]:
+ elif self.message_type in [
+ MessageType.query,
+ MessageType.set,
+ MessageType.notify2,
+ ] and self.body_type in [0xB0, 0xB1, 0xB5]:
self.set_body(XBXMessageBody(super().body, self.body_type))
- elif self.message_type in [MessageType.query, MessageType.set] and self.body_type == 0xC0:
+ elif (
+ self.message_type in [MessageType.query, MessageType.set]
+ and self.body_type == 0xC0
+ ):
self.set_body(XC0MessageBody(super().body))
elif self.message_type == MessageType.query and self.body_type == 0xC1:
self.set_body(XC1MessageBody(super().body, power_analysis_method))
- elif self.message_type in [MessageType.set, MessageType.query, MessageType.notify2] and \
- self.body_type == 0xBB and len(super().body) >= 21:
+ elif (
+ self.message_type
+ in [MessageType.set, MessageType.query, MessageType.notify2]
+ and self.body_type == 0xBB
+ and len(super().body) >= 21
+ ):
self.used_subprotocol = True
self.set_body(XBBMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/b0/device.py b/custom_components/midea_ac_lan/midea/devices/b0/device.py
index c1f5f6ec..8de17bf5 100644
--- a/custom_components/midea_ac_lan/midea/devices/b0/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/b0/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery01,
- MessageB0Response
-)
+
+from .message import MessageB0Response, MessageQuery01
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,22 +24,26 @@ class DeviceAttributes(StrEnum):
class MideaB0Device(MiedaDevice):
_status = {
- 0x01: "Standby", 0x02: "Idle", 0x03: "Working",
- 0x04: "Finished", 0x05: "Delay", 0x06: "Paused"
+ 0x01: "Standby",
+ 0x02: "Idle",
+ 0x03: "Working",
+ 0x04: "Finished",
+ 0x05: "Delay",
+ 0x06: "Paused",
}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -60,7 +64,8 @@ def __init__(
DeviceAttributes.tank_ejected: False,
DeviceAttributes.water_change_reminder: False,
DeviceAttributes.water_shortage: False,
- })
+ },
+ )
def build_query(self):
return [MessageQuery01(self._protocol_version)]
@@ -74,7 +79,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.status:
if value in MideaB0Device._status.keys():
- self._attributes[DeviceAttributes.status] = MideaB0Device._status.get(value)
+ self._attributes[DeviceAttributes.status] = (
+ MideaB0Device._status.get(value)
+ )
else:
self._attributes[DeviceAttributes.status] = None
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/b0/message.py b/custom_components/midea_ac_lan/midea/devices/b0/message.py
index 8dc4d0ce..ebed3bdd 100644
--- a/custom_components/midea_ac_lan/midea/devices/b0/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/b0/message.py
@@ -1,18 +1,13 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageB0Base(MessageRequest):
- def __init__(self, protocol_version, message_type, body_type):
+ def __init__(self, protocol_version, message_type, body_type):
super().__init__(
device_type=0xB0,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x00)
+ body_type=0x00,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -60,9 +57,11 @@ def __init__(self, body):
if len(body) > 15:
self.door = (body[32] & 0x02) > 0
self.status = body[31]
- self.time_remaining = (0 if body[22] == 0xFF else body[22]) * 3600 + \
- (0 if body[23] == 0xFF else body[23]) * 60 + \
- (0 if body[24] == 0xFF else body[24])
+ self.time_remaining = (
+ (0 if body[22] == 0xFF else body[22]) * 3600
+ + (0 if body[23] == 0xFF else body[23]) * 60
+ + (0 if body[24] == 0xFF else body[24])
+ )
self.current_temperature = (body[25] << 8) + (body[26])
if self.current_temperature == 0:
self.current_temperature = (body[27] << 8) + body[28]
diff --git a/custom_components/midea_ac_lan/midea/devices/b1/device.py b/custom_components/midea_ac_lan/midea/devices/b1/device.py
index 4f62e6a9..9b78b67c 100644
--- a/custom_components/midea_ac_lan/midea/devices/b1/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/b1/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageB1Response
-)
+
+from .message import MessageB1Response, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,22 +24,26 @@ class DeviceAttributes(StrEnum):
class MideaB1Device(MiedaDevice):
_status = {
- 0x01: "Standby", 0x02: "Idle", 0x03: "Working",
- 0x04: "Finished", 0x05: "Delay", 0x06: "Paused"
+ 0x01: "Standby",
+ 0x02: "Idle",
+ 0x03: "Working",
+ 0x04: "Finished",
+ 0x05: "Delay",
+ 0x06: "Paused",
}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -60,7 +64,8 @@ def __init__(
DeviceAttributes.tank_ejected: False,
DeviceAttributes.water_change_reminder: False,
DeviceAttributes.water_shortage: False,
- })
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -74,7 +79,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.status:
if value in MideaB1Device._status.keys():
- self._attributes[DeviceAttributes.status] = MideaB1Device._status.get(value)
+ self._attributes[DeviceAttributes.status] = (
+ MideaB1Device._status.get(value)
+ )
else:
self._attributes[DeviceAttributes.status] = None
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/b1/message.py b/custom_components/midea_ac_lan/midea/devices/b1/message.py
index 1810e1e8..d7d6fb63 100644
--- a/custom_components/midea_ac_lan/midea/devices/b1/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/b1/message.py
@@ -1,18 +1,13 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageB1Base(MessageRequest):
- def __init__(self, protocol_version, message_type, body_type):
+ def __init__(self, protocol_version, message_type, body_type):
super().__init__(
device_type=0xB1,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x00)
+ body_type=0x00,
+ )
@property
def _body(self):
@@ -37,9 +33,11 @@ def __init__(self, body):
super().__init__(body)
self.door = (body[16] & 0x02) > 0
self.status = body[1]
- self.time_remaining = (0 if body[6] == 0xFF else body[6]) * 3600 + \
- (0 if body[7] == 0xFF else body[7]) * 60 + \
- (0 if body[8] == 0xFF else body[8])
+ self.time_remaining = (
+ (0 if body[6] == 0xFF else body[6]) * 3600
+ + (0 if body[7] == 0xFF else body[7]) * 60
+ + (0 if body[8] == 0xFF else body[8])
+ )
self.current_temperature = body[19]
self.tank_ejected = (body[16] & 0x04) > 0
self.water_shortage = (body[16] & 0x08) > 0
diff --git a/custom_components/midea_ac_lan/midea/devices/b3/device.py b/custom_components/midea_ac_lan/midea/devices/b3/device.py
index 41fe63c9..8894dd19 100644
--- a/custom_components/midea_ac_lan/midea/devices/b3/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/b3/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageB3Response
-)
+
+from .message import MessageB3Response, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -39,22 +39,25 @@ class DeviceAttributes(StrEnum):
class MideaB2Device(MiedaDevice):
_status = {
- 0x00: "Off", 0x01: "Standby", 0x02: "Working",
- 0x03: "Delay", 0x04: "Finished"
+ 0x00: "Off",
+ 0x01: "Standby",
+ 0x02: "Working",
+ 0x03: "Delay",
+ 0x04: "Finished",
}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -90,7 +93,8 @@ def __init__(
DeviceAttributes.bottom_compartment_preheating: False,
DeviceAttributes.bottom_compartment_cooling: False,
DeviceAttributes.lock: False,
- })
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -105,7 +109,7 @@ def process_message(self, msg):
if status in [
DeviceAttributes.top_compartment_status,
DeviceAttributes.middle_compartment_status,
- DeviceAttributes.bottom_compartment_status
+ DeviceAttributes.bottom_compartment_status,
]:
if value in MideaB2Device._status.keys():
self._attributes[status] = MideaB2Device._status.get(value)
diff --git a/custom_components/midea_ac_lan/midea/devices/b3/message.py b/custom_components/midea_ac_lan/midea/devices/b3/message.py
index 8af1d9e6..c06e22a8 100644
--- a/custom_components/midea_ac_lan/midea/devices/b3/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/b3/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageB3Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xB3,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x31)
+ body_type=0x31,
+ )
@property
def _body(self):
@@ -39,25 +35,37 @@ def __init__(self, body):
self.top_compartment_mode = body[2]
self.top_compartment_temperature = body[3]
self.top_compartment_remaining = (
- body[23] * 3600 if len(body) > 23 and body[23] != 0xFF else 0 +
- body[4] * 60 if body[4] != 0xFF else 0 +
- body[5] if body[5] != 0xFF else 0
+ body[23] * 3600
+ if len(body) > 23 and body[23] != 0xFF
+ else (
+ 0 + body[4] * 60
+ if body[4] != 0xFF
+ else 0 + body[5] if body[5] != 0xFF else 0
+ )
)
self.bottom_compartment_status = body[6]
self.bottom_compartment_mode = body[7]
self.bottom_compartment_temperature = body[8]
self.bottom_compartment_remaining = (
- body[24] * 3600 if len(body) > 24 and body[24] != 0xFF else 0 +
- body[9] * 60 if body[9] != 0xFF else 0 +
- body[10] if body[10] != 0xFF else 0
+ body[24] * 3600
+ if len(body) > 24 and body[24] != 0xFF
+ else (
+ 0 + body[9] * 60
+ if body[9] != 0xFF
+ else 0 + body[10] if body[10] != 0xFF else 0
+ )
)
self.middle_compartment_status = body[17]
self.middle_compartment_mode = body[18]
self.middle_compartment_temperature = body[19]
self.middle_compartment_remaining = (
- body[25] * 3600 if len(body) > 25 and body[25] != 0xFF else 0 +
- body[20] * 60 if body[20] != 0xFF else 0 +
- body[21] if body[21] != 0xFF else 0
+ body[25] * 3600
+ if len(body) > 25 and body[25] != 0xFF
+ else (
+ 0 + body[20] * 60
+ if body[20] != 0xFF
+ else 0 + body[21] if body[21] != 0xFF else 0
+ )
)
self.lock = body[11] & 0x01 > 0
self.bottom_compartment_door = body[11] & 0x02 > 0
@@ -78,25 +86,37 @@ def __init__(self, body):
self.top_compartment_mode = body[2]
self.top_compartment_temperature = body[3]
self.top_compartment_remaining = (
- body[17] * 3600 if len(body) > 17 and body[17] != 0xFF else 0 +
- body[4] * 60 if body[4] != 0xFF else 0 +
- body[5] if body[5] != 0xFF else 0
+ body[17] * 3600
+ if len(body) > 17 and body[17] != 0xFF
+ else (
+ 0 + body[4] * 60
+ if body[4] != 0xFF
+ else 0 + body[5] if body[5] != 0xFF else 0
+ )
)
self.bottom_compartment_status = body[6]
self.bottom_compartment_mode = body[7]
self.bottom_compartment_temperature = body[8]
self.bottom_compartment_remaining = (
- body[18] * 3600 if len(body) > 18 and body[18] != 0xFF else 0 +
- body[9] * 60 if body[9] != 0xFF else 0 +
- body[10] if body[10] != 0xFF else 0
+ body[18] * 3600
+ if len(body) > 18 and body[18] != 0xFF
+ else (
+ 0 + body[9] * 60
+ if body[9] != 0xFF
+ else 0 + body[10] if body[10] != 0xFF else 0
+ )
)
self.middle_compartment_status = body[12]
self.middle_compartment_mode = body[13]
self.middle_compartment_temperature = body[14]
self.middle_compartment_remaining = (
- body[19] * 3600 if len(body) > 19 and body[19] != 0xFF else 0 +
- body[15] * 60 if body[15] != 0xFF else 0 +
- body[16] if body[16] != 0xFF else 0
+ body[19] * 3600
+ if len(body) > 19 and body[19] != 0xFF
+ else (
+ 0 + body[15] * 60
+ if body[15] != 0xFF
+ else 0 + body[16] if body[16] != 0xFF else 0
+ )
)
self.lock = body[11] & 0x01 > 0
@@ -108,30 +128,35 @@ def __init__(self, body):
self.top_compartment_mode = body[6]
self.top_compartment_temperature = body[7]
self.top_compartment_remaining = (
- body[8] * 60 if body[8] != 0xFF else 0 +
- body[9] if body[9] != 0xFF else 0
+ body[8] * 60 if body[8] != 0xFF else 0 + body[9] if body[9] != 0xFF else 0
)
self.bottom_compartment_status = body[10]
self.bottom_compartment_mode = body[11]
self.bottom_compartment_temperature = body[12]
self.bottom_compartment_remaining = (
- body[13] * 60 if body[13] != 0xFF else 0 +
- body[14] if body[14] != 0xFF else 0
+ body[13] * 60
+ if body[13] != 0xFF
+ else 0 + body[14] if body[14] != 0xFF else 0
)
self.bottom_compartment_status = body[15]
self.bottom_compartment_mode = body[16]
self.bottom_compartment_temperature = body[17]
self.bottom_compartment_remaining = (
- body[18] * 60 if body[18] != 0xFF else 0 +
- body[19] if body[19] != 0xFF else 0
+ body[18] * 60
+ if body[18] != 0xFF
+ else 0 + body[19] if body[19] != 0xFF else 0
)
class MessageB3Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type == MessageType.query and self.body_type == 0x31 or
- self.message_type == MessageType.notify1 and self.body_type == 0x41):
+ if (
+ self.message_type == MessageType.query
+ and self.body_type == 0x31
+ or self.message_type == MessageType.notify1
+ and self.body_type == 0x41
+ ):
self.set_body(B3MessageBody31(super().body))
elif self.message_type == MessageType.set and self.body_type == 0x21:
self.set_body(B3MessageBody21(super().body))
diff --git a/custom_components/midea_ac_lan/midea/devices/b4/device.py b/custom_components/midea_ac_lan/midea/devices/b4/device.py
index 56e53d67..72824244 100644
--- a/custom_components/midea_ac_lan/midea/devices/b4/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/b4/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageB4Response
-)
+
+from .message import MessageB4Response, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,22 +24,26 @@ class DeviceAttributes(StrEnum):
class MideaB4Device(MiedaDevice):
_status = {
- 0x01: "Standby", 0x02: "Idle", 0x03: "Working",
- 0x04: "Finished", 0x05: "Delay", 0x06: "Paused"
+ 0x01: "Standby",
+ 0x02: "Idle",
+ 0x03: "Working",
+ 0x04: "Finished",
+ 0x05: "Delay",
+ 0x06: "Paused",
}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -60,7 +64,8 @@ def __init__(
DeviceAttributes.tank_ejected: False,
DeviceAttributes.water_change_reminder: False,
DeviceAttributes.water_shortage: False,
- })
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -74,7 +79,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.status:
if value in MideaB4Device._status.keys():
- self._attributes[DeviceAttributes.status] = MideaB4Device._status.get(value)
+ self._attributes[DeviceAttributes.status] = (
+ MideaB4Device._status.get(value)
+ )
else:
self._attributes[DeviceAttributes.status] = None
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/b4/message.py b/custom_components/midea_ac_lan/midea/devices/b4/message.py
index 91f55059..07cc1ee9 100644
--- a/custom_components/midea_ac_lan/midea/devices/b4/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/b4/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageB4Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xB4,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -35,9 +31,11 @@ def _body(self):
class B4MessageBody(MessageBody):
def __init__(self, body):
super().__init__(body)
- self.time_remaining = (0 if body[22] == 0xFF else body[22]) * 3600 + \
- (0 if body[23] == 0xFF else body[23]) * 60 + \
- (0 if body[24] == 0xFF else body[24])
+ self.time_remaining = (
+ (0 if body[22] == 0xFF else body[22]) * 3600
+ + (0 if body[23] == 0xFF else body[23]) * 60
+ + (0 if body[24] == 0xFF else body[24])
+ )
self.current_temperature = (body[25] << 8) + body[26]
if self.current_temperature == 0:
self.current_temperature = (body[27] << 8) + body[28]
@@ -51,7 +49,11 @@ def __init__(self, body):
class MessageB4Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.notify1, MessageType.query, MessageType.set]:
+ if self.message_type in [
+ MessageType.notify1,
+ MessageType.query,
+ MessageType.set,
+ ]:
if self.body_type == 0x01:
self.set_body(B4MessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/b6/device.py b/custom_components/midea_ac_lan/midea/devices/b6/device.py
index c9d68a1d..88b50c12 100644
--- a/custom_components/midea_ac_lan/midea/devices/b6/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/b6/device.py
@@ -1,14 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageB6Response,
- MessageSet
-)
+import logging
+
+from .message import MessageB6Response, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -26,17 +25,17 @@ class DeviceAttributes(StrEnum):
class MideaB6Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -56,11 +55,10 @@ def __init__(
DeviceAttributes.fan_level: 0,
DeviceAttributes.fan_speed: 0,
DeviceAttributes.oilcup_full: False,
- DeviceAttributes.cleaning_reminder: False
- })
- self._default_speeds = {
- 0: "Off", 1: "Level 1", 2: "Level 2"
- }
+ DeviceAttributes.cleaning_reminder: False,
+ },
+ )
+ self._default_speeds = {0: "Off", 1: "Level 1", 2: "Level 2"}
self._default_power_speed = 2
self._power_speed = self._default_power_speed
self._speeds = self._default_speeds
@@ -87,13 +85,21 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.fan_level:
if value in self._speeds.keys():
- self._attributes[DeviceAttributes.mode] = self._speeds.get(value)
- self._attributes[DeviceAttributes.fan_speed] = list(self._speeds.keys()).index(value)
+ self._attributes[DeviceAttributes.mode] = self._speeds.get(
+ value
+ )
+ self._attributes[DeviceAttributes.fan_speed] = list(
+ self._speeds.keys()
+ ).index(value)
else:
self._attributes[DeviceAttributes.mode] = None
self._attributes[DeviceAttributes.fan_speed] = 0
- new_status[DeviceAttributes.mode.value] = self._attributes[DeviceAttributes.mode]
- new_status[DeviceAttributes.fan_speed.value] = self._attributes[DeviceAttributes.fan_speed]
+ new_status[DeviceAttributes.mode.value] = self._attributes[
+ DeviceAttributes.mode
+ ]
+ new_status[DeviceAttributes.fan_speed.value] = self._attributes[
+ DeviceAttributes.fan_speed
+ ]
self._attributes[status] = getattr(message, str(status))
new_status[str(status)] = self._attributes[status]
return new_status
@@ -107,8 +113,9 @@ def set_attribute(self, attr, value):
elif attr == DeviceAttributes.mode:
if value in self._speeds.values():
message = MessageSet(self._protocol_version)
- message.fan_level = \
- list(self._speeds.keys())[list(self._speeds.values()).index(value)]
+ message.fan_level = list(self._speeds.keys())[
+ list(self._speeds.values()).index(value)
+ ]
elif not value:
message = MessageSet(self._protocol_version)
message.power = False
@@ -130,8 +137,9 @@ def turn_on(self, fan_speed=None, mode=None):
else:
message.fan_level = self._power_speed
if mode is not None in self._speeds.values():
- message.fan_level = \
- list(self._speeds.keys())[list(self._speeds.values()).index(mode)]
+ message.fan_level = list(self._speeds.keys())[
+ list(self._speeds.values()).index(mode)
+ ]
self.build_send(message)
def set_customize(self, customize):
@@ -151,7 +159,9 @@ def set_customize(self, customize):
keys = sorted(speeds.keys())
for k in keys:
self._speeds[k] = speeds[k]
- self.update_all({"speeds": self._speeds, "default_speed": self._power_speed})
+ self.update_all(
+ {"speeds": self._speeds, "default_speed": self._power_speed}
+ )
except Exception as e:
_LOGGER.error(f"[{self.device_id}] Set customize error: {repr(e)}")
diff --git a/custom_components/midea_ac_lan/midea/devices/b6/message.py b/custom_components/midea_ac_lan/midea/devices/b6/message.py
index 4ec8010c..53a1b78e 100644
--- a/custom_components/midea_ac_lan/midea/devices/b6/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/b6/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageB6Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xB6,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,7 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x11 if protocol_version == 2 else 0x31
+ body_type=0x11 if protocol_version == 2 else 0x31,
)
@property
@@ -83,10 +78,9 @@ def _body(self):
else:
value2 = 0x02
value3 = self.fan_level
- return bytearray([
- 0x01, light, value2, value3,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
- ])
+ return bytearray(
+ [0x01, light, value2, value3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
+ )
else:
value13 = 0xFF
value14 = 0xFF
@@ -113,10 +107,7 @@ def _body(self):
value13 = 0x02
value14 = 0x02
value15 = 0x01 if self.light else 0x00
- return bytearray([
- 0x01, value13, value14, value15, value16,
- 0xFF, 0xFF
- ])
+ return bytearray([0x01, value13, value14, value15, value16, 0xFF, 0xFF])
class B6FeedbackBody(MessageBody):
@@ -157,7 +148,7 @@ class B6NewProtocolBody(MessageBody):
def __init__(self, body):
super().__init__(body)
if body[1] == 0x01:
- pack_bytes = body[3: 3 + body[2]]
+ pack_bytes = body[3 : 3 + body[2]]
if pack_bytes[1] != 0xFF:
self.power = True
self.power = pack_bytes[1] not in [0x00, 0x01, 0x05, 0x07]
@@ -189,9 +180,17 @@ def __init__(self, body):
class MessageB6Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type == MessageType.set and self.body_type == 0x22 and super().body[1] == 0x01:
+ if (
+ self.message_type == MessageType.set
+ and self.body_type == 0x22
+ and super().body[1] == 0x01
+ ):
self.set_body(B6SpecialBody(super().body))
- elif self.message_type == MessageType.set and self.body_type == 0x11 and super().body[1] == 0x01:
+ elif (
+ self.message_type == MessageType.set
+ and self.body_type == 0x11
+ and super().body[1] == 0x01
+ ):
#############################
pass
elif self.message_type == MessageType.query:
diff --git a/custom_components/midea_ac_lan/midea/devices/bf/device.py b/custom_components/midea_ac_lan/midea/devices/bf/device.py
index 225cba87..d8fe2070 100644
--- a/custom_components/midea_ac_lan/midea/devices/bf/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/bf/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageBFResponse
-)
+
+from .message import MessageBFResponse, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,22 +24,26 @@ class DeviceAttributes(StrEnum):
class MideaBFDevice(MiedaDevice):
_status = {
- 0x01: "PowerSave", 0x02: "Standby", 0x03: "Working",
- 0x04: "Finished", 0x05: "Delay", 0x06: "Paused"
+ 0x01: "PowerSave",
+ 0x02: "Standby",
+ 0x03: "Working",
+ 0x04: "Finished",
+ 0x05: "Delay",
+ 0x06: "Paused",
}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -60,7 +64,8 @@ def __init__(
DeviceAttributes.tank_ejected: None,
DeviceAttributes.water_change_reminder: None,
DeviceAttributes.water_shortage: None,
- })
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -74,7 +79,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.status:
if value in MideaBFDevice._status.keys():
- self._attributes[DeviceAttributes.status] = MideaBFDevice._status.get(value)
+ self._attributes[DeviceAttributes.status] = (
+ MideaBFDevice._status.get(value)
+ )
else:
self._attributes[DeviceAttributes.status] = "Unknown"
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/bf/message.py b/custom_components/midea_ac_lan/midea/devices/bf/message.py
index e40da95b..358ce3eb 100644
--- a/custom_components/midea_ac_lan/midea/devices/bf/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/bf/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageBFBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xBF,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,14 +33,17 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x02)
+ body_type=0x02,
+ )
self.power = None
self.child_lock = None
@property
def _body(self):
power = 0xFF if self.power is None else 0x11 if self.power else 0x01
- child_lock = 0xFF if self.child_lock is None else 0x01 if self.child_lock else 0x00
+ child_lock = (
+ 0xFF if self.child_lock is None else 0x01 if self.child_lock else 0x00
+ )
return bytearray([power, child_lock] + [0xFF] * 7)
@@ -52,9 +51,11 @@ class MessageBFBody(MessageBody):
def __init__(self, body):
super().__init__(body)
self.status = body[31]
- self.time_remaining = (0 if body[22] == 0xFF else body[22]) * 3600 + \
- (0 if body[23] == 0xFF else body[23]) * 60 + \
- (0 if body[24] == 0xFF else body[24])
+ self.time_remaining = (
+ (0 if body[22] == 0xFF else body[22]) * 3600
+ + (0 if body[23] == 0xFF else body[23]) * 60
+ + (0 if body[24] == 0xFF else body[24])
+ )
cur_temperature = body[25] * 256 + body[26]
if cur_temperature == 0:
cur_temperature = body[27] * 256 + body[28]
@@ -69,6 +70,10 @@ def __init__(self, body):
class MessageBFResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.set, MessageType.notify1, MessageType.query] and self.body_type == 0x01:
+ if (
+ self.message_type
+ in [MessageType.set, MessageType.notify1, MessageType.query]
+ and self.body_type == 0x01
+ ):
self.set_body(MessageBFBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/c2/device.py b/custom_components/midea_ac_lan/midea/devices/c2/device.py
index 580f4b98..3e1a0444 100644
--- a/custom_components/midea_ac_lan/midea/devices/c2/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/c2/device.py
@@ -1,15 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageC2Response,
- MessageSet,
- MessagePower
-)
+import logging
+
+from .message import MessageC2Response, MessagePower, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -33,17 +31,17 @@ class DeviceAttributes(StrEnum):
class MideaC2Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -69,8 +67,9 @@ def __init__(
DeviceAttributes.seat_temp_level: 0,
DeviceAttributes.water_temperature: None,
DeviceAttributes.seat_temperature: None,
- DeviceAttributes.filter_life: None
- })
+ DeviceAttributes.filter_life: None,
+ },
+ )
self._max_dry_level = None
self._max_water_temp_level = None
self._max_seat_temp_level = None
@@ -115,7 +114,7 @@ def set_attribute(self, attr, value):
DeviceAttributes.foam_shield,
DeviceAttributes.water_temp_level,
DeviceAttributes.seat_temp_level,
- DeviceAttributes.dry_level
+ DeviceAttributes.dry_level,
]:
message = MessageSet(self._protocol_version)
setattr(message, attr, value)
@@ -137,10 +136,17 @@ def set_customize(self, customize):
self._max_seat_temp_level = params.get("max_seat_temp_level")
except Exception as e:
_LOGGER.error(f"[{self.device_id}] Set customize error: {repr(e)}")
- self.update_all({"dry_level": {"max_dry_level": self._max_dry_level},
- "water_temp_level": {"max_water_temp_level": self._max_water_temp_level},
- "seat_temp_level": {"max_seat_temp_level": self._max_seat_temp_level}
- })
+ self.update_all(
+ {
+ "dry_level": {"max_dry_level": self._max_dry_level},
+ "water_temp_level": {
+ "max_water_temp_level": self._max_water_temp_level
+ },
+ "seat_temp_level": {
+ "max_seat_temp_level": self._max_seat_temp_level
+ },
+ }
+ )
class MideaAppliance(MideaC2Device):
diff --git a/custom_components/midea_ac_lan/midea/devices/c2/message.py b/custom_components/midea_ac_lan/midea/devices/c2/message.py
index 343fa1b3..4ab2c023 100644
--- a/custom_components/midea_ac_lan/midea/devices/c2/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/c2/message.py
@@ -1,10 +1,6 @@
from enum import IntEnum
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class C2MessageEnum(IntEnum):
@@ -12,8 +8,8 @@ class C2MessageEnum(IntEnum):
child_lock = 0x10
foam_shield = 0x1F
water_temp_level = 0x09
- seat_temp_level = 0x0a
- dry_level = 0x0c
+ seat_temp_level = 0x0A
+ dry_level = 0x0C
C2_MESSAGE_KEYS = {
@@ -21,8 +17,22 @@ class C2MessageEnum(IntEnum):
C2MessageEnum.sensor_light: {True: 0x01 << 1, False: 0x00},
C2MessageEnum.foam_shield: {True: 0x01 << 2, False: 0x00},
C2MessageEnum.dry_level: {0: 0x00, 1: 0x01 << 1, 2: 0x02 << 1, 3: 0x03 << 1},
- C2MessageEnum.seat_temp_level: {0: 0x00, 1: 0x01 << 3, 2: 0x02 << 3, 3: 0x03 << 3, 4: 0x04 << 3, 5: 0x05 << 3},
- C2MessageEnum.water_temp_level: {0: 0x00, 1: 0x01, 2: 0x02, 3: 0x03, 4: 0x04, 5: 0x05}
+ C2MessageEnum.seat_temp_level: {
+ 0: 0x00,
+ 1: 0x01 << 3,
+ 2: 0x02 << 3,
+ 3: 0x03 << 3,
+ 4: 0x04 << 3,
+ 5: 0x05 << 3,
+ },
+ C2MessageEnum.water_temp_level: {
+ 0: 0x00,
+ 1: 0x01,
+ 2: 0x02,
+ 3: 0x03,
+ 4: 0x04,
+ 5: 0x05,
+ },
}
@@ -32,7 +42,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xC2,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -45,7 +55,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -57,7 +68,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x00)
+ body_type=0x00,
+ )
self.power = False
@property
@@ -74,7 +86,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
@property
def _body(self):
@@ -86,7 +99,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x00)
+ body_type=0x00,
+ )
self.child_lock = None
self.sensor_light = None
@@ -127,9 +141,9 @@ def __init__(self, body):
super().__init__(body)
self.power = (body[2] & 0x01) > 0
self.seat_status = (body[3] & 0x01) > 0
- self.dry_level = ((body[6] & 0x7E) >> 1)
- self.water_temp_level = (body[9] & 0x07)
- self.seat_temp_level = ((body[9] & 0x38) >> 3)
+ self.dry_level = (body[6] & 0x7E) >> 1
+ self.water_temp_level = body[9] & 0x07
+ self.seat_temp_level = (body[9] & 0x38) >> 3
self.lid_status = (body[12] & 0x40) > 0
self.foam_shield = (body[13] & 0x80) > 0
self.sensor_light = (body[14] & 0x01) > 0
@@ -148,6 +162,10 @@ def __init__(self, body):
class MessageC2Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.notify1, MessageType.query, MessageType.set]:
+ if self.message_type in [
+ MessageType.notify1,
+ MessageType.query,
+ MessageType.set,
+ ]:
self.set_body(C2MessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/c3/device.py b/custom_components/midea_ac_lan/midea/devices/c3/device.py
index 90b41e5a..c513ec4c 100644
--- a/custom_components/midea_ac_lan/midea/devices/c3/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/c3/device.py
@@ -1,15 +1,18 @@
import logging
+
from .message import (
+ MessageC3Response,
MessageQuery,
- MessageSetSilent,
+ MessageSet,
MessageSetECO,
- MessageC3Response,
- MessageSet
+ MessageSetSilent,
)
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -60,17 +63,17 @@ class DeviceAttributes(StrEnum):
class MideaC3Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -123,8 +126,9 @@ def __init__(
DeviceAttributes.status_ibh: None,
DeviceAttributes.total_produced_energy: None,
DeviceAttributes.outdoor_temperature: None,
- DeviceAttributes.error_code: 0
- })
+ DeviceAttributes.error_code: 0,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -137,28 +141,48 @@ def process_message(self, msg):
if hasattr(message, str(status)):
self._attributes[status] = getattr(message, str(status))
new_status[str(status)] = getattr(message, str(status))
- if 'zone_temp_type' in new_status:
+ if "zone_temp_type" in new_status:
for zone in [0, 1]:
- if self._attributes[DeviceAttributes.zone_temp_type][zone]: # Water temp mode
- self._attributes[DeviceAttributes.target_temperature][zone] = \
+ if self._attributes[DeviceAttributes.zone_temp_type][
+ zone
+ ]: # Water temp mode
+ self._attributes[DeviceAttributes.target_temperature][zone] = (
self._attributes[DeviceAttributes.zone_target_temp][zone]
- if self._attributes[DeviceAttributes.mode_auto] == 2: # cooling mode
- self._attributes[DeviceAttributes.temperature_max][zone] = \
- self._attributes[DeviceAttributes.zone_cooling_temp_max][zone]
- self._attributes[DeviceAttributes.temperature_min][zone] = \
- self._attributes[DeviceAttributes.zone_cooling_temp_min][zone]
+ )
+ if (
+ self._attributes[DeviceAttributes.mode_auto] == 2
+ ): # cooling mode
+ self._attributes[DeviceAttributes.temperature_max][zone] = (
+ self._attributes[DeviceAttributes.zone_cooling_temp_max][
+ zone
+ ]
+ )
+ self._attributes[DeviceAttributes.temperature_min][zone] = (
+ self._attributes[DeviceAttributes.zone_cooling_temp_min][
+ zone
+ ]
+ )
elif self._attributes[DeviceAttributes.mode] == 3: # heating mode
- self._attributes[DeviceAttributes.temperature_max][zone] = \
- self._attributes[DeviceAttributes.zone_heating_temp_max][zone]
- self._attributes[DeviceAttributes.temperature_min][zone] = \
- self._attributes[DeviceAttributes.zone_heating_temp_min][zone]
+ self._attributes[DeviceAttributes.temperature_max][zone] = (
+ self._attributes[DeviceAttributes.zone_heating_temp_max][
+ zone
+ ]
+ )
+ self._attributes[DeviceAttributes.temperature_min][zone] = (
+ self._attributes[DeviceAttributes.zone_heating_temp_min][
+ zone
+ ]
+ )
else: # Room temp mode
- self._attributes[DeviceAttributes.target_temperature][zone] = \
+ self._attributes[DeviceAttributes.target_temperature][zone] = (
self._attributes[DeviceAttributes.room_target_temp]
- self._attributes[DeviceAttributes.temperature_max][zone] = \
+ )
+ self._attributes[DeviceAttributes.temperature_max][zone] = (
self._attributes[DeviceAttributes.room_temp_max]
- self._attributes[DeviceAttributes.temperature_min][zone] = \
+ )
+ self._attributes[DeviceAttributes.temperature_min][zone] = (
self._attributes[DeviceAttributes.room_temp_min]
+ )
if self._attributes[DeviceAttributes.zone1_power]:
if self._attributes[DeviceAttributes.zone_temp_type][zone]:
self._attributes[DeviceAttributes.zone1_water_temp_mode] = True
@@ -179,14 +203,18 @@ def process_message(self, msg):
else:
self._attributes[DeviceAttributes.zone2_water_temp_mode] = False
self._attributes[DeviceAttributes.zone2_room_temp_mode] = False
- new_status[DeviceAttributes.zone1_water_temp_mode.value] = \
- self._attributes[DeviceAttributes.zone1_water_temp_mode]
- new_status[DeviceAttributes.zone2_water_temp_mode.value] = \
- self._attributes[DeviceAttributes.zone2_water_temp_mode]
- new_status[DeviceAttributes.zone1_room_temp_mode.value] = \
- self._attributes[DeviceAttributes.zone1_room_temp_mode]
- new_status[DeviceAttributes.zone2_room_temp_mode.value] = \
- self._attributes[DeviceAttributes.zone2_room_temp_mode]
+ new_status[DeviceAttributes.zone1_water_temp_mode.value] = self._attributes[
+ DeviceAttributes.zone1_water_temp_mode
+ ]
+ new_status[DeviceAttributes.zone2_water_temp_mode.value] = self._attributes[
+ DeviceAttributes.zone2_water_temp_mode
+ ]
+ new_status[DeviceAttributes.zone1_room_temp_mode.value] = self._attributes[
+ DeviceAttributes.zone1_room_temp_mode
+ ]
+ new_status[DeviceAttributes.zone2_room_temp_mode.value] = self._attributes[
+ DeviceAttributes.zone2_room_temp_mode
+ ]
return new_status
@@ -217,7 +245,7 @@ def set_attribute(self, attr, value):
DeviceAttributes.disinfect,
DeviceAttributes.fast_dhw,
DeviceAttributes.dhw_target_temp,
- DeviceAttributes.tbh
+ DeviceAttributes.tbh,
]:
message = self.make_message_set()
setattr(message, str(attr), value)
diff --git a/custom_components/midea_ac_lan/midea/devices/c3/message.py b/custom_components/midea_ac_lan/midea/devices/c3/message.py
index f9703572..cd2d4243 100644
--- a/custom_components/midea_ac_lan/midea/devices/c3/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/c3/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageC3Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xC3,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x01)
+ body_type=0x01,
+ )
self.zone1_power = False
self.zone2_power = False
self.dhw_power = False
@@ -66,12 +63,17 @@ def _body(self):
zone1_target_temp = int(self.zone_target_temp[0])
zone2_target_temp = int(self.zone_target_temp[1])
dhw_target_temp = int(self.dhw_target_temp)
- return bytearray([
- zone1_power | zone2_power | dhw_power,
- self.mode, zone1_target_temp, zone2_target_temp,
- dhw_target_temp, room_target_temp,
- zone1_curve | zone2_curve | disinfect | fast_dhw
- ])
+ return bytearray(
+ [
+ zone1_power | zone2_power | dhw_power,
+ self.mode,
+ zone1_target_temp,
+ zone2_target_temp,
+ dhw_target_temp,
+ room_target_temp,
+ zone1_curve | zone2_curve | disinfect | fast_dhw,
+ ]
+ )
class MessageSetSilent(MessageC3Base):
@@ -79,7 +81,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x05)
+ body_type=0x05,
+ )
self.silent_mode = False
self.super_silent = False
@@ -88,11 +91,9 @@ def _body(self):
silent_mode = 0x01 if self.silent_mode else 0
super_silent = 0x02 if self.super_silent else 0
- return bytearray([
- silent_mode | super_silent,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- ])
+ return bytearray(
+ [silent_mode | super_silent, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
+ )
class MessageSetECO(MessageC3Base):
@@ -100,18 +101,15 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x07)
+ body_type=0x07,
+ )
self.eco_mode = False
@property
def _body(self):
eco_mode = 0x01 if self.eco_mode else 0
- return bytearray([
- eco_mode,
- 0x00, 0x00, 0x00, 0x00,
- 0x00
- ])
+ return bytearray([eco_mode, 0x00, 0x00, 0x00, 0x00, 0x00])
class C3MessageBody(MessageBody):
@@ -127,34 +125,19 @@ def __init__(self, body, data_offset=0):
self.fast_dhw = body[data_offset + 0] & 0x40 > 0
self.zone_temp_type = [
body[data_offset + 1] & 0x10 > 0,
- body[data_offset + 1] & 0x20 > 0
+ body[data_offset + 1] & 0x20 > 0,
]
self.silent_mode = body[data_offset + 2] & 0x02 > 0
self.eco_mode = body[data_offset + 2] & 0x08 > 0
self.mode = body[data_offset + 3]
self.mode_auto = body[data_offset + 4]
- self.zone_target_temp = [
- body[data_offset + 5],
- body[data_offset + 6]
- ]
+ self.zone_target_temp = [body[data_offset + 5], body[data_offset + 6]]
self.dhw_target_temp = body[data_offset + 7]
self.room_target_temp = body[data_offset + 8] / 2
- self.zone_heating_temp_max = [
- body[data_offset + 9],
- body[data_offset + 13]
- ]
- self.zone_heating_temp_min = [
- body[data_offset + 10],
- body[data_offset + 14]
- ]
- self.zone_cooling_temp_max = [
- body[data_offset + 11],
- body[data_offset + 15]
- ]
- self.zone_cooling_temp_min = [
- body[data_offset + 12],
- body[data_offset + 16]
- ]
+ self.zone_heating_temp_max = [body[data_offset + 9], body[data_offset + 13]]
+ self.zone_heating_temp_min = [body[data_offset + 10], body[data_offset + 14]]
+ self.zone_cooling_temp_max = [body[data_offset + 11], body[data_offset + 15]]
+ self.zone_cooling_temp_min = [body[data_offset + 12], body[data_offset + 16]]
self.room_temp_max = body[data_offset + 17] / 2
self.room_temp_min = body[data_offset + 18] / 2
self.dhw_temp_max = body[data_offset + 19]
@@ -173,24 +156,29 @@ def __init__(self, body, data_offset=0):
self.status_heating = (status_byte & 0x01) > 0
self.total_energy_consumption = (
- (body[data_offset + 1] << 32) +
- (body[data_offset + 2] << 16) +
- (body[data_offset + 3] << 8) +
- (body[data_offset + 4]))
+ (body[data_offset + 1] << 32)
+ + (body[data_offset + 2] << 16)
+ + (body[data_offset + 3] << 8)
+ + (body[data_offset + 4])
+ )
self.total_produced_energy = (
- (body[data_offset + 5] << 32) +
- (body[data_offset + 6] << 16) +
- (body[data_offset + 7] << 8) +
- (body[data_offset + 8]))
+ (body[data_offset + 5] << 32)
+ + (body[data_offset + 6] << 16)
+ + (body[data_offset + 7] << 8)
+ + (body[data_offset + 8])
+ )
self.outdoor_temperature = int(body[data_offset + 9])
class MessageC3Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type in [MessageType.set, MessageType.notify1, MessageType.query]
- and self.body_type == 0x01) or self.message_type == MessageType.notify2:
+ if (
+ self.message_type
+ in [MessageType.set, MessageType.notify1, MessageType.query]
+ and self.body_type == 0x01
+ ) or self.message_type == MessageType.notify2:
self.set_body(C3MessageBody(super().body, data_offset=1))
elif self.message_type == MessageType.notify1 and self.body_type == 0x04:
self.set_body(C3Notify1MessageBody(super().body, data_offset=1))
diff --git a/custom_components/midea_ac_lan/midea/devices/ca/device.py b/custom_components/midea_ac_lan/midea/devices/ca/device.py
index 8d05ad69..f169b4ff 100644
--- a/custom_components/midea_ac_lan/midea/devices/ca/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/ca/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageCAResponse
-)
+
+from .message import MessageCAResponse, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -35,17 +35,17 @@ class DeviceAttributes(StrEnum):
class MideaCADevice(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -75,8 +75,9 @@ def __init__(
DeviceAttributes.refrigerator_door: False,
DeviceAttributes.freezer_door: False,
DeviceAttributes.bar_door: False,
- DeviceAttributes.flex_zone_door: False
- })
+ DeviceAttributes.flex_zone_door: False,
+ },
+ )
self._modes = [""]
def build_query(self):
diff --git a/custom_components/midea_ac_lan/midea/devices/ca/message.py b/custom_components/midea_ac_lan/midea/devices/ca/message.py
index b1284262..0611a875 100644
--- a/custom_components/midea_ac_lan/midea/devices/ca/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/ca/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageCABase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xCA,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x00)
+ body_type=0x00,
+ )
@property
def _body(self):
@@ -35,8 +31,8 @@ def _body(self):
class CAGeneralMessageBody(MessageBody):
def __init__(self, body):
super().__init__(body)
- self.refrigerator_setting_temp = (body[2] & 0x0f)
- self.freezer_setting_temp = -12 - ((body[2] & 0xf0) >> 4)
+ self.refrigerator_setting_temp = body[2] & 0x0F
+ self.freezer_setting_temp = -12 - ((body[2] & 0xF0) >> 4)
flex_zone_setting_temp = body[3]
right_flex_zone_setting_temp = body[4]
@@ -103,14 +99,23 @@ def __init__(self, body):
class MessageCAResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if ((self.message_type in [MessageType.query, MessageType.set] and self.body_type == 0x00) or
- (self.message_type == MessageType.notify1 and self.body_type == 0x02)) and len(super().body) > 20:
+ if (
+ (
+ self.message_type in [MessageType.query, MessageType.set]
+ and self.body_type == 0x00
+ )
+ or (self.message_type == MessageType.notify1 and self.body_type == 0x02)
+ ) and len(super().body) > 20:
self.set_body(CAGeneralMessageBody(super().body))
- elif (self.message_type == MessageType.exception and self.body_type == 0x01) or \
- (self.message_type == 0x03 and self.body_type == 0x02):
+ elif (
+ self.message_type == MessageType.exception and self.body_type == 0x01
+ ) or (self.message_type == 0x03 and self.body_type == 0x02):
self.set_body(CAExceptionMessageBody(super().body))
elif self.message_type == MessageType.notify1 and self.body_type == 0x00:
self.set_body(CANotify00MessageBody(super().body))
- elif self.message_type in [MessageType.query, MessageType.notify1] and self.body_type == 0x01:
+ elif (
+ self.message_type in [MessageType.query, MessageType.notify1]
+ and self.body_type == 0x01
+ ):
self.set_body(CANotify01MessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/cc/device.py b/custom_components/midea_ac_lan/midea/devices/cc/device.py
index a82a5fbe..680a0ec9 100644
--- a/custom_components/midea_ac_lan/midea/devices/cc/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/cc/device.py
@@ -1,13 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageSet,
- MessageCCResponse
-)
+
+from .message import MessageCCResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -34,26 +33,29 @@ class DeviceAttributes(StrEnum):
class MideaCCDevice(MiedaDevice):
_fan_speeds_7level = {
- 0x01: "Level 1", 0x02: "Level 2", 0x04: "Level 3",
- 0x08: "Level 4", 0x10: "Level 5", 0x20: "Level 6",
- 0x40: "Level 7", 0x80: "Auto",
- }
- _fan_speeds_3level = {
- 0x01: "Low", 0x08: "Medium", 0x40: "High", 0x80: "Auto"
+ 0x01: "Level 1",
+ 0x02: "Level 2",
+ 0x04: "Level 3",
+ 0x08: "Level 4",
+ 0x10: "Level 5",
+ 0x20: "Level 6",
+ 0x40: "Level 7",
+ 0x80: "Auto",
}
+ _fan_speeds_3level = {0x01: "Low", 0x08: "Medium", 0x40: "High", 0x80: "Auto"}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -82,8 +84,9 @@ def __init__(
DeviceAttributes.fan_speed_level: None,
DeviceAttributes.indoor_temperature: None,
DeviceAttributes.temperature_precision: 1,
- DeviceAttributes.temp_fahrenheit: False
- })
+ DeviceAttributes.temp_fahrenheit: False,
+ },
+ )
self._fan_speeds = None
@property
@@ -106,32 +109,46 @@ def process_message(self, msg):
else:
self._attributes[status] = getattr(message, str(status))
new_status[str(status)] = getattr(message, str(status))
- if fan_speed is not None and self._attributes[DeviceAttributes.fan_speed_level] is not None:
+ if (
+ fan_speed is not None
+ and self._attributes[DeviceAttributes.fan_speed_level] is not None
+ ):
if self._fan_speeds is None:
if self._attributes[DeviceAttributes.fan_speed_level]:
self._fan_speeds = MideaCCDevice._fan_speeds_3level
else:
self._fan_speeds = MideaCCDevice._fan_speeds_7level
if fan_speed in self._fan_speeds.keys():
- self._attributes[DeviceAttributes.fan_speed] = self._fan_speeds.get(fan_speed)
+ self._attributes[DeviceAttributes.fan_speed] = self._fan_speeds.get(
+ fan_speed
+ )
else:
self._attributes[DeviceAttributes.fan_speed] = None
- new_status[DeviceAttributes.fan_speed.value] = self._attributes[DeviceAttributes.fan_speed]
- aux_heating = \
- self._attributes[DeviceAttributes.aux_heat_status] == 1 or \
- self._attributes[DeviceAttributes.auto_aux_heat_running]
+ new_status[DeviceAttributes.fan_speed.value] = self._attributes[
+ DeviceAttributes.fan_speed
+ ]
+ aux_heating = (
+ self._attributes[DeviceAttributes.aux_heat_status] == 1
+ or self._attributes[DeviceAttributes.auto_aux_heat_running]
+ )
if self._attributes[DeviceAttributes.aux_heating] != aux_heating:
self._attributes[DeviceAttributes.aux_heating] = aux_heating
- new_status[DeviceAttributes.aux_heating.value] = self._attributes[DeviceAttributes.aux_heating]
+ new_status[DeviceAttributes.aux_heating.value] = self._attributes[
+ DeviceAttributes.aux_heating
+ ]
return new_status
def make_message_set(self):
message = MessageSet(self._protocol_version)
message.power = self._attributes[DeviceAttributes.power]
message.mode = self._attributes[DeviceAttributes.mode]
- message.target_temperature = self._attributes[DeviceAttributes.target_temperature]
+ message.target_temperature = self._attributes[
+ DeviceAttributes.target_temperature
+ ]
message.fan_speed = list(self._fan_speeds.keys())[
- list(self._fan_speeds.values()).index(self._attributes[DeviceAttributes.fan_speed])
+ list(self._fan_speeds.values()).index(
+ self._attributes[DeviceAttributes.fan_speed]
+ )
]
message.eco_mode = self._attributes[DeviceAttributes.eco_mode]
message.sleep_mode = self._attributes[DeviceAttributes.sleep_mode]
@@ -150,11 +167,13 @@ def set_target_temperature(self, target_temperature, mode):
def set_attribute(self, attr, value):
# if nat a sensor
- if attr not in [DeviceAttributes.indoor_temperature,
- DeviceAttributes.temperature_precision,
- DeviceAttributes.fan_speed_level,
- DeviceAttributes.aux_heat_status,
- DeviceAttributes.auto_aux_heat_running]:
+ if attr not in [
+ DeviceAttributes.indoor_temperature,
+ DeviceAttributes.temperature_precision,
+ DeviceAttributes.fan_speed_level,
+ DeviceAttributes.aux_heat_status,
+ DeviceAttributes.auto_aux_heat_running,
+ ]:
message = self.make_message_set()
if attr == DeviceAttributes.fan_speed:
if value in self._fan_speeds.values():
diff --git a/custom_components/midea_ac_lan/midea/devices/cc/message.py b/custom_components/midea_ac_lan/midea/devices/cc/message.py
index 7aa35319..f94a7c34 100644
--- a/custom_components/midea_ac_lan/midea/devices/cc/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/cc/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageCCBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xCC,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0xC3)
+ body_type=0xC3,
+ )
self.power = False
self.mode = 4
self.fan_speed = 0x80
@@ -73,23 +70,38 @@ def _body(self):
sleep_mode = 0x10 if self.sleep_mode else 0
night_light = 0x08 if self.night_light else 0
# Byte11 Dot of target_temperature
- temperature_dot = int((self.target_temperature - temperature_integer) * 10) & 0xFF
- return bytearray([
- power | mode,
- fan_speed,
- temperature_integer,
- # timer
- 0x00, 0x00,
- eco_mode | ventilation | swing | aux_heating,
- # non-stepless fan speed
- 0xFF,
- sleep_mode | night_light,
- 0x00, 0x00,
- temperature_dot,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00
- ])
+ temperature_dot = (
+ int((self.target_temperature - temperature_integer) * 10) & 0xFF
+ )
+ return bytearray(
+ [
+ power | mode,
+ fan_speed,
+ temperature_integer,
+ # timer
+ 0x00,
+ 0x00,
+ eco_mode | ventilation | swing | aux_heating,
+ # non-stepless fan speed
+ 0xFF,
+ sleep_mode | night_light,
+ 0x00,
+ 0x00,
+ temperature_dot,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class CCGeneralMessageBody(MessageBody):
@@ -119,8 +131,13 @@ def __init__(self, body):
class MessageCCResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type == MessageType.query and self.body_type == 0x01) or \
- (self.message_type in [MessageType.notify1, MessageType.notify2] and self.body_type == 0x01) or \
- (self.message_type == MessageType.set and self.body_type == 0xC3):
+ if (
+ (self.message_type == MessageType.query and self.body_type == 0x01)
+ or (
+ self.message_type in [MessageType.notify1, MessageType.notify2]
+ and self.body_type == 0x01
+ )
+ or (self.message_type == MessageType.set and self.body_type == 0xC3)
+ ):
self.set_body(CCGeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/cd/device.py b/custom_components/midea_ac_lan/midea/devices/cd/device.py
index 8de65e50..a124f735 100644
--- a/custom_components/midea_ac_lan/midea/devices/cd/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/cd/device.py
@@ -1,14 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageSet,
- MessageCDResponse
-)
+import logging
+
+from .message import MessageCDResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -31,17 +30,17 @@ class MideaCDDevice(MiedaDevice):
_modes = ["Energy-save", "Standard", "Dual", "Smart"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -64,8 +63,9 @@ def __init__(
DeviceAttributes.outdoor_temperature: None,
DeviceAttributes.condenser_temperature: None,
DeviceAttributes.compressor_temperature: None,
- DeviceAttributes.compressor_status: None
- })
+ DeviceAttributes.compressor_status: None,
+ },
+ )
self._fields = {}
self._temperature_step = None
self._default_temperature_step = 1
@@ -99,12 +99,20 @@ def process_message(self, msg):
return new_status
def set_attribute(self, attr, value):
- if attr in [DeviceAttributes.mode, DeviceAttributes.power, DeviceAttributes.target_temperature]:
+ if attr in [
+ DeviceAttributes.mode,
+ DeviceAttributes.power,
+ DeviceAttributes.target_temperature,
+ ]:
message = MessageSet(self._protocol_version)
message.fields = self._fields
- message.mode = MideaCDDevice._modes.index(self._attributes[DeviceAttributes.mode])
+ message.mode = MideaCDDevice._modes.index(
+ self._attributes[DeviceAttributes.mode]
+ )
message.power = self._attributes[DeviceAttributes.power]
- message.target_temperature = self._attributes[DeviceAttributes.target_temperature]
+ message.target_temperature = self._attributes[
+ DeviceAttributes.target_temperature
+ ]
if attr == DeviceAttributes.mode:
if value in MideaCDDevice._modes:
setattr(message, str(attr), MideaCDDevice._modes.index(value))
diff --git a/custom_components/midea_ac_lan/midea/devices/cd/message.py b/custom_components/midea_ac_lan/midea/devices/cd/message.py
index 40c4ba0c..454cfe00 100644
--- a/custom_components/midea_ac_lan/midea/devices/cd/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/cd/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageCDBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xCD,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x01)
+ body_type=0x01,
+ )
self.power = False
self.target_temperature = 0
self.aux_heating = False
@@ -53,13 +50,18 @@ def _body(self):
power = 0x01 if self.power else 0x00
mode = self.mode + 1
target_temperature = round(self.target_temperature * 2 + 30)
- return bytearray([
- 0x01, power, mode, target_temperature,
- self.read_field("trValue"),
- self.read_field("openPTC"),
- self.read_field("ptcTemp"),
- 0 # self.read_field("byte8")
- ])
+ return bytearray(
+ [
+ 0x01,
+ power,
+ mode,
+ target_temperature,
+ self.read_field("trValue"),
+ self.read_field("openPTC"),
+ self.read_field("ptcTemp"),
+ 0, # self.read_field("byte8")
+ ]
+ )
class CDGeneralMessageBody(MessageBody):
diff --git a/custom_components/midea_ac_lan/midea/devices/ce/device.py b/custom_components/midea_ac_lan/midea/devices/ce/device.py
index f040e27d..c8ac6ecf 100644
--- a/custom_components/midea_ac_lan/midea/devices/ce/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/ce/device.py
@@ -1,14 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageCEResponse,
- MessageSet
-)
+import logging
+
+from .message import MessageCEResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -36,22 +35,20 @@ class DeviceAttributes(StrEnum):
class MideaCEDevice(MiedaDevice):
- _modes = [
- "Normal", "Sleep mode", "ECO mode"
- ]
+ _modes = ["Normal", "Sleep mode", "ECO mode"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -82,8 +79,9 @@ def __init__(
DeviceAttributes.powerful_purify: False,
DeviceAttributes.filter_cleaning_reminder: False,
DeviceAttributes.filter_change_reminder: False,
- DeviceAttributes.error_code: 0
- })
+ DeviceAttributes.error_code: 0,
+ },
+ )
self._default_speed_count = 7
self._speed_count = self._default_speed_count
self.set_customize(customize)
@@ -114,7 +112,9 @@ def process_message(self, msg):
self._attributes[DeviceAttributes.mode] = "ECO mode"
else:
self._attributes[DeviceAttributes.mode] = "None"
- new_status[DeviceAttributes.mode.value] = self._attributes[DeviceAttributes.mode]
+ new_status[DeviceAttributes.mode.value] = self._attributes[
+ DeviceAttributes.mode
+ ]
return new_status
def make_message_set(self):
diff --git a/custom_components/midea_ac_lan/midea/devices/ce/message.py b/custom_components/midea_ac_lan/midea/devices/ce/message.py
index dfcb6c9e..0f6afe3f 100644
--- a/custom_components/midea_ac_lan/midea/devices/ce/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/ce/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageFABase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xCE,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x01)
+ body_type=0x01,
+ )
self.power = False
self.fan_speed = 0
@@ -59,14 +56,16 @@ def _body(self):
powerful_purify = 0x10 if self.powerful_purify else 0x00
scheduled = 0x01 if self.scheduled else 0x00
child_lock = 0x7F if self.child_lock else 0x00
- return bytearray([
- power | 0x01,
- self.fan_speed,
- link_to_ac | sleep_mode | eco_mode | aux_heating | powerful_purify,
- scheduled,
- 0x00,
- child_lock
- ])
+ return bytearray(
+ [
+ power | 0x01,
+ self.fan_speed,
+ link_to_ac | sleep_mode | eco_mode | aux_heating | powerful_purify,
+ scheduled,
+ 0x00,
+ child_lock,
+ ]
+ )
class CEGeneralMessageBody(MessageBody):
@@ -126,8 +125,10 @@ def __init__(self, body):
class MessageCEResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type in [MessageType.query, MessageType.set] and self.body_type == 0x01) or \
- (self.message_type == MessageType.notify1 and self.body_type == 0x02):
+ if (
+ self.message_type in [MessageType.query, MessageType.set]
+ and self.body_type == 0x01
+ ) or (self.message_type == MessageType.notify1 and self.body_type == 0x02):
self.set_body(CEGeneralMessageBody(super().body))
elif self.message_type == MessageType.notify1 and self.body_type == 0x01:
self.set_body(CENotifyMessageBody(super().body))
diff --git a/custom_components/midea_ac_lan/midea/devices/cf/device.py b/custom_components/midea_ac_lan/midea/devices/cf/device.py
index 273e3972..40b5a9d5 100644
--- a/custom_components/midea_ac_lan/midea/devices/cf/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/cf/device.py
@@ -1,13 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageCFResponse,
- MessageSet
-)
+
+from .message import MessageCFResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -25,17 +24,17 @@ class DeviceAttributes(StrEnum):
class MideaCFDevice(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -55,8 +54,9 @@ def __init__(
DeviceAttributes.aux_heating: False,
DeviceAttributes.current_temperature: 0,
DeviceAttributes.max_temperature: 55,
- DeviceAttributes.min_temperature: 5
- })
+ DeviceAttributes.min_temperature: 5,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
diff --git a/custom_components/midea_ac_lan/midea/devices/cf/message.py b/custom_components/midea_ac_lan/midea/devices/cf/message.py
index 49bf150c..0bf0fb3f 100644
--- a/custom_components/midea_ac_lan/midea/devices/cf/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/cf/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageCFBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xCF,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x01)
+ body_type=0x01,
+ )
self.power = False
self.mode = 0 # 1 自动 2 制冷 3 制热
self.target_temperature = None
@@ -47,11 +44,15 @@ def __init__(self, protocol_version):
def _body(self):
power = 0x01 if self.power else 0x00
mode = self.mode
- target_temperature = 0xFF if self.target_temperature is None else (int(self.target_temperature) & 0xFF)
- aux_heating = 0xFF if self.aux_heating is None else (0x01 if self.aux_heating else 0x00)
- return bytearray([
- power, mode, target_temperature, aux_heating
- ])
+ target_temperature = (
+ 0xFF
+ if self.target_temperature is None
+ else (int(self.target_temperature) & 0xFF)
+ )
+ aux_heating = (
+ 0xFF if self.aux_heating is None else (0x01 if self.aux_heating else 0x00)
+ )
+ return bytearray([power, mode, target_temperature, aux_heating])
class CFMessageBody(MessageBody):
@@ -77,7 +78,10 @@ def __init__(self, body, data_offset=0):
class MessageCFResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set] and self.body_type == 0x01:
+ if (
+ self.message_type in [MessageType.query, MessageType.set]
+ and self.body_type == 0x01
+ ):
self.set_body(CFMessageBody(super().body, data_offset=1))
elif self.message_type in [MessageType.notify1, MessageType.notify2]:
self.set_body(CFMessageBody(super().body, data_offset=0))
diff --git a/custom_components/midea_ac_lan/midea/devices/da/device.py b/custom_components/midea_ac_lan/midea/devices/da/device.py
index f213424f..f5506e40 100644
--- a/custom_components/midea_ac_lan/midea/devices/da/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/da/device.py
@@ -1,14 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessagePower,
- MessageStart,
- MessageDAResponse
-)
+
+from .message import MessageDAResponse, MessagePower, MessageQuery, MessageStart
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -36,17 +34,17 @@ class DeviceAttributes(StrEnum):
class MideaDADevice(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -76,8 +74,9 @@ def __init__(
DeviceAttributes.wash_level: None,
DeviceAttributes.wash_strength: None,
DeviceAttributes.softener: None,
- DeviceAttributes.detergent: None
- })
+ DeviceAttributes.detergent: None,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -86,17 +85,47 @@ def process_message(self, msg):
message = MessageDAResponse(msg)
_LOGGER.debug(f"[{self.device_id}] Received: {message}")
new_status = {}
- progress = ["Idle", "Spin", "Rinse", "Wash",
- "Weight", "Unknown", "Dry", "Soak"]
- program = ["Standard", "Fast", "Blanket", "Wool",
- "embathe", "Memory", "Child", "Down Jacket",
- "Stir", "Mute", "Bucket Self Clean", "Air Dry"]
+ progress = ["Idle", "Spin", "Rinse", "Wash", "Weight", "Unknown", "Dry", "Soak"]
+ program = [
+ "Standard",
+ "Fast",
+ "Blanket",
+ "Wool",
+ "embathe",
+ "Memory",
+ "Child",
+ "Down Jacket",
+ "Stir",
+ "Mute",
+ "Bucket Self Clean",
+ "Air Dry",
+ ]
speed = ["-", "Low", "Medium", "High"]
strength = ["-", "Week", "Medium", "Strong"]
- detergent = ["No", "Less", "Medium", "More", "4",
- "5", "6", "7", "8", "Insufficient"]
- softener = ["No", "Intelligent", "Programed", "3", "4",
- "5", "6", "7", "8", "Insufficient"]
+ detergent = [
+ "No",
+ "Less",
+ "Medium",
+ "More",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "Insufficient",
+ ]
+ softener = [
+ "No",
+ "Intelligent",
+ "Programed",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "Insufficient",
+ ]
for status in self._attributes.keys():
if hasattr(message, str(status)):
if status == DeviceAttributes.progress:
diff --git a/custom_components/midea_ac_lan/midea/devices/da/message.py b/custom_components/midea_ac_lan/midea/devices/da/message.py
index 9baf761a..5578d46b 100644
--- a/custom_components/midea_ac_lan/midea/devices/da/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/da/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageDABase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xDA,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x03)
+ body_type=0x03,
+ )
@property
def _body(self):
@@ -37,15 +33,14 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.power = False
@property
def _body(self):
power = 0x01 if self.power else 0x00
- return bytearray([
- power, 0xFF
- ])
+ return bytearray([power, 0xFF])
class MessageStart(MessageDABase):
@@ -53,21 +48,18 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.start = False
self.washing_data = bytearray([])
@property
def _body(self):
if self.start:
- return bytearray([
- 0xFF, 0x01
- ]) + self.washing_data
+ return bytearray([0xFF, 0x01]) + self.washing_data
else:
# Stop
- return bytearray([
- 0xFF, 0x00
- ])
+ return bytearray([0xFF, 0x00])
class DAGeneralMessageBody(MessageBody):
@@ -79,14 +71,14 @@ def __init__(self, body):
self.program = body[4]
self.wash_time = body[9]
self.soak_time = body[12]
- self.dehydration_time = (body[10] & 0xf0) >> 4
- self.dehydration_speed = (body[6] & 0xf0) >> 4
- self.rinse_count = body[10] & 0xf
- self.rinse_level = (body[5] & 0xf0) >> 4
- self.wash_level = body[5] & 0xf
- self.wash_strength = body[6] & 0xf
- self.softener = (body[8] & 0xf0) >> 4
- self.detergent = body[8] & 0x0f
+ self.dehydration_time = (body[10] & 0xF0) >> 4
+ self.dehydration_speed = (body[6] & 0xF0) >> 4
+ self.rinse_count = body[10] & 0xF
+ self.rinse_level = (body[5] & 0xF0) >> 4
+ self.wash_level = body[5] & 0xF
+ self.wash_strength = body[6] & 0xF
+ self.softener = (body[8] & 0xF0) >> 4
+ self.detergent = body[8] & 0x0F
self.washing_data = body[3:15]
self.progress = 0
for i in range(1, 7):
@@ -102,7 +94,8 @@ def __init__(self, body):
class MessageDAResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set] or \
- (self.message_type == MessageType.notify1 and self.body_type == 0x04):
+ if self.message_type in [MessageType.query, MessageType.set] or (
+ self.message_type == MessageType.notify1 and self.body_type == 0x04
+ ):
self.set_body(DAGeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/db/device.py b/custom_components/midea_ac_lan/midea/devices/db/device.py
index 0ef737c0..fe1c02e4 100644
--- a/custom_components/midea_ac_lan/midea/devices/db/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/db/device.py
@@ -1,14 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessagePower,
- MessageStart,
- MessageDBResponse
-)
+
+from .message import MessageDBResponse, MessagePower, MessageQuery, MessageStart
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,17 +22,17 @@ class DeviceAttributes(StrEnum):
class MideaDBDevice(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -52,8 +50,9 @@ def __init__(
DeviceAttributes.start: False,
DeviceAttributes.washing_data: bytearray([]),
DeviceAttributes.progress: "Unknown",
- DeviceAttributes.time_remaining: None
- })
+ DeviceAttributes.time_remaining: None,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -62,8 +61,17 @@ def process_message(self, msg):
message = MessageDBResponse(msg)
_LOGGER.debug(f"[{self.device_id}] Received: {message}")
new_status = {}
- progress = ["Idle", "Spin", "Rinse", "Wash", "Pre-wash",
- "Dry", "Weight", "Hi-speed Spin", "Unknown"]
+ progress = [
+ "Idle",
+ "Spin",
+ "Rinse",
+ "Wash",
+ "Pre-wash",
+ "Dry",
+ "Weight",
+ "Hi-speed Spin",
+ "Unknown",
+ ]
for status in self._attributes.keys():
if hasattr(message, str(status)):
if status == DeviceAttributes.progress:
diff --git a/custom_components/midea_ac_lan/midea/devices/db/message.py b/custom_components/midea_ac_lan/midea/devices/db/message.py
index 580e5542..7a70ca55 100644
--- a/custom_components/midea_ac_lan/midea/devices/db/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/db/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageDBBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xDB,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x03)
+ body_type=0x03,
+ )
@property
def _body(self):
@@ -37,20 +33,38 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.power = False
@property
def _body(self):
power = 0x01 if self.power else 0x00
- return bytearray([
- power,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF
- ])
+ return bytearray(
+ [
+ power,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ ]
+ )
class MessageStart(MessageDBBase):
@@ -58,21 +72,18 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.start = False
self.washing_data = bytearray([])
@property
def _body(self):
- if self.start: # Pause
- return bytearray([
- 0xFF, 0x01
- ]) + self.washing_data
+ if self.start: # Pause
+ return bytearray([0xFF, 0x01]) + self.washing_data
else:
# Pause
- return bytearray([
- 0xFF, 0x00
- ])
+ return bytearray([0xFF, 0x00])
class DBGeneralMessageBody(MessageBody):
@@ -95,7 +106,8 @@ def __init__(self, body):
class MessageDBResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set] or \
- (self.message_type == MessageType.notify1 and self.body_type == 0x04):
+ if self.message_type in [MessageType.query, MessageType.set] or (
+ self.message_type == MessageType.notify1 and self.body_type == 0x04
+ ):
self.set_body(DBGeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/dc/device.py b/custom_components/midea_ac_lan/midea/devices/dc/device.py
index b78c121e..7e6d659f 100644
--- a/custom_components/midea_ac_lan/midea/devices/dc/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/dc/device.py
@@ -1,14 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessagePower,
- MessageStart,
- MessageDCResponse
-)
+
+from .message import MessageDCResponse, MessagePower, MessageQuery, MessageStart
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,17 +22,17 @@ class DeviceAttributes(StrEnum):
class MideaDADevice(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -52,8 +50,9 @@ def __init__(
DeviceAttributes.start: False,
DeviceAttributes.washing_data: bytearray([]),
DeviceAttributes.progress: "Unknown",
- DeviceAttributes.time_remaining: None
- })
+ DeviceAttributes.time_remaining: None,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -62,8 +61,16 @@ def process_message(self, msg):
message = MessageDCResponse(msg)
_LOGGER.debug(f"[{self.device_id}] Received: {message}")
new_status = {}
- progress = ["Prog0", "Prog1", "Prog2", "Prog3",
- "Prog4", "Prog5", "Prog6", "Prog7"]
+ progress = [
+ "Prog0",
+ "Prog1",
+ "Prog2",
+ "Prog3",
+ "Prog4",
+ "Prog5",
+ "Prog6",
+ "Prog7",
+ ]
for status in self._attributes.keys():
if hasattr(message, str(status)):
if status == DeviceAttributes.progress:
diff --git a/custom_components/midea_ac_lan/midea/devices/dc/message.py b/custom_components/midea_ac_lan/midea/devices/dc/message.py
index b9e66a7a..3be5d3dd 100644
--- a/custom_components/midea_ac_lan/midea/devices/dc/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/dc/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageDCBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xDC,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x03)
+ body_type=0x03,
+ )
@property
def _body(self):
@@ -37,15 +33,14 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.power = False
@property
def _body(self):
power = 0x01 if self.power else 0x00
- return bytearray([
- power, 0xFF
- ])
+ return bytearray([power, 0xFF])
class MessageStart(MessageDCBase):
@@ -53,21 +48,18 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.start = False
self.washing_data = bytearray([])
@property
def _body(self):
if self.start:
- return bytearray([
- 0xFF, 0x01
- ]) + self.washing_data
+ return bytearray([0xFF, 0x01]) + self.washing_data
else:
# Stop
- return bytearray([
- 0xFF, 0x00
- ])
+ return bytearray([0xFF, 0x00])
class DCGeneralMessageBody(MessageBody):
@@ -90,7 +82,8 @@ def __init__(self, body):
class MessageDCResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set] or \
- (self.message_type == MessageType.notify1 and self.body_type == 0x04):
+ if self.message_type in [MessageType.query, MessageType.set] or (
+ self.message_type == MessageType.notify1 and self.body_type == 0x04
+ ):
self.set_body(DCGeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/e1/device.py b/custom_components/midea_ac_lan/midea/devices/e1/device.py
index afc3d4c4..43c72ffa 100644
--- a/custom_components/midea_ac_lan/midea/devices/e1/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/e1/device.py
@@ -1,15 +1,18 @@
import logging
+
from .message import (
- MessageQuery,
+ MessageE1Response,
+ MessageLock,
MessagePower,
+ MessageQuery,
MessageStorage,
- MessageLock,
- MessageE1Response
)
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -44,17 +47,17 @@ class DeviceAttributes(StrEnum):
class MideaE1Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -91,31 +94,32 @@ def __init__(
DeviceAttributes.error_code: None,
DeviceAttributes.softwater: 0,
DeviceAttributes.wrong_operation: None,
- DeviceAttributes.bright: 0
- })
+ DeviceAttributes.bright: 0,
+ },
+ )
self._modes = {
- 0x0: "Neutral Gear", # BYTE_MODE_NEUTRAL_GEAR
- 0x1: "Auto", # BYTE_MODE_AUTO_WASH
- 0x2: "Heavy", # BYTE_MODE_STRONG_WASH
- 0x3: "Normal", # BYTE_MODE_STANDARD_WASH
- 0x4: "Energy Saving", # BYTE_MODE_ECO_WASH
- 0x5: "Delicate", # BYTE_MODE_GLASS_WASH
- 0x6: "Hour", # BYTE_MODE_HOUR_WASH
- 0x7: "Quick", # BYTE_MODE_FAST_WASH
- 0x8: "Rinse", # BYTE_MODE_SOAK_WASH
- 0x9: "90min", # BYTE_MODE_90MIN_WASH
- 0xA: "Self Clean", # BYTE_MODE_SELF_CLEAN
- 0xB: "Fruit Wash", # BYTE_MODE_FRUIT_WASH
- 0xC: "Self Define", # BYTE_MODE_SELF_DEFINE
- 0xD: "Germ", # BYTE_MODE_GERM ???
- 0xE: "Bowl Wash", # BYTE_MODE_BOWL_WASH
- 0xF: "Kill Germ", # BYTE_MODE_KILL_GERM
- 0x10: "Sea Food Wash", # BYTE_MODE_SEA_FOOD_WASH
- 0x12: "Hot Pot Wash", # BYTE_MODE_HOT_POT_WASH
- 0x13: "Quiet", # BYTE_MODE_QUIET_NIGHT_WASH
- 0x14: "Less Wash", # BYTE_MODE_LESS_WASH
- 0x16: "Oil Net Wash", # BYTE_MODE_OIL_NET_WASH
- 0x19: "Cloud Wash" # BYTE_MODE_CLOUD_WASH
+ 0x0: "Neutral Gear", # BYTE_MODE_NEUTRAL_GEAR
+ 0x1: "Auto", # BYTE_MODE_AUTO_WASH
+ 0x2: "Heavy", # BYTE_MODE_STRONG_WASH
+ 0x3: "Normal", # BYTE_MODE_STANDARD_WASH
+ 0x4: "Energy Saving", # BYTE_MODE_ECO_WASH
+ 0x5: "Delicate", # BYTE_MODE_GLASS_WASH
+ 0x6: "Hour", # BYTE_MODE_HOUR_WASH
+ 0x7: "Quick", # BYTE_MODE_FAST_WASH
+ 0x8: "Rinse", # BYTE_MODE_SOAK_WASH
+ 0x9: "90min", # BYTE_MODE_90MIN_WASH
+ 0xA: "Self Clean", # BYTE_MODE_SELF_CLEAN
+ 0xB: "Fruit Wash", # BYTE_MODE_FRUIT_WASH
+ 0xC: "Self Define", # BYTE_MODE_SELF_DEFINE
+ 0xD: "Germ", # BYTE_MODE_GERM ???
+ 0xE: "Bowl Wash", # BYTE_MODE_BOWL_WASH
+ 0xF: "Kill Germ", # BYTE_MODE_KILL_GERM
+ 0x10: "Sea Food Wash", # BYTE_MODE_SEA_FOOD_WASH
+ 0x12: "Hot Pot Wash", # BYTE_MODE_HOT_POT_WASH
+ 0x13: "Quiet", # BYTE_MODE_QUIET_NIGHT_WASH
+ 0x14: "Less Wash", # BYTE_MODE_LESS_WASH
+ 0x16: "Oil Net Wash", # BYTE_MODE_OIL_NET_WASH
+ 0x19: "Cloud Wash", # BYTE_MODE_CLOUD_WASH
}
self._status = ["Off", "Idle", "Delay", "Running", "Error"]
self._progress = ["Idle", "Pre-wash", "Wash", "Rinse", "Dry", "Complete"]
diff --git a/custom_components/midea_ac_lan/midea/devices/e1/message.py b/custom_components/midea_ac_lan/midea/devices/e1/message.py
index 1147e648..530572e8 100644
--- a/custom_components/midea_ac_lan/midea/devices/e1/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/e1/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageE1Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xE1,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,16 +20,14 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x08)
+ body_type=0x08,
+ )
self.power = False
@property
def _body(self):
power = 0x01 if self.power else 0x00
- return bytearray([
- power,
- 0x00, 0x00, 0x00
- ])
+ return bytearray([power, 0x00, 0x00, 0x00])
class MessageLock(MessageE1Base):
@@ -42,7 +35,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x83)
+ body_type=0x83,
+ )
self.lock = False
@property
@@ -56,14 +50,18 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x81)
+ body_type=0x81,
+ )
self.storage = False
@property
def _body(self):
storage = 0x01 if self.storage else 0x00
- return bytearray([0x00, 0x00, 0x00, storage]) + \
- bytearray([0xff] * 6) + bytearray([0x00] * 27)
+ return (
+ bytearray([0x00, 0x00, 0x00, storage])
+ + bytearray([0xFF] * 6)
+ + bytearray([0x00] * 27)
+ )
class MessageQuery(MessageE1Base):
@@ -71,7 +69,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x00)
+ body_type=0x00,
+ )
@property
def _body(self):
@@ -85,9 +84,9 @@ def __init__(self, body):
self.status = body[1]
self.mode = body[2]
self.additional = body[3]
- self.door = (body[5] & 0x01) == 0 # 0 - open, 1 - close
- self.rinse_aid = (body[5] & 0x02) > 0 # 0 - enough, 1 - shortage
- self.salt = (body[5] & 0x04) > 0 # 0 - enough, 1 - shortage
+ self.door = (body[5] & 0x01) == 0 # 0 - open, 1 - close
+ self.rinse_aid = (body[5] & 0x02) > 0 # 0 - enough, 1 - shortage
+ self.salt = (body[5] & 0x04) > 0 # 0 - enough, 1 - shortage
start_pause = (body[5] & 0x08) > 0
if start_pause:
self.start = True
@@ -115,7 +114,9 @@ def __init__(self, body):
class MessageE1Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type == MessageType.set and 0 <= self.body_type <= 7) or \
- (self.message_type in [MessageType.query, MessageType.notify1] and self.body_type == 0):
+ if (self.message_type == MessageType.set and 0 <= self.body_type <= 7) or (
+ self.message_type in [MessageType.query, MessageType.notify1]
+ and self.body_type == 0
+ ):
self.set_body(E1GeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/e2/device.py b/custom_components/midea_ac_lan/midea/devices/e2/device.py
index fc8ca315..b261a44f 100644
--- a/custom_components/midea_ac_lan/midea/devices/e2/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/e2/device.py
@@ -1,16 +1,19 @@
-import logging
import json
+import logging
+
from .message import (
- MessageQuery,
- MessageSet,
MessageE2Response,
+ MessageNewProtocolSet,
MessagePower,
- MessageNewProtocolSet
+ MessageQuery,
+ MessageSet,
)
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -32,17 +35,17 @@ class DeviceAttributes(StrEnum):
class MideaE2Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -66,8 +69,9 @@ def __init__(
DeviceAttributes.variable_heating: False,
DeviceAttributes.heating_time_remaining: 0,
DeviceAttributes.water_consumption: None,
- DeviceAttributes.heating_power: None
- })
+ DeviceAttributes.heating_power: None,
+ },
+ )
self._default_old_protocol = "auto"
self._old_protocol = self._default_old_protocol
self.set_customize(customize)
@@ -91,15 +95,21 @@ def process_message(self, msg):
def make_message_set(self):
message = MessageSet(self._protocol_version)
message.protection = self._attributes[DeviceAttributes.protection]
- message.whole_tank_heating = self._attributes[DeviceAttributes.whole_tank_heating]
- message.target_temperature = self._attributes[DeviceAttributes.target_temperature]
+ message.whole_tank_heating = self._attributes[
+ DeviceAttributes.whole_tank_heating
+ ]
+ message.target_temperature = self._attributes[
+ DeviceAttributes.target_temperature
+ ]
message.variable_heating = self._attributes[DeviceAttributes.variable_heating]
return message
def set_attribute(self, attr, value):
- if attr not in [DeviceAttributes.heating,
- DeviceAttributes.keep_warm,
- DeviceAttributes.current_temperature]:
+ if attr not in [
+ DeviceAttributes.heating,
+ DeviceAttributes.keep_warm,
+ DeviceAttributes.current_temperature,
+ ]:
if self._old_protocol is not None and self._old_protocol != "auto":
old_protocol = self._old_protocol
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/e2/message.py b/custom_components/midea_ac_lan/midea/devices/e2/message.py
index 18d80ecc..a70c6cc9 100644
--- a/custom_components/midea_ac_lan/midea/devices/e2/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/e2/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageE2Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xE2,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -37,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.power = False
@property
@@ -54,7 +51,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x14)
+ body_type=0x14,
+ )
self.target_temperature = None
self.variable_heating = None
self.whole_tank_heating = None
@@ -80,7 +78,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x04)
+ body_type=0x04,
+ )
self.target_temperature = 0
self.variable_heating = False
self.whole_tank_heating = False
@@ -95,18 +94,28 @@ def _body(self):
target_temperature = self.target_temperature & 0xFF
# Byte 9 variable_heating
variable_heating = 0x10 if self.variable_heating else 0x00
- return bytearray([
- 0x01,
- 0x00,
- 0x80,
- whole_tank_heating | protection,
- target_temperature,
- 0x00, 0x00, 0x00,
- variable_heating,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00
- ])
+ return bytearray(
+ [
+ 0x01,
+ 0x00,
+ 0x80,
+ whole_tank_heating | protection,
+ target_temperature,
+ 0x00,
+ 0x00,
+ 0x00,
+ variable_heating,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class E2GeneralMessageBody(MessageBody):
@@ -130,7 +139,12 @@ def __init__(self, body):
class MessageE2Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type in [MessageType.query, MessageType.notify1] and self.body_type == 0x01) or \
- (self.message_type == MessageType.set and self.body_type in [0x01, 0x02, 0x04, 0x14]):
+ if (
+ self.message_type in [MessageType.query, MessageType.notify1]
+ and self.body_type == 0x01
+ ) or (
+ self.message_type == MessageType.set
+ and self.body_type in [0x01, 0x02, 0x04, 0x14]
+ ):
self.set_body(E2GeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/e3/device.py b/custom_components/midea_ac_lan/midea/devices/e3/device.py
index 69b92557..250076d1 100644
--- a/custom_components/midea_ac_lan/midea/devices/e3/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/e3/device.py
@@ -1,16 +1,19 @@
-import logging
import json
+import logging
+
from .message import (
- MessageQuery,
- MessageSet,
+ MessageE3Response,
MessageNewProtocolSet,
MessagePower,
- MessageE3Response
+ MessageQuery,
+ MessageSet,
)
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -29,17 +32,17 @@ class DeviceAttributes(StrEnum):
class MideaE3Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -61,10 +64,9 @@ def __init__(
DeviceAttributes.smart_volume: False,
DeviceAttributes.current_temperature: None,
DeviceAttributes.target_temperature: 40,
- })
- self._old_subtypes = [
- 32, 33, 34, 35, 36, 37, 40, 43, 48, 49, 80
- ]
+ },
+ )
+ self._old_subtypes = [32, 33, 34, 35, 36, 37, 40, 43, 48, 49, 80]
self._precision_halves = None
self._default_precision_halves = False
self.set_customize(customize)
@@ -82,9 +84,10 @@ def process_message(self, msg):
new_status = {}
for status in self._attributes.keys():
if hasattr(message, str(status)):
- if self._precision_halves and status in \
- [DeviceAttributes.current_temperature,
- DeviceAttributes.target_temperature]:
+ if self._precision_halves and status in [
+ DeviceAttributes.current_temperature,
+ DeviceAttributes.target_temperature,
+ ]:
self._attributes[status] = getattr(message, str(status)) / 2
else:
self._attributes[status] = getattr(message, str(status))
@@ -98,13 +101,17 @@ def make_message_set(self):
message.protection = self._attributes[DeviceAttributes.protection]
message.zero_clod_pulse = self._attributes[DeviceAttributes.zero_cold_pulse]
message.smart_volume = self._attributes[DeviceAttributes.smart_volume]
- message.target_temperature = self._attributes[DeviceAttributes.target_temperature]
+ message.target_temperature = self._attributes[
+ DeviceAttributes.target_temperature
+ ]
return message
def set_attribute(self, attr, value):
- if attr not in [DeviceAttributes.burning_state,
- DeviceAttributes.current_temperature,
- DeviceAttributes.protection]:
+ if attr not in [
+ DeviceAttributes.burning_state,
+ DeviceAttributes.current_temperature,
+ DeviceAttributes.protection,
+ ]:
if self._precision_halves and attr == DeviceAttributes.target_temperature:
value = int(value * 2)
if attr == DeviceAttributes.power:
diff --git a/custom_components/midea_ac_lan/midea/devices/e3/message.py b/custom_components/midea_ac_lan/midea/devices/e3/message.py
index 2b86ff07..4b6952a2 100644
--- a/custom_components/midea_ac_lan/midea/devices/e3/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/e3/message.py
@@ -1,17 +1,11 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
-
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
NEW_PROTOCOL_PARAMS = {
"zero_cold_water": 0x03,
# "zero_cold_master": 0x12,
"zero_cold_pulse": 0x04,
"smart_volume": 0x07,
- "target_temperature": 0x08
+ "target_temperature": 0x08,
}
@@ -21,7 +15,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xE3,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -34,7 +28,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
@@ -46,7 +41,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x02)
+ body_type=0x02,
+ )
self.power = False
@property
@@ -63,7 +59,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x04)
+ body_type=0x04,
+ )
self.target_temperature = 0
self.zero_cold_water = False
@@ -83,17 +80,24 @@ def _body(self):
# Byte 5 target_temperature
target_temperature = self.target_temperature & 0xFF
- return bytearray([
- 0x01,
- zero_cold_water | 0x02,
- protection | zero_cold_pulse | smart_volume,
- 0x00,
- target_temperature,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00,
-
- ])
+ return bytearray(
+ [
+ 0x01,
+ zero_cold_water | 0x02,
+ protection | zero_cold_pulse | smart_volume,
+ 0x00,
+ target_temperature,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessageNewProtocolSet(MessageE3Base):
@@ -101,7 +105,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x14)
+ body_type=0x14,
+ )
self.key = None
self.value = None
@@ -112,14 +117,29 @@ def _body(self):
value = self.value
else:
value = 0x01 if self.value else 0x00
- return bytearray([
- key, value,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00
- ])
+ return bytearray(
+ [
+ key,
+ value,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class E3GeneralMessageBody(MessageBody):
@@ -138,8 +158,16 @@ def __init__(self, body):
class MessageE3Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type == MessageType.query and self.body_type == 0x01) or \
- (self.message_type == MessageType.set and self.body_type in [0x01, 0x02, 0x04, 0x14]) or \
- (self.message_type == MessageType.notify1 and self.body_type in [0x00, 0x01]):
+ if (
+ (self.message_type == MessageType.query and self.body_type == 0x01)
+ or (
+ self.message_type == MessageType.set
+ and self.body_type in [0x01, 0x02, 0x04, 0x14]
+ )
+ or (
+ self.message_type == MessageType.notify1
+ and self.body_type in [0x00, 0x01]
+ )
+ ):
self.set_body(E3GeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/e6/device.py b/custom_components/midea_ac_lan/midea/devices/e6/device.py
index 951125df..82368b40 100644
--- a/custom_components/midea_ac_lan/midea/devices/e6/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/e6/device.py
@@ -1,13 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageSet,
- MessageE6Response
-)
+
+from .message import MessageE6Response, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -28,17 +27,17 @@ class DeviceAttributes(StrEnum):
class MideaE6Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -61,8 +60,9 @@ def __init__(
DeviceAttributes.heating_temperature: 50,
DeviceAttributes.bathing_temperature: 40,
DeviceAttributes.heating_leaving_temperature: None,
- DeviceAttributes.bathing_leaving_temperature: None
- })
+ DeviceAttributes.bathing_leaving_temperature: None,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -78,10 +78,12 @@ def process_message(self, msg):
return new_status
def set_attribute(self, attr, value):
- if attr in [DeviceAttributes.main_power,
- DeviceAttributes.heating_power,
- DeviceAttributes.heating_temperature,
- DeviceAttributes.bathing_temperature]:
+ if attr in [
+ DeviceAttributes.main_power,
+ DeviceAttributes.heating_power,
+ DeviceAttributes.heating_temperature,
+ DeviceAttributes.bathing_temperature,
+ ]:
message = MessageSet(self._protocol_version)
setattr(message, str(attr), value)
self.build_send(message)
diff --git a/custom_components/midea_ac_lan/midea/devices/e6/message.py b/custom_components/midea_ac_lan/midea/devices/e6/message.py
index 79738af4..230e2d5d 100644
--- a/custom_components/midea_ac_lan/midea/devices/e6/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/e6/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageE6Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type):
device_type=0xE6,
protocol_version=protocol_version,
message_type=message_type,
- body_type=None
+ body_type=None,
)
@property
@@ -27,8 +22,7 @@ def _body(self):
class MessageQuery(MessageE6Base):
def __init__(self, protocol_version):
super().__init__(
- protocol_version=protocol_version,
- message_type=MessageType.query
+ protocol_version=protocol_version, message_type=MessageType.query
)
@property
@@ -39,8 +33,7 @@ def _body(self):
class MessageSet(MessageE6Base):
def __init__(self, protocol_version):
super().__init__(
- protocol_version=protocol_version,
- message_type=MessageType.set
+ protocol_version=protocol_version, message_type=MessageType.set
)
self.main_power = None
self.heating_temperature = None
@@ -71,14 +64,8 @@ def __init__(self, body):
self.heating_working = (body[2] & 0x10) > 0
self.bathing_working = (body[2] & 0x20) > 0
self.heating_power = (body[4] & 0x01) > 0
- self.min_temperature = [
- body[16],
- body[11]
- ]
- self.max_temperature = [
- body[15],
- body[10]
- ]
+ self.min_temperature = [body[16], body[11]]
+ self.max_temperature = [body[15], body[10]]
self.heating_temperature = body[17]
self.bathing_temperature = body[12]
self.heating_leaving_temperature = body[14]
diff --git a/custom_components/midea_ac_lan/midea/devices/e8/device.py b/custom_components/midea_ac_lan/midea/devices/e8/device.py
index abaaada3..813941a2 100644
--- a/custom_components/midea_ac_lan/midea/devices/e8/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/e8/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageE8Response
-)
+
+from .message import MessageE8Response, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -25,22 +25,26 @@ class DeviceAttributes(StrEnum):
class MideaE8Device(MiedaDevice):
_status = {
- 0x00: "Standby", 0x01: "Delay", 0x02: "Working",
- 0x03: "Paused", 0x04: "Keep-Warming", 0xFF: "Error"
+ 0x00: "Standby",
+ 0x01: "Delay",
+ 0x02: "Working",
+ 0x03: "Paused",
+ 0x04: "Keep-Warming",
+ 0xFF: "Error",
}
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -62,7 +66,8 @@ def __init__(
DeviceAttributes.current_temperature: None,
DeviceAttributes.finished: None,
DeviceAttributes.water_shortage: None,
- })
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -76,7 +81,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.status:
if value in MideaE8Device._status.keys():
- self._attributes[DeviceAttributes.status] = MideaE8Device._status.get(value)
+ self._attributes[DeviceAttributes.status] = (
+ MideaE8Device._status.get(value)
+ )
else:
self._attributes[DeviceAttributes.status] = None
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/e8/message.py b/custom_components/midea_ac_lan/midea/devices/e8/message.py
index 9c45c688..6fe81409 100644
--- a/custom_components/midea_ac_lan/midea/devices/e8/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/e8/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageE8Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xE8,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0xAA)
+ body_type=0xAA,
+ )
@property
def _body(self):
@@ -50,7 +46,10 @@ def __init__(self, message):
super().__init__(message)
if len(super().body) > 6:
sub_cmd = super().body[6]
- if ((self.message_type == MessageType.set and sub_cmd in [0x02, 0x04, 0x06]) or
- self.message_type in [MessageType.query, MessageType.notify1] and sub_cmd == 2):
+ if (
+ (self.message_type == MessageType.set and sub_cmd in [0x02, 0x04, 0x06])
+ or self.message_type in [MessageType.query, MessageType.notify1]
+ and sub_cmd == 2
+ ):
self.set_body(E8MessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/ea/device.py b/custom_components/midea_ac_lan/midea/devices/ea/device.py
index aa4fbc45..722d12d8 100644
--- a/custom_components/midea_ac_lan/midea/devices/ea/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/ea/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageEAResponse
-)
+
+from .message import MessageEAResponse, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,43 +24,122 @@ class DeviceAttributes(StrEnum):
class MideaEADevice(MiedaDevice):
- _mode_list = [
- "smart", "reserve", "cook_rice", "fast_cook_rice", "standard_cook_rice",
- "gruel", "cook_congee", "stew_soup", "stewing", "heat_rice", "make_cake",
- "yoghourt", "soup_rice", "coarse_rice", "five_ceeals_rice", "eight_treasures_rice",
- "crispy_rice", "shelled_rice", "eight_treasures_congee", "infant_congee",
- "older_rice", "rice_soup", "rice_paste", "egg_custard", "warm_milk",
- "hot_spring_egg", "millet_congee", "firewood_rice", "few_rice",
- "red_potato", "corn", "quick_freeze_bun", "steam_ribs", "steam_egg",
- "coarse_congee", "steep_rice", "appetizing_congee", "corn_congee",
- "sprout_rice", "luscious_rice", "luscious_boiled", "fast_rice", "fast_boil",
- "bean_rice_congee", "fast_congee", "baby_congee", "cook_soup", "congee_coup",
- "steam_corn", "steam_red_potato", "boil_congee", "delicious_steam", "boil_egg",
- "rice_wine", "fruit_vegetable_paste", "vegetable_porridge", "pork_porridge",
- "fragrant_rice", "assorte_rice", "steame_fish", "baby_rice", "essence_rice",
- "fragrant_dense_congee", "one_two_cook", "original_steame", "hot_fast_rice",
- "online_celebrity_rice", "sushi_rice", "stone_bowl_rice", "no_water_treat",
- "keep_fresh", "low_sugar_rice", "black_buckwheat_rice", "resveratrol_rice",
- "yellow_wheat_rice", "green_buckwheat_rice", "roughage_rice", "millet_mixed_rice",
- "iron_pan_rice", "olla_pan_rice", "vegetable_rice", "baby_side", "regimen_congee",
- "earthen_pot_congee", "regimen_soup", "pottery_jar_soup", "canton_soup",
- "nutrition_stew", "northeast_stew", "uncap_boil", "trichromatic_coarse_grain",
- "four_color_vegetables", "egg", "chop",
- ] + ["unknown"] * 98 + ["clean"] + ["unknown"] * 5 + ["keep_warm"]
+ _mode_list = (
+ [
+ "smart",
+ "reserve",
+ "cook_rice",
+ "fast_cook_rice",
+ "standard_cook_rice",
+ "gruel",
+ "cook_congee",
+ "stew_soup",
+ "stewing",
+ "heat_rice",
+ "make_cake",
+ "yoghourt",
+ "soup_rice",
+ "coarse_rice",
+ "five_ceeals_rice",
+ "eight_treasures_rice",
+ "crispy_rice",
+ "shelled_rice",
+ "eight_treasures_congee",
+ "infant_congee",
+ "older_rice",
+ "rice_soup",
+ "rice_paste",
+ "egg_custard",
+ "warm_milk",
+ "hot_spring_egg",
+ "millet_congee",
+ "firewood_rice",
+ "few_rice",
+ "red_potato",
+ "corn",
+ "quick_freeze_bun",
+ "steam_ribs",
+ "steam_egg",
+ "coarse_congee",
+ "steep_rice",
+ "appetizing_congee",
+ "corn_congee",
+ "sprout_rice",
+ "luscious_rice",
+ "luscious_boiled",
+ "fast_rice",
+ "fast_boil",
+ "bean_rice_congee",
+ "fast_congee",
+ "baby_congee",
+ "cook_soup",
+ "congee_coup",
+ "steam_corn",
+ "steam_red_potato",
+ "boil_congee",
+ "delicious_steam",
+ "boil_egg",
+ "rice_wine",
+ "fruit_vegetable_paste",
+ "vegetable_porridge",
+ "pork_porridge",
+ "fragrant_rice",
+ "assorte_rice",
+ "steame_fish",
+ "baby_rice",
+ "essence_rice",
+ "fragrant_dense_congee",
+ "one_two_cook",
+ "original_steame",
+ "hot_fast_rice",
+ "online_celebrity_rice",
+ "sushi_rice",
+ "stone_bowl_rice",
+ "no_water_treat",
+ "keep_fresh",
+ "low_sugar_rice",
+ "black_buckwheat_rice",
+ "resveratrol_rice",
+ "yellow_wheat_rice",
+ "green_buckwheat_rice",
+ "roughage_rice",
+ "millet_mixed_rice",
+ "iron_pan_rice",
+ "olla_pan_rice",
+ "vegetable_rice",
+ "baby_side",
+ "regimen_congee",
+ "earthen_pot_congee",
+ "regimen_soup",
+ "pottery_jar_soup",
+ "canton_soup",
+ "nutrition_stew",
+ "northeast_stew",
+ "uncap_boil",
+ "trichromatic_coarse_grain",
+ "four_color_vegetables",
+ "egg",
+ "chop",
+ ]
+ + ["unknown"] * 98
+ + ["clean"]
+ + ["unknown"] * 5
+ + ["keep_warm"]
+ )
_progress = ["Idle", "Delay", "Cooking", "Keep-warm"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -81,8 +160,9 @@ def __init__(
DeviceAttributes.top_temperature: None,
DeviceAttributes.bottom_temperature: None,
DeviceAttributes.keep_warm_time: None,
- DeviceAttributes.progress: "Unknown"
- })
+ DeviceAttributes.progress: "Unknown",
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
diff --git a/custom_components/midea_ac_lan/midea/devices/ea/message.py b/custom_components/midea_ac_lan/midea/devices/ea/message.py
index 50ac934a..49347767 100644
--- a/custom_components/midea_ac_lan/midea/devices/ea/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/ea/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageEABase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xEA,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,13 +20,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=None)
+ body_type=None,
+ )
@property
def body(self):
- return bytearray([
- 0xAA, 0x55, 0x01, 0x03, 0x00
- ])
+ return bytearray([0xAA, 0x55, 0x01, 0x03, 0x00])
@property
def _body(self):
@@ -100,16 +94,22 @@ def __init__(self, message):
if self.message_type == MessageType.set and super().body[5] == 0x16: # 381
self.set_body(EABody1(super().body))
elif self.message_type == MessageType.query:
- if super().body[6] == 0x52 and super().body[7] == 0xc3: # 404
+ if super().body[6] == 0x52 and super().body[7] == 0xC3: # 404
self.set_body(EABody2(super().body))
- elif super().body[5] == 0x3d: # 420
+ elif super().body[5] == 0x3D: # 420
self.set_body(EABody1(super().body))
- elif self.message_type == MessageType.notify1 and super().body[5] == 0x3d: # 463
+ elif (
+ self.message_type == MessageType.notify1 and super().body[5] == 0x3D
+ ): # 463
self.set_body(EABody1(super().body))
else:
- if (self.message_type == MessageType.set and super().body[3] == 0x02) or \
- (self.message_type == MessageType.query and super().body[3] == 0x03) or \
- (self.message_type == MessageType.notify1 and super().body[3] == 0x04): # 351
+ if (
+ (self.message_type == MessageType.set and super().body[3] == 0x02)
+ or (self.message_type == MessageType.query and super().body[3] == 0x03)
+ or (
+ self.message_type == MessageType.notify1 and super().body[3] == 0x04
+ )
+ ): # 351
self.set_body(EABody3(super().body))
elif self.message_type == MessageType.notify1 and super().body[3] == 0x06:
self.mode = super().body[4] + (super().body[5] << 8)
diff --git a/custom_components/midea_ac_lan/midea/devices/ec/device.py b/custom_components/midea_ac_lan/midea/devices/ec/device.py
index c6eed5b1..a87e9955 100644
--- a/custom_components/midea_ac_lan/midea/devices/ec/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/ec/device.py
@@ -1,12 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageECResponse
-)
+
+from .message import MessageECResponse, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -24,45 +24,134 @@ class DeviceAttributes(StrEnum):
class MideaECDevice(MiedaDevice):
- _mode_list = [
- "smart", "reserve", "cook_rice", "fast_cook_rice", "standard_cook_rice",
- "gruel", "cook_congee", "stew_soup", "stewing", "heat_rice", "make_cake",
- "yoghourt", "soup_rice", "coarse_rice", "five_ceeals_rice", "eight_treasures_rice",
- "crispy_rice", "shelled_rice", "eight_treasures_congee", "infant_congee",
- "older_rice", "rice_soup", "rice_paste", "egg_custard", "warm_milk",
- "hot_spring_egg", "millet_congee", "firewood_rice", "few_rice",
- "red_potato", "corn", "quick_freeze_bun", "steam_ribs", "steam_egg",
- "coarse_congee", "steep_rice", "appetizing_congee", "corn_congee",
- "sprout_rice", "luscious_rice", "luscious_boiled", "fast_rice", "fast_boil",
- "bean_rice_congee", "fast_congee", "baby_congee", "cook_soup", "congee_coup",
- "steam_corn", "steam_red_potato", "boil_congee", "delicious_steam", "boil_egg",
- "rice_wine", "fruit_vegetable_paste", "vegetable_porridge", "pork_porridge",
- "fragrant_rice", "assorte_rice", "steame_fish", "baby_rice", "essence_rice",
- "fragrant_dense_congee", "one_two_cook", "original_steame", "hot_fast_rice",
- "online_celebrity_rice", "sushi_rice", "stone_bowl_rice", "no_water_treat",
- "keep_fresh", "low_sugar_rice", "black_buckwheat_rice", "resveratrol_rice",
- "yellow_wheat_rice", "green_buckwheat_rice", "roughage_rice", "millet_mixed_rice",
- "iron_pan_rice", "olla_pan_rice", "vegetable_rice", "baby_side", "regimen_congee",
- "earthen_pot_congee", "regimen_soup", "pottery_jar_soup", "canton_soup",
- "nutrition_stew", "northeast_stew", "uncap_boil", "trichromatic_coarse_grain",
- "four_color_vegetables", "egg", "chop",
- ] + ["unknown"] * 98 + ["clean"] + ["unknown"] * 5 + ["keep_warm", "diy"]
- _progress = ["Idle", "Cooking", "Delay", "Keep-warm",
- "Lid-open", "Relieving", "Keep-pressure",
- "Relieving", "Cooking", "Relieving", "Lid-open"]
+ _mode_list = (
+ [
+ "smart",
+ "reserve",
+ "cook_rice",
+ "fast_cook_rice",
+ "standard_cook_rice",
+ "gruel",
+ "cook_congee",
+ "stew_soup",
+ "stewing",
+ "heat_rice",
+ "make_cake",
+ "yoghourt",
+ "soup_rice",
+ "coarse_rice",
+ "five_ceeals_rice",
+ "eight_treasures_rice",
+ "crispy_rice",
+ "shelled_rice",
+ "eight_treasures_congee",
+ "infant_congee",
+ "older_rice",
+ "rice_soup",
+ "rice_paste",
+ "egg_custard",
+ "warm_milk",
+ "hot_spring_egg",
+ "millet_congee",
+ "firewood_rice",
+ "few_rice",
+ "red_potato",
+ "corn",
+ "quick_freeze_bun",
+ "steam_ribs",
+ "steam_egg",
+ "coarse_congee",
+ "steep_rice",
+ "appetizing_congee",
+ "corn_congee",
+ "sprout_rice",
+ "luscious_rice",
+ "luscious_boiled",
+ "fast_rice",
+ "fast_boil",
+ "bean_rice_congee",
+ "fast_congee",
+ "baby_congee",
+ "cook_soup",
+ "congee_coup",
+ "steam_corn",
+ "steam_red_potato",
+ "boil_congee",
+ "delicious_steam",
+ "boil_egg",
+ "rice_wine",
+ "fruit_vegetable_paste",
+ "vegetable_porridge",
+ "pork_porridge",
+ "fragrant_rice",
+ "assorte_rice",
+ "steame_fish",
+ "baby_rice",
+ "essence_rice",
+ "fragrant_dense_congee",
+ "one_two_cook",
+ "original_steame",
+ "hot_fast_rice",
+ "online_celebrity_rice",
+ "sushi_rice",
+ "stone_bowl_rice",
+ "no_water_treat",
+ "keep_fresh",
+ "low_sugar_rice",
+ "black_buckwheat_rice",
+ "resveratrol_rice",
+ "yellow_wheat_rice",
+ "green_buckwheat_rice",
+ "roughage_rice",
+ "millet_mixed_rice",
+ "iron_pan_rice",
+ "olla_pan_rice",
+ "vegetable_rice",
+ "baby_side",
+ "regimen_congee",
+ "earthen_pot_congee",
+ "regimen_soup",
+ "pottery_jar_soup",
+ "canton_soup",
+ "nutrition_stew",
+ "northeast_stew",
+ "uncap_boil",
+ "trichromatic_coarse_grain",
+ "four_color_vegetables",
+ "egg",
+ "chop",
+ ]
+ + ["unknown"] * 98
+ + ["clean"]
+ + ["unknown"] * 5
+ + ["keep_warm", "diy"]
+ )
+ _progress = [
+ "Idle",
+ "Cooking",
+ "Delay",
+ "Keep-warm",
+ "Lid-open",
+ "Relieving",
+ "Keep-pressure",
+ "Relieving",
+ "Cooking",
+ "Relieving",
+ "Lid-open",
+ ]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -83,8 +172,9 @@ def __init__(
DeviceAttributes.bottom_temperature: None,
DeviceAttributes.keep_warm_time: None,
DeviceAttributes.progress: "Unknown",
- DeviceAttributes.with_pressure: None
- })
+ DeviceAttributes.with_pressure: None,
+ },
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -98,7 +188,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.progress:
if value < len(MideaECDevice._progress):
- self._attributes[status] = MideaECDevice._progress[getattr(message, str(status))]
+ self._attributes[status] = MideaECDevice._progress[
+ getattr(message, str(status))
+ ]
else:
self._attributes[status] = "Unknown"
elif status == DeviceAttributes.mode:
diff --git a/custom_components/midea_ac_lan/midea/devices/ec/message.py b/custom_components/midea_ac_lan/midea/devices/ec/message.py
index 5911670c..00c4aefe 100644
--- a/custom_components/midea_ac_lan/midea/devices/ec/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/ec/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageECBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xEC,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,16 +20,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=None)
+ body_type=None,
+ )
@property
def body(self):
- return bytearray([
- 0xAA, 0x55,
- 0x01, 0x03,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- ])
+ return bytearray([0xAA, 0x55, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
@property
def _body(self):
@@ -63,7 +54,7 @@ def __init__(self, body):
self.keep_warm_time = body[19] * 60 + body[20]
self.top_temperature = body[48]
self.bottom_temperature = body[49]
- self.with_pressure = (body[33] > 0)
+ self.with_pressure = body[33] > 0
class MessageECResponse(MessageResponse):
@@ -71,10 +62,12 @@ def __init__(self, message):
super().__init__(message)
if self.message_type == MessageType.notify1 and super().body[3] == 0x01:
self.set_body(ECBodyNew(super().body))
- elif (self.message_type == MessageType.set and super().body[3] == 0x02) or \
- (self.message_type == MessageType.query and super().body[3] == 0x03) or \
- (self.message_type == MessageType.notify1 and super().body[3] == 0x04) or \
- (self.message_type == MessageType.notify1 and super().body[3] == 0x3d):
+ elif (
+ (self.message_type == MessageType.set and super().body[3] == 0x02)
+ or (self.message_type == MessageType.query and super().body[3] == 0x03)
+ or (self.message_type == MessageType.notify1 and super().body[3] == 0x04)
+ or (self.message_type == MessageType.notify1 and super().body[3] == 0x3D)
+ ):
self.set_body(ECGeneralMessageBody(super().body))
elif self.message_type == MessageType.notify1 and super().body[3] == 0x06:
self.mode = super().body[4] + (super().body[5] << 8)
diff --git a/custom_components/midea_ac_lan/midea/devices/ed/device.py b/custom_components/midea_ac_lan/midea/devices/ed/device.py
index 3052f861..a25872e5 100644
--- a/custom_components/midea_ac_lan/midea/devices/ed/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/ed/device.py
@@ -1,14 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageEDResponse,
- MessageNewSet,
- MessageOldSet
-)
+
+from .message import MessageEDResponse, MessageNewSet, MessageOldSet, MessageQuery
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -31,17 +29,17 @@ class DeviceAttributes(StrEnum):
class MideaEDDevice(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -65,17 +63,16 @@ def __init__(
DeviceAttributes.life1: None,
DeviceAttributes.life2: None,
DeviceAttributes.life3: None,
- DeviceAttributes.child_lock: False
- })
+ DeviceAttributes.child_lock: False,
+ },
+ )
self._device_class = 0
def _use_new_set(self):
- return True # if (self.sub_type > 342 or self.sub_type == 340) else False
+ return True # if (self.sub_type > 342 or self.sub_type == 340) else False
def build_query(self):
- return [
- MessageQuery(self._protocol_version, self._device_class)
- ]
+ return [MessageQuery(self._protocol_version, self._device_class)]
def process_message(self, msg):
message = MessageEDResponse(msg)
@@ -92,10 +89,7 @@ def process_message(self, msg):
def set_attribute(self, attr, value):
message = None
if self._use_new_set():
- if attr in [
- DeviceAttributes.power,
- DeviceAttributes.child_lock
- ]:
+ if attr in [DeviceAttributes.power, DeviceAttributes.child_lock]:
message = MessageNewSet(self._protocol_version)
else:
if attr in []:
diff --git a/custom_components/midea_ac_lan/midea/devices/ed/message.py b/custom_components/midea_ac_lan/midea/devices/ed/message.py
index 30a5a53b..e843d8af 100644
--- a/custom_components/midea_ac_lan/midea/devices/ed/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/ed/message.py
@@ -1,10 +1,6 @@
from enum import IntEnum
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class NewSetTags(IntEnum):
@@ -15,7 +11,9 @@ class NewSetTags(IntEnum):
class EDNewSetParamPack:
@staticmethod
def pack(param, value, addition=0):
- return bytearray([param & 0xFF, param >> 8, value, addition & 0xFF, addition >> 8])
+ return bytearray(
+ [param & 0xFF, param >> 8, value, addition & 0xFF, addition >> 8]
+ )
class MessageEDBase(MessageRequest):
@@ -24,7 +22,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xED,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -37,7 +35,8 @@ def __init__(self, protocol_version, device_class):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=device_class)
+ body_type=device_class,
+ )
@property
def _body(self):
@@ -49,7 +48,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x15)
+ body_type=0x15,
+ )
self.power = None
self.lock = None
@@ -61,16 +61,14 @@ def _body(self):
pack_count += 1
payload.extend(
EDNewSetParamPack.pack(
- param=NewSetTags.power, # power
- value=0x01 if self.power else 0x00
+ param=NewSetTags.power, value=0x01 if self.power else 0x00 # power
)
)
if self.lock is not None:
pack_count += 1
payload.extend(
EDNewSetParamPack.pack(
- param=NewSetTags.lock, # lock
- value=0x01 if self.lock else 0x00
+ param=NewSetTags.lock, value=0x01 if self.lock else 0x00 # lock
)
)
payload[1] = pack_count
@@ -82,7 +80,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=None)
+ body_type=None,
+ )
@property
def body(self):
@@ -157,10 +156,17 @@ def __init__(self, body):
self.child_lock = (body[data_offset + 5] & 0x01) > 0
self.power = (body[data_offset + 6] & 0x01) > 0
elif attr == 0x011:
- self.water_consumption = float((body[data_offset + 3] +
- (body[data_offset + 4] << 8) +
- (body[data_offset + 5] << 16) +
- (body[data_offset + 6] << 24))) / 1000
+ self.water_consumption = (
+ float(
+ (
+ body[data_offset + 3]
+ + (body[data_offset + 4] << 8)
+ + (body[data_offset + 5] << 16)
+ + (body[data_offset + 6] << 24)
+ )
+ )
+ / 1000
+ )
elif attr == 0x013:
self.in_tds = body[data_offset + 3] + (body[data_offset + 4] << 8)
self.out_tds = body[data_offset + 5] + (body[data_offset + 6] << 8)
diff --git a/custom_components/midea_ac_lan/midea/devices/fa/device.py b/custom_components/midea_ac_lan/midea/devices/fa/device.py
index 58dea3e9..38772c93 100644
--- a/custom_components/midea_ac_lan/midea/devices/fa/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/fa/device.py
@@ -1,14 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageFAResponse,
- MessageSet
-)
+import logging
+
+from .message import MessageFAResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -26,32 +25,45 @@ class DeviceAttributes(StrEnum):
class MideaFADevice(MiedaDevice):
- _oscillation_angles = [
- "Off", "30", "60", "90", "120", "180", "360"
- ]
- _tilting_angles = [
- "Off", "30", "60", "90", "120", "180", "360", "+60", "-60", "40"
- ]
+ _oscillation_angles = ["Off", "30", "60", "90", "120", "180", "360"]
+ _tilting_angles = ["Off", "30", "60", "90", "120", "180", "360", "+60", "-60", "40"]
_oscillation_modes = [
- "Off", "Oscillation", "Tilting", "Curve-W", "Curve-8", "Reserved", "Both"
+ "Off",
+ "Oscillation",
+ "Tilting",
+ "Curve-W",
+ "Curve-8",
+ "Reserved",
+ "Both",
]
_modes = [
- "Normal", "Natural", "Sleep", "Comfort", "Silent", "Baby",
- "Induction", "Circulation", "Strong", "Soft", "Customize", "Warm", "Smart"
+ "Normal",
+ "Natural",
+ "Sleep",
+ "Comfort",
+ "Silent",
+ "Baby",
+ "Induction",
+ "Circulation",
+ "Strong",
+ "Soft",
+ "Customize",
+ "Warm",
+ "Smart",
]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -73,7 +85,8 @@ def __init__(
DeviceAttributes.oscillation_angle: None,
DeviceAttributes.tilting_angle: None,
DeviceAttributes.oscillation_mode: None,
- })
+ },
+ )
self._default_speed_count = 3
self._speed_count = self._default_speed_count
self.set_customize(customize)
@@ -110,7 +123,9 @@ def process_message(self, msg):
value = getattr(message, str(status))
if status == DeviceAttributes.oscillation_angle:
if value < len(MideaFADevice._oscillation_angles):
- self._attributes[status] = MideaFADevice._oscillation_angles[value]
+ self._attributes[status] = MideaFADevice._oscillation_angles[
+ value
+ ]
else:
self._attributes[status] = None
elif status == DeviceAttributes.tilting_angle:
@@ -120,7 +135,9 @@ def process_message(self, msg):
self._attributes[status] = None
elif status == DeviceAttributes.oscillation_mode:
if value < len(MideaFADevice._oscillation_modes):
- self._attributes[status] = MideaFADevice._oscillation_modes[value]
+ self._attributes[status] = MideaFADevice._oscillation_modes[
+ value
+ ]
else:
self._attributes[status] = None
elif status == DeviceAttributes.mode:
@@ -132,7 +149,10 @@ def process_message(self, msg):
self._attributes[status] = value
if not value:
self._attributes[DeviceAttributes.fan_speed] = 0
- elif status == DeviceAttributes.fan_speed and not self._attributes[DeviceAttributes.power]:
+ elif (
+ status == DeviceAttributes.fan_speed
+ and not self._attributes[DeviceAttributes.power]
+ ):
self._attributes[status] = 0
else:
self._attributes[status] = value
@@ -148,20 +168,28 @@ def set_oscillation(self, attr, value):
if value:
message.oscillation_angle = 3 # 90
message.oscillation_mode = 1 # Oscillation
- elif attr == DeviceAttributes.oscillation_mode and \
- (value in MideaFADevice._oscillation_modes or not value):
+ elif attr == DeviceAttributes.oscillation_mode and (
+ value in MideaFADevice._oscillation_modes or not value
+ ):
message = MessageSet(self._protocol_version, self.subtype)
if value == "Off" or not value:
message.oscillate = False
else:
message.oscillate = True
- message.oscillation_mode = MideaFADevice._oscillation_modes.index(value)
+ message.oscillation_mode = MideaFADevice._oscillation_modes.index(
+ value
+ )
if value == "Oscillation":
- if self._attributes[DeviceAttributes.oscillation_angle] == "Off":
+ if (
+ self._attributes[DeviceAttributes.oscillation_angle]
+ == "Off"
+ ):
message.oscillation_angle = 3 # 90
else:
- message.oscillation_angle = MideaFADevice._oscillation_angles.index(
- self._attributes[DeviceAttributes.oscillation_angle]
+ message.oscillation_angle = (
+ MideaFADevice._oscillation_angles.index(
+ self._attributes[DeviceAttributes.oscillation_angle]
+ )
)
elif value == "Tilting":
if self._attributes[DeviceAttributes.tilting_angle] == "Off":
@@ -171,11 +199,16 @@ def set_oscillation(self, attr, value):
self._attributes[DeviceAttributes.tilting_angle]
)
else:
- if self._attributes[DeviceAttributes.oscillation_angle] == "Off":
+ if (
+ self._attributes[DeviceAttributes.oscillation_angle]
+ == "Off"
+ ):
message.oscillation_angle = 3 # 90
else:
- message.oscillation_angle = MideaFADevice._oscillation_angles.index(
- self._attributes[DeviceAttributes.oscillation_angle]
+ message.oscillation_angle = (
+ MideaFADevice._oscillation_angles.index(
+ self._attributes[DeviceAttributes.oscillation_angle]
+ )
)
if self._attributes[DeviceAttributes.tilting_angle] == "Off":
message.tilting_angle = 3 # 90
@@ -183,8 +216,9 @@ def set_oscillation(self, attr, value):
message.tilting_angle = MideaFADevice._tilting_angles.index(
self._attributes[DeviceAttributes.tilting_angle]
)
- elif attr == DeviceAttributes.oscillation_angle and \
- (value in MideaFADevice._oscillation_angles or not value):
+ elif attr == DeviceAttributes.oscillation_angle and (
+ value in MideaFADevice._oscillation_angles or not value
+ ):
message = MessageSet(self._protocol_version, self.subtype)
if value == "Off" or not value:
if self._attributes[DeviceAttributes.tilting_angle] == "Off":
@@ -196,17 +230,22 @@ def set_oscillation(self, attr, value):
self._attributes[DeviceAttributes.tilting_angle]
)
else:
- message.oscillation_angle = MideaFADevice._oscillation_angles.index(value)
+ message.oscillation_angle = MideaFADevice._oscillation_angles.index(
+ value
+ )
message.oscillate = True
if self._attributes[DeviceAttributes.tilting_angle] == "Off":
message.oscillation_mode = 1
- elif self._attributes[DeviceAttributes.oscillation_mode] == "Tilting":
+ elif (
+ self._attributes[DeviceAttributes.oscillation_mode] == "Tilting"
+ ):
message.oscillation_mode = 6
message.tilting_angle = MideaFADevice._tilting_angles.index(
self._attributes[DeviceAttributes.tilting_angle]
)
- elif attr == DeviceAttributes.tilting_angle and \
- (value in MideaFADevice._tilting_angles or not value):
+ elif attr == DeviceAttributes.tilting_angle and (
+ value in MideaFADevice._tilting_angles or not value
+ ):
message = MessageSet(self._protocol_version, self.subtype)
if value == "Off" or not value:
if self._attributes[DeviceAttributes.oscillation_angle] == "Off":
@@ -214,18 +253,25 @@ def set_oscillation(self, attr, value):
else:
message.oscillate = True
message.oscillation_mode = 1
- message.oscillation_angle = MideaFADevice._oscillation_angles.index(
- self._attributes[DeviceAttributes.oscillation_angle]
+ message.oscillation_angle = (
+ MideaFADevice._oscillation_angles.index(
+ self._attributes[DeviceAttributes.oscillation_angle]
+ )
)
else:
message.tilting_angle = MideaFADevice._tilting_angles.index(value)
message.oscillate = True
if self._attributes[DeviceAttributes.oscillation_angle] == "Off":
message.oscillation_mode = 2
- elif self._attributes[DeviceAttributes.oscillation_mode] == "Oscillation":
+ elif (
+ self._attributes[DeviceAttributes.oscillation_mode]
+ == "Oscillation"
+ ):
message.oscillation_mode = 6
- message.oscillation_angle = MideaFADevice._oscillation_angles.index(
- self._attributes[DeviceAttributes.oscillation_angle]
+ message.oscillation_angle = (
+ MideaFADevice._oscillation_angles.index(
+ self._attributes[DeviceAttributes.oscillation_angle]
+ )
)
return message
@@ -235,11 +281,14 @@ def set_attribute(self, attr, value):
DeviceAttributes.oscillate,
DeviceAttributes.oscillation_mode,
DeviceAttributes.oscillation_angle,
- DeviceAttributes.tilting_angle
+ DeviceAttributes.tilting_angle,
]:
message = self.set_oscillation(attr, value)
- elif attr == DeviceAttributes.fan_speed and value > 0 and \
- not self._attributes[DeviceAttributes.power]:
+ elif (
+ attr == DeviceAttributes.fan_speed
+ and value > 0
+ and not self._attributes[DeviceAttributes.power]
+ ):
message = MessageSet(self._protocol_version, self.subtype)
message.fan_speed = value
message.power = True
diff --git a/custom_components/midea_ac_lan/midea/devices/fa/message.py b/custom_components/midea_ac_lan/midea/devices/fa/message.py
index 4153e040..6e11a307 100644
--- a/custom_components/midea_ac_lan/midea/devices/fa/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/fa/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageFABase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xFA,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=None)
+ body_type=None,
+ )
@property
def body(self):
@@ -41,7 +37,8 @@ def __init__(self, protocol_version, subtype):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x00)
+ body_type=0x00,
+ )
self._subtype = subtype
self.power = None
self.lock = None
@@ -55,31 +52,84 @@ def __init__(self, protocol_version, subtype):
@property
def _body(self):
if 1 <= self._subtype <= 10 or self._subtype == 161:
- _body_return = bytearray([
- 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- ])
+ _body_return = bytearray(
+ [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
if self._subtype != 10:
_body_return[13] = 0xFF
else:
- _body_return = bytearray([
- 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00
- ])
+ _body_return = bytearray(
+ [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x80,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
if self.power is not None:
if self.power:
_body_return[3] = 1
@@ -100,9 +150,13 @@ def _body(self):
else:
_body_return[7] = 0
if self.oscillation_angle is not None:
- _body_return[7] = 1 | _body_return[7] | ((self.oscillation_angle << 4) & 0x70)
+ _body_return[7] = (
+ 1 | _body_return[7] | ((self.oscillation_angle << 4) & 0x70)
+ )
if self.oscillation_mode is not None:
- _body_return[7] = 1 | _body_return[7] | ((self.oscillation_mode << 1) & 0x0E)
+ _body_return[7] = (
+ 1 | _body_return[7] | ((self.oscillation_mode << 1) & 0x0E)
+ )
if self.tilting_angle is not None and len(_body_return) > 24:
_body_return[24] = self.tilting_angle
return _body_return
@@ -117,7 +171,7 @@ def __init__(self, body):
else:
self.child_lock = False
self.power = (body[4] & 0x01) > 0
- mode = ((body[4] & 0x1E) >> 1)
+ mode = (body[4] & 0x1E) >> 1
if mode > 0:
self.mode = mode - 1
fan_speed = body[5]
@@ -134,6 +188,10 @@ def __init__(self, body):
class MessageFAResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set, MessageType.notify1]:
+ if self.message_type in [
+ MessageType.query,
+ MessageType.set,
+ MessageType.notify1,
+ ]:
self.set_body(FAGeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/fb/device.py b/custom_components/midea_ac_lan/midea/devices/fb/device.py
index c7b614ab..c5ae1887 100644
--- a/custom_components/midea_ac_lan/midea/devices/fb/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/fb/device.py
@@ -1,13 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageFBResponse,
- MessageSet
-)
+
+from .message import MessageFBResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -23,22 +22,30 @@ class DeviceAttributes(StrEnum):
class MideaFBDevice(MiedaDevice):
- _modes = {0x01: "Auto", 0x02: "ECO", 0x03: "Sleep",
- 0x04: "Anti-freezing", 0x05: "Comfort", 0x06: "Constant-temperature",
- 0x07: "Normal", 0x08: "Fast-heating", 0x10: "Standby"}
+ _modes = {
+ 0x01: "Auto",
+ 0x02: "ECO",
+ 0x03: "Sleep",
+ 0x04: "Anti-freezing",
+ 0x05: "Comfort",
+ 0x06: "Constant-temperature",
+ 0x07: "Normal",
+ 0x08: "Fast-heating",
+ 0x10: "Standby",
+ }
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -58,7 +65,8 @@ def __init__(
DeviceAttributes.target_temperature: None,
DeviceAttributes.current_temperature: None,
DeviceAttributes.child_lock: False,
- })
+ },
+ )
@property
def modes(self):
diff --git a/custom_components/midea_ac_lan/midea/devices/fb/message.py b/custom_components/midea_ac_lan/midea/devices/fb/message.py
index 2fe89860..57e613d9 100644
--- a/custom_components/midea_ac_lan/midea/devices/fb/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/fb/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageFBBase(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xFB,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=None)
+ body_type=None,
+ )
@property
def body(self):
@@ -41,7 +37,8 @@ def __init__(self, protocol_version, subtype):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x00)
+ body_type=0x00,
+ )
self._subtype = subtype
self.power = None
self.mode = None
@@ -53,24 +50,52 @@ def __init__(self, protocol_version, subtype):
def body(self):
power = 0 if self.power is None else (0x01 if self.power else 0x02)
mode = 0 if self.mode is None else self.mode
- heating_level = 0 if self.heating_level is None else \
- (int(self.heating_level if 1 <= self.heating_level <= 10 else 0) & 0xFF)
- target_temperature = 0 if self.target_temperature is None else \
- (int((self.target_temperature + 41) if -40 <= self.target_temperature <= 50 else
- (0x80 if self.target_temperature in [0x80, 87] else 0)) & 0xFF)
- child_lock = 0xFF if self.child_lock is None else (0x01 if self.child_lock else 0x00)
- _return_body = bytearray([
- power,
- 0x00, 0x00, 0x00,
- mode,
- heating_level,
- target_temperature,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00,
- child_lock,
- 0x00
- ])
+ heating_level = (
+ 0
+ if self.heating_level is None
+ else (
+ int(self.heating_level if 1 <= self.heating_level <= 10 else 0) & 0xFF
+ )
+ )
+ target_temperature = (
+ 0
+ if self.target_temperature is None
+ else (
+ int(
+ (self.target_temperature + 41)
+ if -40 <= self.target_temperature <= 50
+ else (0x80 if self.target_temperature in [0x80, 87] else 0)
+ )
+ & 0xFF
+ )
+ )
+ child_lock = (
+ 0xFF if self.child_lock is None else (0x01 if self.child_lock else 0x00)
+ )
+ _return_body = bytearray(
+ [
+ power,
+ 0x00,
+ 0x00,
+ 0x00,
+ mode,
+ heating_level,
+ target_temperature,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ child_lock,
+ 0x00,
+ ]
+ )
if self._subtype > 5:
_return_body += bytearray([0x00, 0x00, 0x00])
return _return_body
@@ -100,6 +125,10 @@ def __init__(self, body):
class MessageFBResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set, MessageType.notify1]:
+ if self.message_type in [
+ MessageType.query,
+ MessageType.set,
+ MessageType.notify1,
+ ]:
self.set_body(FBGeneralMessageBody(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/fc/device.py b/custom_components/midea_ac_lan/midea/devices/fc/device.py
index e4282516..fad4f23d 100644
--- a/custom_components/midea_ac_lan/midea/devices/fc/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/fc/device.py
@@ -1,14 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageFCResponse,
- MessageSet
-)
+import logging
+
+from .message import MessageFCResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -33,28 +32,29 @@ class DeviceAttributes(StrEnum):
class MideaFCDevice(MiedaDevice):
_modes = {
- 0x00: "Standby", 0x10: "Auto", 0x20: "Manual", 0x30: "Sleep", 0x40: "Fast", 0x50: "Smoke"
- }
- _speeds = {
- 1: "Auto", 4: "Standby", 39: "Low", 59: "Medium", 80: "High"
- }
- _screen_displays = {
- 0: "Bright", 6: "Dim", 7: "Off"
+ 0x00: "Standby",
+ 0x10: "Auto",
+ 0x20: "Manual",
+ 0x30: "Sleep",
+ 0x40: "Fast",
+ 0x50: "Smoke",
}
+ _speeds = {1: "Auto", 4: "Standby", 39: "Low", 59: "Medium", 80: "High"}
+ _screen_displays = {0: "Bright", 6: "Dim", 7: "Off"}
_detect_modes = ["Off", "PM 2.5", "Methanal"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -82,7 +82,8 @@ def __init__(
DeviceAttributes.prompt_tone: True,
DeviceAttributes.filter1_life: None,
DeviceAttributes.filter2_life: None,
- })
+ },
+ )
self._standby_detect_default = [40, 20]
self._standby_detect = self._standby_detect_default
@@ -126,7 +127,9 @@ def process_message(self, msg):
self._attributes[status] = None
elif status == DeviceAttributes.screen_display:
if value in MideaFCDevice._screen_displays.keys():
- self._attributes[status] = MideaFCDevice._screen_displays.get(value)
+ self._attributes[status] = MideaFCDevice._screen_displays.get(
+ value
+ )
else:
self._attributes[status] = None
elif status == DeviceAttributes.detect_mode:
@@ -148,20 +151,40 @@ def make_message_set(self):
message.anion = self._attributes[DeviceAttributes.anion]
message.standby = self._attributes[DeviceAttributes.standby]
message.screen_display = self._attributes[DeviceAttributes.screen_display]
- message.detect_mode = 0 if self._attributes[DeviceAttributes.detect_mode] is None else \
- MideaFCDevice._detect_modes.index(self._attributes[DeviceAttributes.detect_mode])
- message.mode = 0x10 if self._attributes[DeviceAttributes.mode] is None else \
- list(MideaFCDevice._modes.keys())[list(MideaFCDevice._modes.values()).index(
- self._attributes[DeviceAttributes.mode]
- )]
- message.fan_speed = 39 if self._attributes[DeviceAttributes.fan_speed] is None else \
- list(MideaFCDevice._speeds.keys())[list(MideaFCDevice._speeds.values()).index(
- self._attributes[DeviceAttributes.fan_speed]
- )]
- message.screen_display = 0 if self._attributes[DeviceAttributes.screen_display] is None else \
- list(MideaFCDevice._screen_displays.keys())[list(MideaFCDevice._screen_displays.values()).index(
- self._attributes[DeviceAttributes.screen_display]
- )]
+ message.detect_mode = (
+ 0
+ if self._attributes[DeviceAttributes.detect_mode] is None
+ else MideaFCDevice._detect_modes.index(
+ self._attributes[DeviceAttributes.detect_mode]
+ )
+ )
+ message.mode = (
+ 0x10
+ if self._attributes[DeviceAttributes.mode] is None
+ else list(MideaFCDevice._modes.keys())[
+ list(MideaFCDevice._modes.values()).index(
+ self._attributes[DeviceAttributes.mode]
+ )
+ ]
+ )
+ message.fan_speed = (
+ 39
+ if self._attributes[DeviceAttributes.fan_speed] is None
+ else list(MideaFCDevice._speeds.keys())[
+ list(MideaFCDevice._speeds.values()).index(
+ self._attributes[DeviceAttributes.fan_speed]
+ )
+ ]
+ )
+ message.screen_display = (
+ 0
+ if self._attributes[DeviceAttributes.screen_display] is None
+ else list(MideaFCDevice._screen_displays.keys())[
+ list(MideaFCDevice._screen_displays.values()).index(
+ self._attributes[DeviceAttributes.screen_display]
+ )
+ ]
+ )
message.standby_detect = self._standby_detect
return message
@@ -183,9 +206,9 @@ def set_attribute(self, attr, value):
]
elif attr == DeviceAttributes.screen_display:
if value in MideaFCDevice._screen_displays.values():
- message.screen_display = list(MideaFCDevice._screen_displays.keys())[
- list(MideaFCDevice._screen_displays.values()).index(value)
- ]
+ message.screen_display = list(
+ MideaFCDevice._screen_displays.keys()
+ )[list(MideaFCDevice._screen_displays.values()).index(value)]
elif not value:
message.screen_display = 7
elif attr == DeviceAttributes.detect_mode:
diff --git a/custom_components/midea_ac_lan/midea/devices/fc/message.py b/custom_components/midea_ac_lan/midea/devices/fc/message.py
index febbfbaa..db391f8e 100644
--- a/custom_components/midea_ac_lan/midea/devices/fc/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/fc/message.py
@@ -1,10 +1,5 @@
from ...core.crc8 import calculate
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageFCBase(MessageRequest):
@@ -15,7 +10,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xFC,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
MessageFCBase._message_serial += 1
if MessageFCBase._message_serial >= 254:
@@ -38,17 +33,34 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x41)
+ body_type=0x41,
+ )
@property
def _body(self):
- return bytearray([
- 0x00, 0x00, 0xFF, 0x03,
- 0x00, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
- ])
+ return bytearray(
+ [
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0x03,
+ 0x00,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessageSet(MessageFCBase):
@@ -56,7 +68,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x48)
+ body_type=0x48,
+ )
self.power = False
self.mode = 0
self.fan_speed = 0
@@ -91,16 +104,30 @@ def _body(self):
standby = 0x08
standby_detect_high = 0
standby_detect_low = 0
- return bytearray([
- power | prompt_tone | detect | 0x02,
- self.mode,
- self.fan_speed,
- 0x00, 0x00, 0x00, 0x00,
- child_lock, self.screen_display, anion,
- 0x00, 0x00, 0x00, detect_mode,
- standby, standby_detect_high, standby_detect_low,
- 0x00, 0x00, 0x00,
- ])
+ return bytearray(
+ [
+ power | prompt_tone | detect | 0x02,
+ self.mode,
+ self.fan_speed,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ child_lock,
+ self.screen_display,
+ anion,
+ 0x00,
+ 0x00,
+ 0x00,
+ detect_mode,
+ standby,
+ standby_detect_high,
+ standby_detect_low,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class FCGeneralMessageBody(MessageBody):
@@ -171,8 +198,11 @@ def __init__(self, message):
if self.body_type in [0xB0, 0xB1]:
pass
else:
- if self.message_type in [MessageType.query, MessageType.set, MessageType.notify1] and \
- self.body_type == 0xC8:
+ if (
+ self.message_type
+ in [MessageType.query, MessageType.set, MessageType.notify1]
+ and self.body_type == 0xC8
+ ):
self.set_body(FCGeneralMessageBody(super().body))
elif self.message_type == MessageType.notify1 and self.body_type == 0xA0:
self.set_body(FCNotifyMessageBody(super().body))
diff --git a/custom_components/midea_ac_lan/midea/devices/fd/device.py b/custom_components/midea_ac_lan/midea/devices/fd/device.py
index b3f010ff..82dfc063 100644
--- a/custom_components/midea_ac_lan/midea/devices/fd/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/fd/device.py
@@ -1,13 +1,12 @@
import logging
-from .message import (
- MessageQuery,
- MessageFDResponse,
- MessageSet
-)
+
+from .message import MessageFDResponse, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -28,31 +27,45 @@ class DeviceAttributes(StrEnum):
class MideaFDDevice(MiedaDevice):
_modes = [
- "Manual", "Auto", "Continuous", "Living-Room", "Bed-Room", "Kitchen", "Sleep"
+ "Manual",
+ "Auto",
+ "Continuous",
+ "Living-Room",
+ "Bed-Room",
+ "Kitchen",
+ "Sleep",
]
_speeds_old = {
- 1: "Lowest", 40: "Low", 60: "Medium", 80: "High", 102: "Auto", 127: "Off"
+ 1: "Lowest",
+ 40: "Low",
+ 60: "Medium",
+ 80: "High",
+ 102: "Auto",
+ 127: "Off",
}
_speeds_new = {
- 1: "Lowest", 39: "Low", 59: "Medium", 80: "High", 101: "Auto", 127: "Off"
- }
- _screen_displays = {
- 0: "Bright", 6: "Dim", 7: "Off"
+ 1: "Lowest",
+ 39: "Low",
+ 59: "Medium",
+ 80: "High",
+ 101: "Auto",
+ 127: "Off",
}
+ _screen_displays = {0: "Bright", 6: "Dim", 7: "Off"}
_detect_modes = ["Off", "PM 2.5", "Methanal"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -76,7 +89,8 @@ def __init__(
DeviceAttributes.mode: None,
DeviceAttributes.screen_display: None,
DeviceAttributes.disinfect: None,
- })
+ },
+ )
if self.subtype > 5:
self._speeds = MideaFDDevice._speeds_new
else:
@@ -121,7 +135,9 @@ def process_message(self, msg):
self._attributes[status] = None
elif status == DeviceAttributes.screen_display:
if value in MideaFDDevice._screen_displays.keys():
- self._attributes[status] = MideaFDDevice._screen_displays.get(value)
+ self._attributes[status] = MideaFDDevice._screen_displays.get(
+ value
+ )
else:
self._attributes[status] = None
else:
@@ -136,17 +152,29 @@ def make_message_set(self):
message.screen_display = self._attributes[DeviceAttributes.screen_display]
message.disinfect = self._attributes[DeviceAttributes.disinfect]
if self._attributes[DeviceAttributes.mode] in MideaFDDevice._modes:
- message.mode = MideaFDDevice._modes.index(self._attributes[DeviceAttributes.mode]) + 1
+ message.mode = (
+ MideaFDDevice._modes.index(self._attributes[DeviceAttributes.mode]) + 1
+ )
else:
message.mode = 1
- message.fan_speed = 40 if self._attributes[DeviceAttributes.fan_speed] is None else \
- list(self._speeds.keys())[list(self._speeds.values()).index(
- self._attributes[DeviceAttributes.fan_speed]
- )]
- message.screen_display = 0 if self._attributes[DeviceAttributes.screen_display] is None else \
- list(MideaFDDevice._screen_displays.keys())[list(MideaFDDevice._screen_displays.values()).index(
- self._attributes[DeviceAttributes.screen_display]
- )]
+ message.fan_speed = (
+ 40
+ if self._attributes[DeviceAttributes.fan_speed] is None
+ else list(self._speeds.keys())[
+ list(self._speeds.values()).index(
+ self._attributes[DeviceAttributes.fan_speed]
+ )
+ ]
+ )
+ message.screen_display = (
+ 0
+ if self._attributes[DeviceAttributes.screen_display] is None
+ else list(MideaFDDevice._screen_displays.keys())[
+ list(MideaFDDevice._screen_displays.values()).index(
+ self._attributes[DeviceAttributes.screen_display]
+ )
+ ]
+ )
return message
def set_attribute(self, attr, value):
@@ -165,9 +193,9 @@ def set_attribute(self, attr, value):
]
elif attr == DeviceAttributes.screen_display:
if value in MideaFDDevice._screen_displays.values():
- message.screen_display = list(MideaFDDevice._screen_displays.keys())[
- list(MideaFDDevice._screen_displays.values()).index(value)
- ]
+ message.screen_display = list(
+ MideaFDDevice._screen_displays.keys()
+ )[list(MideaFDDevice._screen_displays.values()).index(value)]
elif not value:
message.screen_display = 7
else:
diff --git a/custom_components/midea_ac_lan/midea/devices/fd/message.py b/custom_components/midea_ac_lan/midea/devices/fd/message.py
index d5402bff..39aa6ec1 100644
--- a/custom_components/midea_ac_lan/midea/devices/fd/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/fd/message.py
@@ -1,10 +1,5 @@
from ...core.crc8 import calculate
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class MessageFDBase(MessageRequest):
@@ -15,7 +10,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0xFD,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
MessageFDBase._message_serial += 1
if MessageFDBase._message_serial >= 254:
@@ -38,17 +33,34 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x41)
+ body_type=0x41,
+ )
@property
def _body(self):
- return bytearray([
- 0x81, 0x00, 0xFF, 0x03,
- 0x00, 0x00, 0x02, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00
- ])
+ return bytearray(
+ [
+ 0x81,
+ 0x00,
+ 0xFF,
+ 0x03,
+ 0x00,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class MessageSet(MessageFDBase):
@@ -56,7 +68,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x48)
+ body_type=0x48,
+ )
self.power = False
self.fan_speed = 0
self.target_humidity = 50
@@ -70,20 +83,31 @@ def _body(self):
power = 0x01 if self.power else 0x00
prompt_tone = 0x40 if self.prompt_tone else 0x00
disinfect = 0 if self.disinfect is None else (1 if self.disinfect else 2)
- return bytearray([
- power | prompt_tone | 0x02,
- 0x00,
- self.fan_speed,
- 0x00, 0x00, 0x00,
- self.target_humidity,
- 0x00,
- self.screen_display,
- self.mode,
- 0x00, 0x00, 0x00, 0x00,
- disinfect,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- ])
+ return bytearray(
+ [
+ power | prompt_tone | 0x02,
+ 0x00,
+ self.fan_speed,
+ 0x00,
+ 0x00,
+ 0x00,
+ self.target_humidity,
+ 0x00,
+ self.screen_display,
+ self.mode,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ disinfect,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ ]
+ )
class FDC8MessageBody(MessageBody):
@@ -127,7 +151,11 @@ def __init__(self, body):
class MessageFDResponse(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.query, MessageType.set, MessageType.notify1]:
+ if self.message_type in [
+ MessageType.query,
+ MessageType.set,
+ MessageType.notify1,
+ ]:
if self.body_type in [0xB0, 0xB1]:
pass
elif self.body_type == 0xA0:
@@ -135,5 +163,9 @@ def __init__(self, message):
elif self.body_type == 0xC8:
self.set_body(FDC8MessageBody(super().body))
self.set_attr()
- if hasattr(self, "fan_speed") and self.fan_speed is not None and self.fan_speed < 5:
+ if (
+ hasattr(self, "fan_speed")
+ and self.fan_speed is not None
+ and self.fan_speed < 5
+ ):
self.fan_speed = 1
diff --git a/custom_components/midea_ac_lan/midea/devices/x13/device.py b/custom_components/midea_ac_lan/midea/devices/x13/device.py
index d719ad1f..cc019d20 100644
--- a/custom_components/midea_ac_lan/midea/devices/x13/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/x13/device.py
@@ -1,14 +1,13 @@
-import logging
import json
-from .message import (
- MessageQuery,
- MessageSet,
- Message13Response
-)
+import logging
+
+from .message import Message13Response, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -26,17 +25,17 @@ class Midea13Device(MiedaDevice):
_effects = ["Manual", "Living", "Reading", "Mildly", "Cinema", "Night"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -54,8 +53,9 @@ def __init__(
DeviceAttributes.color_temperature: None,
DeviceAttributes.rgb_color: None,
DeviceAttributes.effect: None,
- DeviceAttributes.power: False
- })
+ DeviceAttributes.power: False,
+ },
+ )
self._color_temp_range = None
self._default_color_temp_range = [2700, 6500]
self.set_customize(customize)
@@ -69,12 +69,17 @@ def color_temp_range(self):
return self._color_temp_range
def kelvin_to_midea(self, kelvin):
- return round((kelvin - self._color_temp_range[0]) /
- (self._color_temp_range[1] - self._color_temp_range[0]) * 255)
+ return round(
+ (kelvin - self._color_temp_range[0])
+ / (self._color_temp_range[1] - self._color_temp_range[0])
+ * 255
+ )
def midea_to_kelvin(self, midea):
- return round((self._color_temp_range[1] - self._color_temp_range[0]) / 255 * midea) + \
- self._color_temp_range[0]
+ return (
+ round((self._color_temp_range[1] - self._color_temp_range[0]) / 255 * midea)
+ + self._color_temp_range[0]
+ )
def build_query(self):
return [MessageQuery(self._protocol_version)]
@@ -101,10 +106,12 @@ def process_message(self, msg):
return new_status
def set_attribute(self, attr, value):
- if attr in [DeviceAttributes.brightness,
- DeviceAttributes.color_temperature,
- DeviceAttributes.effect,
- DeviceAttributes.power]:
+ if attr in [
+ DeviceAttributes.brightness,
+ DeviceAttributes.color_temperature,
+ DeviceAttributes.effect,
+ DeviceAttributes.power,
+ ]:
message = MessageSet(self._protocol_version)
if attr == DeviceAttributes.effect and value in self._effects:
setattr(message, str(attr), Midea13Device._effects.index(value))
diff --git a/custom_components/midea_ac_lan/midea/devices/x13/message.py b/custom_components/midea_ac_lan/midea/devices/x13/message.py
index ce8e3699..fb208a11 100644
--- a/custom_components/midea_ac_lan/midea/devices/x13/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/x13/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class Message13Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0x13,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,13 +20,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x24)
+ body_type=0x24,
+ )
@property
def _body(self):
- return bytearray([
- 0x00, 0x00, 0x00, 0x00
- ])
+ return bytearray([0x00, 0x00, 0x00, 0x00])
class MessageSet(Message13Base):
@@ -39,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x00)
+ body_type=0x00,
+ )
self.brightness = None
self.color_temperature = None
self.effect = None
@@ -71,11 +66,11 @@ def __init__(self, body):
self.effect = self.read_byte(body, 3) - 1
if self.effect > 5:
self.effect = 1
- '''
+ """
self.rgb_color = [self.read_byte(body, 5),
self.read_byte(body, 6),
self.read_byte(body, 7)]
- '''
+ """
self.power = self.read_byte(body, 8) > 0
@@ -88,7 +83,7 @@ def __init__(self, body):
class Message13Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.body_type == 0xa4:
+ if self.body_type == 0xA4:
self.set_body(MessageMainLightBody(super().body))
elif self.message_type == MessageType.set and self.body_type > 0x80:
self.set_body(MessageMainLightResponseBody(super().body))
diff --git a/custom_components/midea_ac_lan/midea/devices/x26/device.py b/custom_components/midea_ac_lan/midea/devices/x26/device.py
index 2230154e..b01c67b5 100644
--- a/custom_components/midea_ac_lan/midea/devices/x26/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/x26/device.py
@@ -1,14 +1,13 @@
import logging
import math
-from .message import (
- MessageQuery,
- MessageSet,
- Message26Response
-)
+
+from .message import Message26Response, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -29,17 +28,17 @@ class Midea26Device(MiedaDevice):
_directions = ["60", "70", "80", "90", "100", "110", "120", "Oscillate"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -59,8 +58,9 @@ def __init__(
DeviceAttributes.direction: None,
DeviceAttributes.current_humidity: None,
DeviceAttributes.current_radar: None,
- DeviceAttributes.current_temperature: None
- })
+ DeviceAttributes.current_temperature: None,
+ },
+ )
self._fields = {}
@staticmethod
@@ -68,8 +68,11 @@ def _convert_to_midea_direction(direction):
if direction == "Oscillate":
result = 0xFD
else:
- result = Midea26Device._directions.index(direction) * 10 + 60 \
- if direction in Midea26Device._directions else 0xFD
+ result = (
+ Midea26Device._directions.index(direction) * 10 + 60
+ if direction in Midea26Device._directions
+ else 0xFD
+ )
return result
@staticmethod
@@ -111,21 +114,23 @@ def process_message(self, msg):
return new_status
def set_attribute(self, attr, value):
- if attr in [DeviceAttributes.main_light,
- DeviceAttributes.night_light,
- DeviceAttributes.mode,
- DeviceAttributes.direction
- ]:
+ if attr in [
+ DeviceAttributes.main_light,
+ DeviceAttributes.night_light,
+ DeviceAttributes.mode,
+ DeviceAttributes.direction,
+ ]:
message = MessageSet(self._protocol_version)
message.fields = self._fields
message.main_light = self._attributes[DeviceAttributes.main_light]
message.night_light = self._attributes[DeviceAttributes.night_light]
- message.mode = Midea26Device._modes.index(self._attributes[DeviceAttributes.mode])
- message.direction = self._convert_to_midea_direction(self._attributes[DeviceAttributes.direction])
- if attr in [
- DeviceAttributes.main_light,
- DeviceAttributes.night_light
- ]:
+ message.mode = Midea26Device._modes.index(
+ self._attributes[DeviceAttributes.mode]
+ )
+ message.direction = self._convert_to_midea_direction(
+ self._attributes[DeviceAttributes.direction]
+ )
+ if attr in [DeviceAttributes.main_light, DeviceAttributes.night_light]:
message.main_light = False
message.night_light = False
setattr(message, str(attr), value)
diff --git a/custom_components/midea_ac_lan/midea/devices/x26/message.py b/custom_components/midea_ac_lan/midea/devices/x26/message.py
index f0afd96c..51026d3a 100644
--- a/custom_components/midea_ac_lan/midea/devices/x26/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/x26/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class Message26Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0x26,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,12 +20,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
- return bytearray([
- ])
+ return bytearray([])
class MessageSet(Message26Base):
@@ -38,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x01)
+ body_type=0x01,
+ )
self.fields = {}
self.main_light = False
self.night_light = False
@@ -51,47 +47,53 @@ def read_field(self, field):
@property
def _body(self):
- return bytearray([
- 1 if self.main_light else 0,
- self.read_field("MAIN_LIGHT_BRIGHTNESS"),
- 1 if self.night_light else 0,
- self.read_field("NIGHT_LIGHT_BRIGHTNESS"),
- self.read_field("RADAR_INDUCTION_ENABLE"),
- self.read_field("RADAR_INDUCTION_CLOSING_TIME"),
- self.read_field("LIGHT_INTENSITY_THRESHOLD"),
- self.read_field("RADAR_SENSITIVITY"),
- 1 if self.mode == 1 or self.mode == 2 else 0,
- 0 if not (self.mode == 1 or self.mode == 2) else 55 if self.mode == 1 else 30,
- self.read_field("HEATING_SPEED"),
- self.direction,
- 1 if self.mode == 3 else 0,
- self.read_field("BATH_HEATING_TIME"),
- self.read_field("BATH_TEMPERATURE"),
- self.read_field("BATH_SPEED"),
- self.direction,
- 1 if self.mode == 5 else 0,
- self.read_field("VENTILATION_SPEED"),
- self.direction,
- 1 if self.mode == 6 else 0,
- self.read_field("DRYING_TIME"),
- self.read_field("DRYING_TEMPERATURE"),
- self.read_field("DRYING_SPEED"),
- self.direction,
- 1 if self.mode == 4 else 0,
- self.read_field("BLOWING_SPEED"),
- self.direction,
- self.read_field("DELAY_ENABLE"),
- self.read_field("DELAY_TIME"),
- self.read_field("SOFT_WIND_ENABLE"),
- self.read_field("SOFT_WIND_TIME"),
- self.read_field("SOFT_WIND_TEMPERATURE"),
- self.read_field("SOFT_WIND_SPEED"),
- self.read_field("SOFT_WIND_DIRECTION"),
- self.read_field("WINDLESS_ENABLE"),
- self.read_field("ANION_ENABLE"),
- self.read_field("SMELLY_ENABLE"),
- self.read_field("SMELLY_THRESHOLD")
- ])
+ return bytearray(
+ [
+ 1 if self.main_light else 0,
+ self.read_field("MAIN_LIGHT_BRIGHTNESS"),
+ 1 if self.night_light else 0,
+ self.read_field("NIGHT_LIGHT_BRIGHTNESS"),
+ self.read_field("RADAR_INDUCTION_ENABLE"),
+ self.read_field("RADAR_INDUCTION_CLOSING_TIME"),
+ self.read_field("LIGHT_INTENSITY_THRESHOLD"),
+ self.read_field("RADAR_SENSITIVITY"),
+ 1 if self.mode == 1 or self.mode == 2 else 0,
+ (
+ 0
+ if not (self.mode == 1 or self.mode == 2)
+ else 55 if self.mode == 1 else 30
+ ),
+ self.read_field("HEATING_SPEED"),
+ self.direction,
+ 1 if self.mode == 3 else 0,
+ self.read_field("BATH_HEATING_TIME"),
+ self.read_field("BATH_TEMPERATURE"),
+ self.read_field("BATH_SPEED"),
+ self.direction,
+ 1 if self.mode == 5 else 0,
+ self.read_field("VENTILATION_SPEED"),
+ self.direction,
+ 1 if self.mode == 6 else 0,
+ self.read_field("DRYING_TIME"),
+ self.read_field("DRYING_TEMPERATURE"),
+ self.read_field("DRYING_SPEED"),
+ self.direction,
+ 1 if self.mode == 4 else 0,
+ self.read_field("BLOWING_SPEED"),
+ self.direction,
+ self.read_field("DELAY_ENABLE"),
+ self.read_field("DELAY_TIME"),
+ self.read_field("SOFT_WIND_ENABLE"),
+ self.read_field("SOFT_WIND_TIME"),
+ self.read_field("SOFT_WIND_TEMPERATURE"),
+ self.read_field("SOFT_WIND_SPEED"),
+ self.read_field("SOFT_WIND_DIRECTION"),
+ self.read_field("WINDLESS_ENABLE"),
+ self.read_field("ANION_ENABLE"),
+ self.read_field("SMELLY_ENABLE"),
+ self.read_field("SMELLY_THRESHOLD"),
+ ]
+ )
class Message26Body(MessageBody):
@@ -168,6 +170,10 @@ def __init__(self, body):
class Message26Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.set, MessageType.notify1, MessageType.query] and self.body_type == 0x01:
+ if (
+ self.message_type
+ in [MessageType.set, MessageType.notify1, MessageType.query]
+ and self.body_type == 0x01
+ ):
self.set_body(Message26Body(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/x34/device.py b/custom_components/midea_ac_lan/midea/devices/x34/device.py
index a1cb1ef7..76e8f303 100644
--- a/custom_components/midea_ac_lan/midea/devices/x34/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/x34/device.py
@@ -1,15 +1,18 @@
import logging
+
from .message import (
- MessageQuery,
+ Message34Response,
+ MessageLock,
MessagePower,
+ MessageQuery,
MessageStorage,
- MessageLock,
- Message34Response
)
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -44,17 +47,17 @@ class DeviceAttributes(StrEnum):
class Midea34Device(MiedaDevice):
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -91,31 +94,32 @@ def __init__(
DeviceAttributes.error_code: None,
DeviceAttributes.softwater: 0,
DeviceAttributes.wrong_operation: None,
- DeviceAttributes.bright: 0
- })
+ DeviceAttributes.bright: 0,
+ },
+ )
self._modes = {
- 0x0: "Neutral Gear", # BYTE_MODE_NEUTRAL_GEAR
- 0x1: "Auto", # BYTE_MODE_AUTO_WASH
- 0x2: "Heavy", # BYTE_MODE_STRONG_WASH
- 0x3: "Normal", # BYTE_MODE_STANDARD_WASH
- 0x4: "Energy Saving", # BYTE_MODE_ECO_WASH
- 0x5: "Delicate", # BYTE_MODE_GLASS_WASH
- 0x6: "Hour", # BYTE_MODE_HOUR_WASH
- 0x7: "Quick", # BYTE_MODE_FAST_WASH
- 0x8: "Rinse", # BYTE_MODE_SOAK_WASH
- 0x9: "90min", # BYTE_MODE_90MIN_WASH
- 0xA: "Self Clean", # BYTE_MODE_SELF_CLEAN
- 0xB: "Fruit Wash", # BYTE_MODE_FRUIT_WASH
- 0xC: "Self Define", # BYTE_MODE_SELF_DEFINE
- 0xD: "Germ", # BYTE_MODE_GERM ???
- 0xE: "Bowl Wash", # BYTE_MODE_BOWL_WASH
- 0xF: "Kill Germ", # BYTE_MODE_KILL_GERM
- 0x10: "Sea Food Wash", # BYTE_MODE_SEA_FOOD_WASH
- 0x12: "Hot Pot Wash", # BYTE_MODE_HOT_POT_WASH
- 0x13: "Quiet", # BYTE_MODE_QUIET_NIGHT_WASH
- 0x14: "Less Wash", # BYTE_MODE_LESS_WASH
- 0x16: "Oil Net Wash", # BYTE_MODE_OIL_NET_WASH
- 0x19: "Cloud Wash" # BYTE_MODE_CLOUD_WASH
+ 0x0: "Neutral Gear", # BYTE_MODE_NEUTRAL_GEAR
+ 0x1: "Auto", # BYTE_MODE_AUTO_WASH
+ 0x2: "Heavy", # BYTE_MODE_STRONG_WASH
+ 0x3: "Normal", # BYTE_MODE_STANDARD_WASH
+ 0x4: "Energy Saving", # BYTE_MODE_ECO_WASH
+ 0x5: "Delicate", # BYTE_MODE_GLASS_WASH
+ 0x6: "Hour", # BYTE_MODE_HOUR_WASH
+ 0x7: "Quick", # BYTE_MODE_FAST_WASH
+ 0x8: "Rinse", # BYTE_MODE_SOAK_WASH
+ 0x9: "90min", # BYTE_MODE_90MIN_WASH
+ 0xA: "Self Clean", # BYTE_MODE_SELF_CLEAN
+ 0xB: "Fruit Wash", # BYTE_MODE_FRUIT_WASH
+ 0xC: "Self Define", # BYTE_MODE_SELF_DEFINE
+ 0xD: "Germ", # BYTE_MODE_GERM ???
+ 0xE: "Bowl Wash", # BYTE_MODE_BOWL_WASH
+ 0xF: "Kill Germ", # BYTE_MODE_KILL_GERM
+ 0x10: "Sea Food Wash", # BYTE_MODE_SEA_FOOD_WASH
+ 0x12: "Hot Pot Wash", # BYTE_MODE_HOT_POT_WASH
+ 0x13: "Quiet", # BYTE_MODE_QUIET_NIGHT_WASH
+ 0x14: "Less Wash", # BYTE_MODE_LESS_WASH
+ 0x16: "Oil Net Wash", # BYTE_MODE_OIL_NET_WASH
+ 0x19: "Cloud Wash", # BYTE_MODE_CLOUD_WASH
}
self._status = ["Off", "Idle", "Delay", "Running", "Error"]
self._progress = ["Idle", "Pre-wash", "Wash", "Rinse", "Dry", "Complete"]
diff --git a/custom_components/midea_ac_lan/midea/devices/x34/message.py b/custom_components/midea_ac_lan/midea/devices/x34/message.py
index 729280f1..c107acd2 100644
--- a/custom_components/midea_ac_lan/midea/devices/x34/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/x34/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody,
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class Message34Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0x34,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,7 +20,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x00)
+ body_type=0x00,
+ )
@property
def _body(self):
@@ -37,16 +33,14 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x08)
+ body_type=0x08,
+ )
self.power = False
@property
def _body(self):
power = 0x01 if self.power else 0x00
- return bytearray([
- power,
- 0x00, 0x00, 0x00
- ])
+ return bytearray([power, 0x00, 0x00, 0x00])
class MessageLock(Message34Base):
@@ -54,7 +48,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x83)
+ body_type=0x83,
+ )
self.lock = False
@property
@@ -68,14 +63,18 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x81)
+ body_type=0x81,
+ )
self.storage = False
@property
def _body(self):
storage = 0x01 if self.storage else 0x00
- return bytearray([0x00, 0x00, 0x00, storage]) + \
- bytearray([0xff] * 6) + bytearray([0x00] * 27)
+ return (
+ bytearray([0x00, 0x00, 0x00, storage])
+ + bytearray([0xFF] * 6)
+ + bytearray([0x00] * 27)
+ )
class Message34Body(MessageBody):
@@ -85,9 +84,9 @@ def __init__(self, body):
self.status = body[1]
self.mode = body[2]
self.additional = body[3]
- self.door = (body[5] & 0x01) == 0 # 0 - open, 1 - close
- self.rinse_aid = (body[5] & 0x02) > 0 # 0 - enough, 1 - shortage
- self.salt = (body[5] & 0x04) > 0 # 0 - enough, 1 - shortage
+ self.door = (body[5] & 0x01) == 0 # 0 - open, 1 - close
+ self.rinse_aid = (body[5] & 0x02) > 0 # 0 - enough, 1 - shortage
+ self.salt = (body[5] & 0x04) > 0 # 0 - enough, 1 - shortage
start_pause = (body[5] & 0x08) > 0
if start_pause:
self.start = True
@@ -115,7 +114,9 @@ def __init__(self, body):
class Message34Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if (self.message_type == MessageType.set and 0 <= self.body_type <= 7) or \
- (self.message_type in [MessageType.query, MessageType.notify1] and self.body_type == 0):
+ if (self.message_type == MessageType.set and 0 <= self.body_type <= 7) or (
+ self.message_type in [MessageType.query, MessageType.notify1]
+ and self.body_type == 0
+ ):
self.set_body(Message34Body(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea/devices/x40/device.py b/custom_components/midea_ac_lan/midea/devices/x40/device.py
index f7d33fd9..6115e00c 100644
--- a/custom_components/midea_ac_lan/midea/devices/x40/device.py
+++ b/custom_components/midea_ac_lan/midea/devices/x40/device.py
@@ -1,14 +1,13 @@
import logging
import math
-from .message import (
- MessageQuery,
- MessageSet,
- Message40Response
-)
+
+from .message import Message40Response, MessageQuery, MessageSet
+
try:
from enum import StrEnum
except ImportError:
from ...backports.myenum import StrEnum
+
from ...core.device import MiedaDevice
_LOGGER = logging.getLogger(__name__)
@@ -27,17 +26,17 @@ class Midea40Device(MiedaDevice):
_directions = ["60", "70", "80", "90", "100", "Oscillate"]
def __init__(
- self,
- name: str,
- device_id: int,
- ip_address: str,
- port: int,
- token: str,
- key: str,
- protocol: int,
- model: str,
- subtype: int,
- customize: str
+ self,
+ name: str,
+ device_id: int,
+ ip_address: str,
+ port: int,
+ token: str,
+ key: str,
+ protocol: int,
+ model: str,
+ subtype: int,
+ customize: str,
):
super().__init__(
name=name,
@@ -56,8 +55,9 @@ def __init__(
DeviceAttributes.direction: False,
DeviceAttributes.ventilation: False,
DeviceAttributes.smelly_sensor: False,
- DeviceAttributes.current_temperature: None
- })
+ DeviceAttributes.current_temperature: None,
+ },
+ )
self._fields = {}
@property
@@ -69,8 +69,11 @@ def _convert_to_midea_direction(direction):
if direction == "Oscillate":
result = 0xFD
else:
- result = Midea40Device._directions.index(direction) * 10 + 60 \
- if direction in Midea40Device._directions else 0xFD
+ result = (
+ Midea40Device._directions.index(direction) * 10 + 60
+ if direction in Midea40Device._directions
+ else 0xFD
+ )
return result
@staticmethod
@@ -102,18 +105,22 @@ def process_message(self, msg):
return new_status
def set_attribute(self, attr, value):
- if attr in [DeviceAttributes.light,
- DeviceAttributes.fan_speed,
- DeviceAttributes.direction,
- DeviceAttributes.ventilation,
- DeviceAttributes.smelly_sensor]:
+ if attr in [
+ DeviceAttributes.light,
+ DeviceAttributes.fan_speed,
+ DeviceAttributes.direction,
+ DeviceAttributes.ventilation,
+ DeviceAttributes.smelly_sensor,
+ ]:
message = MessageSet(self._protocol_version)
message.fields = self._fields
message.light = self._attributes[DeviceAttributes.light]
message.ventilation = self._attributes[DeviceAttributes.ventilation]
message.smelly_sensor = self._attributes[DeviceAttributes.smelly_sensor]
message.fan_speed = self._attributes[DeviceAttributes.fan_speed]
- message.direction = self._convert_to_midea_direction(self._attributes[DeviceAttributes.direction])
+ message.direction = self._convert_to_midea_direction(
+ self._attributes[DeviceAttributes.direction]
+ )
if attr == DeviceAttributes.direction:
message.direction = self._convert_to_midea_direction(value)
elif attr == DeviceAttributes.ventilation and message.fan_speed == 2:
diff --git a/custom_components/midea_ac_lan/midea/devices/x40/message.py b/custom_components/midea_ac_lan/midea/devices/x40/message.py
index 71baa781..fba44d2e 100644
--- a/custom_components/midea_ac_lan/midea/devices/x40/message.py
+++ b/custom_components/midea_ac_lan/midea/devices/x40/message.py
@@ -1,9 +1,4 @@
-from ...core.message import (
- MessageType,
- MessageRequest,
- MessageResponse,
- MessageBody
-)
+from ...core.message import MessageBody, MessageRequest, MessageResponse, MessageType
class Message40Base(MessageRequest):
@@ -12,7 +7,7 @@ def __init__(self, protocol_version, message_type, body_type):
device_type=0x40,
protocol_version=protocol_version,
message_type=message_type,
- body_type=body_type
+ body_type=body_type,
)
@property
@@ -25,12 +20,12 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.query,
- body_type=0x01)
+ body_type=0x01,
+ )
@property
def _body(self):
- return bytearray([
- ])
+ return bytearray([])
class MessageSet(Message40Base):
@@ -38,7 +33,8 @@ def __init__(self, protocol_version):
super().__init__(
protocol_version=protocol_version,
message_type=MessageType.set,
- body_type=0x01)
+ body_type=0x01,
+ )
self.fields = {}
self.light = False
self.fan_speed = 0
@@ -58,47 +54,49 @@ def _body(self):
ventilation = 1 if self.ventilation else 0
direction = self.direction
smelly_sensor = 1 if self.smelly_sensor else 0
- return bytearray([
- light,
- self.read_field("MAIN_LIGHT_BRIGHTNESS"),
- self.read_field("NIGHT_LIGHT_ENABLE"),
- self.read_field("NIGHT_LIGHT_BRIGHTNESS"),
- self.read_field("RADAR_INDUCTION_ENABLE"),
- self.read_field("RADAR_INDUCTION_CLOSING_TIME"),
- self.read_field("LIGHT_INTENSITY_THRESHOLD"),
- self.read_field("RADAR_SENSITIVITY"),
- self.read_field("HEATING_ENABLE"),
- self.read_field("HEATING_TEMPERATURE"),
- self.read_field("HEATING_SPEED"),
- self.read_field("HEATING_DIRECTION"),
- self.read_field("BATH_ENABLE"),
- self.read_field("BATH_HEATING_TIME"),
- self.read_field("BATH_TEMPERATURE"),
- self.read_field("BATH_SPEED"),
- self.read_field("BATH_DIRECTION"),
- ventilation,
- self.read_field("VENTILATION_SPEED"),
- self.read_field("VENTILATION_DIRECTION"),
- self.read_field("DRYING_ENABLE"),
- self.read_field("DRYING_TIME"),
- self.read_field("DRYING_TEMPERATURE"),
- self.read_field("DRYING_SPEED"),
- self.read_field("DRYING_DIRECTION"),
- blow,
- fan_speed,
- direction,
- self.read_field("DELAY_ENABLE"),
- self.read_field("DELAY_TIME"),
- self.read_field("SOFT_WIND_ENABLE"),
- self.read_field("SOFT_WIND_TIME"),
- self.read_field("SOFT_WIND_TEMPERATURE"),
- self.read_field("SOFT_WIND_SPEED"),
- self.read_field("SOFT_WIND_DIRECTION"),
- self.read_field("WINDLESS_ENABLE"),
- self.read_field("ANION_ENABLE"),
- smelly_sensor,
- self.read_field("SMELLY_THRESHOLD")
- ])
+ return bytearray(
+ [
+ light,
+ self.read_field("MAIN_LIGHT_BRIGHTNESS"),
+ self.read_field("NIGHT_LIGHT_ENABLE"),
+ self.read_field("NIGHT_LIGHT_BRIGHTNESS"),
+ self.read_field("RADAR_INDUCTION_ENABLE"),
+ self.read_field("RADAR_INDUCTION_CLOSING_TIME"),
+ self.read_field("LIGHT_INTENSITY_THRESHOLD"),
+ self.read_field("RADAR_SENSITIVITY"),
+ self.read_field("HEATING_ENABLE"),
+ self.read_field("HEATING_TEMPERATURE"),
+ self.read_field("HEATING_SPEED"),
+ self.read_field("HEATING_DIRECTION"),
+ self.read_field("BATH_ENABLE"),
+ self.read_field("BATH_HEATING_TIME"),
+ self.read_field("BATH_TEMPERATURE"),
+ self.read_field("BATH_SPEED"),
+ self.read_field("BATH_DIRECTION"),
+ ventilation,
+ self.read_field("VENTILATION_SPEED"),
+ self.read_field("VENTILATION_DIRECTION"),
+ self.read_field("DRYING_ENABLE"),
+ self.read_field("DRYING_TIME"),
+ self.read_field("DRYING_TEMPERATURE"),
+ self.read_field("DRYING_SPEED"),
+ self.read_field("DRYING_DIRECTION"),
+ blow,
+ fan_speed,
+ direction,
+ self.read_field("DELAY_ENABLE"),
+ self.read_field("DELAY_TIME"),
+ self.read_field("SOFT_WIND_ENABLE"),
+ self.read_field("SOFT_WIND_TIME"),
+ self.read_field("SOFT_WIND_TEMPERATURE"),
+ self.read_field("SOFT_WIND_SPEED"),
+ self.read_field("SOFT_WIND_DIRECTION"),
+ self.read_field("WINDLESS_ENABLE"),
+ self.read_field("ANION_ENABLE"),
+ smelly_sensor,
+ self.read_field("SMELLY_THRESHOLD"),
+ ]
+ )
class Message40Body(MessageBody):
@@ -157,6 +155,10 @@ def __init__(self, body):
class Message40Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
- if self.message_type in [MessageType.set, MessageType.notify1, MessageType.query] and self.body_type == 0x01:
+ if (
+ self.message_type
+ in [MessageType.set, MessageType.notify1, MessageType.query]
+ and self.body_type == 0x01
+ ):
self.set_body(Message40Body(super().body))
self.set_attr()
diff --git a/custom_components/midea_ac_lan/midea_devices.py b/custom_components/midea_ac_lan/midea_devices.py
index fb46ab95..5ad32bd2 100644
--- a/custom_components/midea_ac_lan/midea_devices.py
+++ b/custom_components/midea_ac_lan/midea_devices.py
@@ -1,19 +1,17 @@
+from homeassistant.components.binary_sensor import BinarySensorDeviceClass
+from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass
from homeassistant.const import (
+ CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
+ CONCENTRATION_PARTS_PER_MILLION,
+ PERCENTAGE,
Platform,
- UnitOfTime,
- UnitOfTemperature,
+ UnitOfEnergy,
UnitOfPower,
- PERCENTAGE,
+ UnitOfTemperature,
+ UnitOfTime,
UnitOfVolume,
- UnitOfEnergy,
- CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
- CONCENTRATION_PARTS_PER_MILLION
)
-from homeassistant.components.binary_sensor import BinarySensorDeviceClass
-from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass
-from .midea.devices.x26.device import DeviceAttributes as X26Attributes
-from .midea.devices.x34.device import DeviceAttributes as X34Attributes
-from .midea.devices.x40.device import DeviceAttributes as X40Attributes
+
from .midea.devices.a1.device import DeviceAttributes as A1Attributes
from .midea.devices.ac.device import DeviceAttributes as ACAttributes
from .midea.devices.b0.device import DeviceAttributes as B0Attributes
@@ -44,18 +42,16 @@
from .midea.devices.fb.device import DeviceAttributes as FBAttributes
from .midea.devices.fc.device import DeviceAttributes as FCAttributes
from .midea.devices.fd.device import DeviceAttributes as FDAttributes
-
+from .midea.devices.x26.device import DeviceAttributes as X26Attributes
+from .midea.devices.x34.device import DeviceAttributes as X34Attributes
+from .midea.devices.x40.device import DeviceAttributes as X40Attributes
MIDEA_DEVICES = {
0x13: {
"name": "Light",
"entities": {
- "light": {
- "type": Platform.LIGHT,
- "icon": "mdi:lightbulb",
- "default": True
- }
- }
+ "light": {"type": Platform.LIGHT, "icon": "mdi:lightbulb", "default": True}
+ },
},
0x26: {
"name": "Bathroom Master",
@@ -65,43 +61,43 @@
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
X26Attributes.current_humidity: {
"type": Platform.SENSOR,
"name": "Current Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
X26Attributes.current_radar: {
"type": Platform.BINARY_SENSOR,
"name": "Occupancy Status",
- "device_class": BinarySensorDeviceClass.MOVING
+ "device_class": BinarySensorDeviceClass.MOVING,
},
X26Attributes.main_light: {
"type": Platform.SWITCH,
"name": "Main Light",
- "icon": "mdi:lightbulb"
+ "icon": "mdi:lightbulb",
},
X26Attributes.night_light: {
"type": Platform.SWITCH,
"name": "Night Light",
- "icon": "mdi:lightbulb"
+ "icon": "mdi:lightbulb",
},
X26Attributes.mode: {
"type": Platform.SELECT,
"name": "Mode",
"options": "preset_modes",
- "icon": "mdi:fan"
+ "icon": "mdi:fan",
},
X26Attributes.direction: {
"type": Platform.SELECT,
"name": "Direction",
"options": "directions",
- "icon": "mdi:arrow-split-vertical"
- }
- }
+ "icon": "mdi:arrow-split-vertical",
+ },
+ },
},
0x34: {
"name": "Sink Dishwasher",
@@ -110,81 +106,78 @@
"type": Platform.BINARY_SENSOR,
"name": "Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
X34Attributes.rinse_aid: {
"type": Platform.BINARY_SENSOR,
"name": "Rinse Aid Shortage",
"icon": "mdi:bottle-tonic",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
X34Attributes.salt: {
"type": Platform.BINARY_SENSOR,
"name": "Salt Shortage",
"icon": "mdi:drag",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
X34Attributes.humidity: {
"type": Platform.SENSOR,
"name": "Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
X34Attributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
X34Attributes.status: {
"type": Platform.SENSOR,
"name": "Status",
- "icon": "mdi:information"
+ "icon": "mdi:information",
},
X34Attributes.storage_remaining: {
"type": Platform.SENSOR,
"name": "Storage Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.HOURS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
X34Attributes.temperature: {
"type": Platform.SENSOR,
"name": "Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
X34Attributes.time_remaining: {
"type": Platform.SENSOR,
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
- },
- X34Attributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
+ "state_class": SensorStateClass.MEASUREMENT,
},
+ X34Attributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
X34Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
X34Attributes.storage: {
"type": Platform.SWITCH,
"name": "Storage",
- "icon": "mdi:repeat-variant"
+ "icon": "mdi:repeat-variant",
},
X34Attributes.mode: {
"type": Platform.SENSOR,
"name": "Working Mode",
- "icon": "mdi:dishwasher"
+ "icon": "mdi:dishwasher",
},
X34Attributes.error_code: {
"type": Platform.SENSOR,
"name": "Error Code",
- "icon": "mdi:alert-box"
+ "icon": "mdi:alert-box",
},
X34Attributes.softwater: {
"type": Platform.SENSOR,
@@ -194,47 +187,43 @@
X34Attributes.bright: {
"type": Platform.SENSOR,
"name": "Bright Level",
- "icon": "mdi:star-four-points"
- }
- }
+ "icon": "mdi:star-four-points",
+ },
+ },
},
0x40: {
"name": "Integrated Ceiling Fan",
"entities": {
- "fan": {
- "type": Platform.FAN,
- "icon": "mdi:fan",
- "default": True
- },
+ "fan": {"type": Platform.FAN, "icon": "mdi:fan", "default": True},
X40Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
X40Attributes.light: {
"type": Platform.SWITCH,
"name": "Light",
- "icon": "mdi:lightbulb"
+ "icon": "mdi:lightbulb",
},
X40Attributes.ventilation: {
"type": Platform.SWITCH,
"name": "Ventilation",
- "icon": "mdi:air-filter"
+ "icon": "mdi:air-filter",
},
X40Attributes.smelly_sensor: {
"type": Platform.SWITCH,
"name": "Smelly Sensor",
- "icon": "mdi:scent"
+ "icon": "mdi:scent",
},
X40Attributes.direction: {
"type": Platform.SELECT,
"name": "Direction",
"options": "directions",
- "icon": "mdi:arrow-split-vertical"
- }
- }
+ "icon": "mdi:arrow-split-vertical",
+ },
+ },
},
0xA1: {
"name": "Dehumidifier",
@@ -242,72 +231,69 @@
"humidifier": {
"type": Platform.HUMIDIFIER,
"icon": "mdi:air-humidifier",
- "default": True
- },
- A1Attributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
+ "default": True,
},
+ A1Attributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
A1Attributes.anion: {
"type": Platform.SWITCH,
"name": "Anion",
- "icon": "mdi:vanish"
+ "icon": "mdi:vanish",
},
A1Attributes.prompt_tone: {
"type": Platform.SWITCH,
"name": "Prompt Tone",
- "icon": "mdi:bell"
+ "icon": "mdi:bell",
},
A1Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
A1Attributes.swing: {
"type": Platform.SWITCH,
"name": "swing",
- "icon": "mdi:pan-horizontal"
+ "icon": "mdi:pan-horizontal",
},
A1Attributes.fan_speed: {
"type": Platform.SELECT,
"name": "Fan Speed",
"options": "fan_speeds",
- "icon": "mdi:fan"
+ "icon": "mdi:fan",
},
A1Attributes.water_level_set: {
"type": Platform.SELECT,
"name": "Water Level Setting",
"options": "water_level_sets",
- "icon": "mdi:cup-water"
+ "icon": "mdi:cup-water",
},
A1Attributes.current_humidity: {
"type": Platform.SENSOR,
"name": "Current Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
A1Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
A1Attributes.tank: {
"type": Platform.SENSOR,
"name": "Tank",
"icon": "mdi:cup-water",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
A1Attributes.tank_full: {
"type": Platform.BINARY_SENSOR,
"name": "Tank status",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
- }
- }
+ "device_class": BinarySensorDeviceClass.PROBLEM,
+ },
+ },
},
0xAC: {
"name": "Air Conditioner",
@@ -315,147 +301,143 @@
"climate": {
"type": Platform.CLIMATE,
"icon": "mdi:air-conditioner",
- "default": True
- },
- "fresh_air": {
- "type": Platform.FAN,
- "icon": "mdi:fan",
- "name": "Fresh Air"
+ "default": True,
},
+ "fresh_air": {"type": Platform.FAN, "icon": "mdi:fan", "name": "Fresh Air"},
ACAttributes.aux_heating: {
"type": Platform.SWITCH,
"name": "Aux Heating",
- "icon": "mdi:heat-wave"
+ "icon": "mdi:heat-wave",
},
ACAttributes.boost_mode: {
"type": Platform.SWITCH,
"name": "Boost Mode",
- "icon": "mdi:turbine"
+ "icon": "mdi:turbine",
},
ACAttributes.breezeless: {
"type": Platform.SWITCH,
"name": "Breezeless",
- "icon": "mdi:tailwind"
+ "icon": "mdi:tailwind",
},
ACAttributes.comfort_mode: {
"type": Platform.SWITCH,
"name": "Comfort Mode",
- "icon": "mdi:alpha-c-circle"
+ "icon": "mdi:alpha-c-circle",
},
ACAttributes.dry: {
"type": Platform.SWITCH,
"name": "Dry",
- "icon": "mdi:air-filter"
+ "icon": "mdi:air-filter",
},
ACAttributes.eco_mode: {
"type": Platform.SWITCH,
"name": "ECO Mode",
- "icon": "mdi:leaf-circle"
+ "icon": "mdi:leaf-circle",
},
ACAttributes.frost_protect: {
"type": Platform.SWITCH,
"name": "Frost Protect",
- "icon": "mdi:snowflake-alert"
+ "icon": "mdi:snowflake-alert",
},
ACAttributes.indirect_wind: {
"type": Platform.SWITCH,
"name": "Indirect Wind",
- "icon": "mdi:tailwind"
+ "icon": "mdi:tailwind",
},
ACAttributes.natural_wind: {
"type": Platform.SWITCH,
"name": "Natural Wind",
- "icon": "mdi:tailwind"
+ "icon": "mdi:tailwind",
},
ACAttributes.prompt_tone: {
"type": Platform.SWITCH,
"name": "Prompt Tone",
- "icon": "mdi:bell"
+ "icon": "mdi:bell",
},
ACAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
ACAttributes.screen_display: {
"type": Platform.SWITCH,
"name": "Screen Display",
- "icon": "mdi:television-ambient-light"
+ "icon": "mdi:television-ambient-light",
},
ACAttributes.screen_display_alternate: {
"type": Platform.SWITCH,
"name": "Screen Display Alternate",
- "icon": "mdi:television-ambient-light"
+ "icon": "mdi:television-ambient-light",
},
ACAttributes.sleep_mode: {
"type": Platform.SWITCH,
"name": "Sleep Mode",
- "icon": "mdi:power-sleep"
+ "icon": "mdi:power-sleep",
},
ACAttributes.smart_eye: {
"type": Platform.SWITCH,
"name": "Smart Eye",
- "icon": "mdi:eye"
+ "icon": "mdi:eye",
},
ACAttributes.swing_horizontal: {
"type": Platform.SWITCH,
"name": "Swing Horizontal",
- "icon": "mdi:arrow-split-vertical"
+ "icon": "mdi:arrow-split-vertical",
},
ACAttributes.swing_vertical: {
"type": Platform.SWITCH,
"name": "Swing Vertical",
- "icon": "mdi:arrow-split-horizontal"
+ "icon": "mdi:arrow-split-horizontal",
},
ACAttributes.full_dust: {
"type": Platform.BINARY_SENSOR,
"name": "Full of Dust",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
ACAttributes.indoor_humidity: {
"type": Platform.SENSOR,
"name": "Indoor Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
ACAttributes.indoor_temperature: {
"type": Platform.SENSOR,
"name": "Indoor Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
ACAttributes.outdoor_temperature: {
"type": Platform.SENSOR,
"name": "Outdoor Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
ACAttributes.total_energy_consumption: {
"type": Platform.SENSOR,
"name": "Total Energy Consumption",
"device_class": SensorDeviceClass.ENERGY,
"unit": UnitOfEnergy.KILO_WATT_HOUR,
- "state_class": SensorStateClass.TOTAL_INCREASING
+ "state_class": SensorStateClass.TOTAL_INCREASING,
},
ACAttributes.current_energy_consumption: {
"type": Platform.SENSOR,
"name": "Current Energy Consumption",
"device_class": SensorDeviceClass.ENERGY,
"unit": UnitOfEnergy.KILO_WATT_HOUR,
- "state_class": SensorStateClass.TOTAL_INCREASING
+ "state_class": SensorStateClass.TOTAL_INCREASING,
},
ACAttributes.realtime_power: {
"type": Platform.SENSOR,
"name": "Realtime Power",
"device_class": SensorDeviceClass.POWER,
"unit": UnitOfPower.WATT,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xB0: {
"name": "Microwave Oven",
@@ -464,32 +446,32 @@
"type": Platform.BINARY_SENSOR,
"name": "Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
B0Attributes.tank_ejected: {
"type": Platform.BINARY_SENSOR,
"name": "Tank Ejected",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B0Attributes.water_change_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Water Change Reminder",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B0Attributes.water_shortage: {
"type": Platform.BINARY_SENSOR,
"name": "Water Shortage",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B0Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B0Attributes.status: {
"type": Platform.SENSOR,
@@ -501,9 +483,9 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xB1: {
"name": "Electric Oven",
@@ -512,32 +494,32 @@
"type": Platform.BINARY_SENSOR,
"name": "Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
B1Attributes.tank_ejected: {
"type": Platform.BINARY_SENSOR,
"name": "Tank ejected",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B1Attributes.water_change_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Water Change Reminder",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B1Attributes.water_shortage: {
"type": Platform.BINARY_SENSOR,
"name": "Water Shortage",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B1Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B1Attributes.status: {
"type": Platform.SENSOR,
@@ -549,9 +531,9 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xB3: {
"name": "Dish Sterilizer",
@@ -613,58 +595,58 @@
B3Attributes.top_compartment_status: {
"type": Platform.SENSOR,
"name": "Top Compartment Status",
- "icon": "mdi:information"
+ "icon": "mdi:information",
},
B3Attributes.top_compartment_temperature: {
"type": Platform.SENSOR,
"name": "Top Compartment Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B3Attributes.top_compartment_remaining: {
"type": Platform.SENSOR,
"name": "Top Compartment Remaining",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B3Attributes.middle_compartment_status: {
"type": Platform.SENSOR,
"name": "Middle Compartment Status",
- "icon": "mdi:information"
+ "icon": "mdi:information",
},
B3Attributes.middle_compartment_temperature: {
"type": Platform.SENSOR,
"name": "Middle Compartment Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B3Attributes.middle_compartment_remaining: {
"type": Platform.SENSOR,
"name": "Middle Compartment Remaining",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B3Attributes.bottom_compartment_status: {
"type": Platform.SENSOR,
"name": "Bottom Compartment Status",
- "icon": "mdi:information"
+ "icon": "mdi:information",
},
B3Attributes.bottom_compartment_temperature: {
"type": Platform.SENSOR,
"name": "Bottom Compartment Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B3Attributes.bottom_compartment_remaining: {
"type": Platform.SENSOR,
"name": "Bottom Compartment Remaining",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xB4: {
"name": "Toaster",
@@ -673,32 +655,32 @@
"type": Platform.BINARY_SENSOR,
"name": "Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
B4Attributes.tank_ejected: {
"type": Platform.BINARY_SENSOR,
"name": "Tank ejected",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B4Attributes.water_change_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Water Change Reminder",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B4Attributes.water_shortage: {
"type": Platform.BINARY_SENSOR,
"name": "Water Shortage",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B4Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
B4Attributes.status: {
"type": Platform.SENSOR,
@@ -710,47 +692,43 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xB6: {
"name": "Range Hood",
"entities": {
- "fan": {
- "type": Platform.FAN,
- "icon": "mdi:fan",
- "default": True
- },
+ "fan": {"type": Platform.FAN, "icon": "mdi:fan", "default": True},
B6Attributes.light: {
"type": Platform.SWITCH,
"name": "Light",
- "icon": "mdi:lightbulb"
+ "icon": "mdi:lightbulb",
},
B6Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
B6Attributes.cleaning_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Cleaning Reminder",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B6Attributes.oilcup_full: {
"type": Platform.BINARY_SENSOR,
"name": "Oil-cup Full",
"icon": "mdi:cup",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
B6Attributes.fan_level: {
"type": Platform.SENSOR,
"name": "Fan level",
"icon": "mdi:fan",
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
- }
+ },
},
0xBF: {
"name": "Microwave Steam Oven",
@@ -759,32 +737,32 @@
"type": Platform.BINARY_SENSOR,
"name": "Tank ejected",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
BFAttributes.water_change_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Water Change Reminder",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
BFAttributes.door: {
"type": Platform.BINARY_SENSOR,
"name": "Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
BFAttributes.water_shortage: {
"type": Platform.BINARY_SENSOR,
"name": "Water Shortage",
"icon": "mdi:cup-water",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
BFAttributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
BFAttributes.status: {
"type": Platform.SENSOR,
@@ -796,9 +774,9 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xC2: {
"name": "Toilet",
@@ -806,58 +784,55 @@
C2Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
C2Attributes.sensor_light: {
"type": Platform.SWITCH,
"name": "Sensor Light",
- "icon": "mdi:lightbulb"
+ "icon": "mdi:lightbulb",
},
C2Attributes.foam_shield: {
"type": Platform.SWITCH,
"name": "Foam Shield",
"icon": "mdi:chart-bubble",
},
- C2Attributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
- },
+ C2Attributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
C2Attributes.seat_status: {
"type": Platform.BINARY_SENSOR,
"name": "Seat Status",
- "icon": "mdi:seat-legroom-normal"
+ "icon": "mdi:seat-legroom-normal",
},
C2Attributes.lid_status: {
"type": Platform.BINARY_SENSOR,
"name": "Lid Status",
- "icon": "mdi:toilet"
+ "icon": "mdi:toilet",
},
C2Attributes.light_status: {
"type": Platform.BINARY_SENSOR,
"name": "Light Status",
"icon": "mdi:lightbulb",
- "device_class": BinarySensorDeviceClass.LIGHT
+ "device_class": BinarySensorDeviceClass.LIGHT,
},
C2Attributes.water_temperature: {
"type": Platform.SENSOR,
"name": "Water Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
C2Attributes.seat_temperature: {
"type": Platform.SENSOR,
"name": "Seat Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
C2Attributes.filter_life: {
"type": Platform.SENSOR,
"name": "Filter Life",
"icon": "mdi:toilet",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
C2Attributes.dry_level: {
"type": Platform.NUMBER,
@@ -865,7 +840,7 @@
"icon": "mdi:fire",
"max": "max_dry_level",
"min": 0,
- "step": 1
+ "step": 1,
},
C2Attributes.water_temp_level: {
"type": Platform.NUMBER,
@@ -873,7 +848,7 @@
"icon": "mdi:fire",
"max": "max_water_temp_level",
"min": 0,
- "step": 1
+ "step": 1,
},
C2Attributes.seat_temp_level: {
"type": Platform.NUMBER,
@@ -881,9 +856,9 @@
"icon": "mdi:fire",
"max": "max_seat_temp_level",
"min": 0,
- "step": 1
- }
- }
+ "step": 1,
+ },
+ },
},
0xC3: {
"name": "Heat Pump Wi-Fi Controller",
@@ -893,70 +868,70 @@
"icon": "mdi:air-conditioner",
"name": "Zone1 Thermostat",
"zone": 0,
- "default": True
+ "default": True,
},
"climate_zone2": {
"type": Platform.CLIMATE,
"icon": "mdi:air-conditioner",
"name": "Zone2 Thermostat",
"zone": 1,
- "default": True
+ "default": True,
},
"water_heater": {
"type": Platform.WATER_HEATER,
"icon": "mdi:heat-pump",
"name": "Domestic hot water",
- "default": True
+ "default": True,
},
C3Attributes.disinfect: {
"type": Platform.SWITCH,
"name": "Disinfect",
- "icon": "mdi:water-plus-outline"
+ "icon": "mdi:water-plus-outline",
},
C3Attributes.dhw_power: {
"type": Platform.SWITCH,
"name": "DHW Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
C3Attributes.eco_mode: {
"type": Platform.SWITCH,
"name": "ECO Mode",
- "icon": "mdi:leaf-circle"
+ "icon": "mdi:leaf-circle",
},
C3Attributes.fast_dhw: {
"type": Platform.SWITCH,
"name": "Fast DHW",
- "icon": "mdi:rotate-orbit"
+ "icon": "mdi:rotate-orbit",
},
C3Attributes.silent_mode: {
"type": Platform.SWITCH,
"name": "Silent Mode",
- "icon": "mdi:fan-remove"
+ "icon": "mdi:fan-remove",
},
C3Attributes.tbh: {
"type": Platform.SWITCH,
"name": "TBH",
- "icon": "mdi:water-boiler"
+ "icon": "mdi:water-boiler",
},
C3Attributes.zone1_curve: {
"type": Platform.SWITCH,
"name": "Zone1 Curve",
- "icon": "mdi:chart-bell-curve-cumulative"
+ "icon": "mdi:chart-bell-curve-cumulative",
},
C3Attributes.zone2_curve: {
"type": Platform.SWITCH,
"name": "Zone2 Curve",
- "icon": "mdi:chart-bell-curve-cumulative"
+ "icon": "mdi:chart-bell-curve-cumulative",
},
C3Attributes.zone1_power: {
"type": Platform.SWITCH,
"name": "Zone1 Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
C3Attributes.zone2_power: {
"type": Platform.SWITCH,
"name": "Zone2 Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
C3Attributes.zone1_water_temp_mode: {
"type": Platform.BINARY_SENSOR,
@@ -985,14 +960,14 @@
C3Attributes.error_code: {
"type": Platform.SENSOR,
"name": "Error Code",
- "icon": "mdi:alpha-e-circle"
+ "icon": "mdi:alpha-e-circle",
},
C3Attributes.tank_actual_temperature: {
"type": Platform.SENSOR,
"name": "Tank Actual Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
C3Attributes.status_dhw: {
"type": Platform.BINARY_SENSOR,
@@ -1023,23 +998,23 @@
"name": "Total energy consumption",
"device_class": SensorDeviceClass.ENERGY,
"unit": UnitOfEnergy.KILO_WATT_HOUR,
- "state_class": SensorStateClass.TOTAL_INCREASING
+ "state_class": SensorStateClass.TOTAL_INCREASING,
},
C3Attributes.total_produced_energy: {
"type": Platform.SENSOR,
"name": "Total produced energy",
"device_class": SensorDeviceClass.ENERGY,
"unit": UnitOfEnergy.KILO_WATT_HOUR,
- "state_class": SensorStateClass.TOTAL_INCREASING
+ "state_class": SensorStateClass.TOTAL_INCREASING,
},
C3Attributes.outdoor_temperature: {
"type": Platform.SENSOR,
"name": "Outdoor Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xCA: {
"name": "Refrigerator",
@@ -1048,112 +1023,112 @@
"type": Platform.BINARY_SENSOR,
"name": "Bar Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
CAAttributes.bar_door_overtime: {
"type": Platform.BINARY_SENSOR,
"name": "Bar Door Overtime",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CAAttributes.flex_zone_door: {
"type": Platform.BINARY_SENSOR,
"name": "Flex Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
CAAttributes.flex_zone_door_overtime: {
"type": Platform.BINARY_SENSOR,
"name": "Flex Zone Door",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CAAttributes.freezer_door: {
"type": Platform.BINARY_SENSOR,
"name": "Freezer Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
CAAttributes.freezer_door_overtime: {
"type": Platform.BINARY_SENSOR,
"name": "Freezer Door Overtime",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CAAttributes.refrigerator_door: {
"type": Platform.BINARY_SENSOR,
"name": "Refrigerator Door",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CAAttributes.refrigerator_door_overtime: {
"type": Platform.BINARY_SENSOR,
"name": "Refrigerator Door Overtime",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CAAttributes.flex_zone_actual_temp: {
"type": Platform.SENSOR,
"name": "Flex Zone Actual Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.flex_zone_setting_temp: {
"type": Platform.SENSOR,
"name": "Flex Zone Setting Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.freezer_actual_temp: {
"type": Platform.SENSOR,
"name": "Freezer Actual Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.freezer_setting_temp: {
"type": Platform.SENSOR,
"name": "Freezer Setting Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.energy_consumption: {
"type": Platform.SENSOR,
"name": "Energy Consumption",
"device_class": SensorDeviceClass.ENERGY,
"unit": UnitOfEnergy.KILO_WATT_HOUR,
- "state_class": SensorStateClass.TOTAL_INCREASING
+ "state_class": SensorStateClass.TOTAL_INCREASING,
},
CAAttributes.refrigerator_actual_temp: {
"type": Platform.SENSOR,
"name": "Refrigerator Actual Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.refrigerator_setting_temp: {
"type": Platform.SENSOR,
"name": "Refrigerator Setting Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.right_flex_zone_actual_temp: {
"type": Platform.SENSOR,
"name": "Right Flex Zone Actual Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CAAttributes.right_flex_zone_setting_temp: {
"type": Platform.SENSOR,
"name": "Right Flex Zone Setting Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
},
},
@@ -1163,46 +1138,46 @@
"climate": {
"type": Platform.CLIMATE,
"icon": "hass:air-conditioner",
- "default": True
+ "default": True,
},
CCAttributes.aux_heating: {
"type": Platform.SWITCH,
"name": "Aux Heating",
- "icon": "mdi:heat-wave"
+ "icon": "mdi:heat-wave",
},
CCAttributes.eco_mode: {
"type": Platform.SWITCH,
"name": "ECO Mode",
- "icon": "mdi:leaf-circle"
+ "icon": "mdi:leaf-circle",
},
CCAttributes.night_light: {
"type": Platform.SWITCH,
"name": "Night Light",
- "icon": "mdi:lightbulb"
+ "icon": "mdi:lightbulb",
},
CCAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
CCAttributes.sleep_mode: {
"type": Platform.SWITCH,
"name": "Sleep Mode",
- "icon": "mdi:power-sleep"
+ "icon": "mdi:power-sleep",
},
CCAttributes.swing: {
"type": Platform.SWITCH,
"name": "Swing",
- "icon": "mdi:arrow-split-horizontal"
+ "icon": "mdi:arrow-split-horizontal",
},
CCAttributes.indoor_temperature: {
"type": Platform.SENSOR,
"name": "Indoor Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
- }
+ },
},
0xCD: {
"name": "Heat Pump Water Heater",
@@ -1210,132 +1185,125 @@
"water_heater": {
"type": Platform.WATER_HEATER,
"icon": "mdi:heat-pump",
- "default": True
+ "default": True,
},
CDAttributes.compressor_status: {
"type": Platform.BINARY_SENSOR,
"name": "Compressor Status",
"icon": "mdi:drag",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
CDAttributes.compressor_temperature: {
"type": Platform.SENSOR,
"name": "Compressor Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CDAttributes.condenser_temperature: {
"type": Platform.SENSOR,
"name": "Condenser Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CDAttributes.outdoor_temperature: {
"type": Platform.SENSOR,
"name": "Outdoor Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CDAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
- }
- }
+ "icon": "mdi:power",
+ },
+ },
},
0xCE: {
"name": "Fresh Air Appliance",
"entities": {
- "fan": {
- "type": Platform.FAN,
- "icon": "mdi:fan",
- "default": True
- },
+ "fan": {"type": Platform.FAN, "icon": "mdi:fan", "default": True},
CEAttributes.filter_cleaning_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Filter Cleaning Reminder",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CEAttributes.filter_change_reminder: {
"type": Platform.BINARY_SENSOR,
"name": "Filter Change Reminder",
"icon": "mdi:alert-circle",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
CEAttributes.current_humidity: {
"type": Platform.SENSOR,
"name": "Current Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CEAttributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CEAttributes.co2: {
"type": Platform.SENSOR,
"name": "Carbon Dioxide",
"device_class": SensorDeviceClass.CO2,
"unit": CONCENTRATION_PARTS_PER_MILLION,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CEAttributes.hcho: {
"type": Platform.SENSOR,
"name": "Methanal",
"icon": "mdi:molecule",
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
CEAttributes.pm25: {
"type": Platform.SENSOR,
"name": "PM 2.5",
"device_class": SensorDeviceClass.PM25,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
- "state_class": SensorStateClass.MEASUREMENT
- },
- CEAttributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
+ "state_class": SensorStateClass.MEASUREMENT,
},
+ CEAttributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
CEAttributes.aux_heating: {
"type": Platform.SWITCH,
"name": "Aux Heating",
- "icon": "mdi:heat-wave"
+ "icon": "mdi:heat-wave",
},
CEAttributes.eco_mode: {
"type": Platform.SWITCH,
"name": "ECO Mode",
- "icon": "mdi:leaf-circle"
+ "icon": "mdi:leaf-circle",
},
CEAttributes.link_to_ac: {
"type": Platform.SWITCH,
"name": "Link to AC",
- "icon": "mdi:link"
+ "icon": "mdi:link",
},
CEAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
CEAttributes.powerful_purify: {
"type": Platform.SWITCH,
"name": "Powerful Purification",
- "icon": "mdi:turbine"
+ "icon": "mdi:turbine",
},
CEAttributes.sleep_mode: {
"type": Platform.SWITCH,
"name": "Sleep Mode",
- "icon": "mdi:power-sleep"
+ "icon": "mdi:power-sleep",
},
- }
+ },
},
0xCF: {
"name": "Heat Pump",
@@ -1343,26 +1311,26 @@
"climate": {
"type": Platform.CLIMATE,
"icon": "hass:air-conditioner",
- "default": True
+ "default": True,
},
CFAttributes.aux_heating: {
"type": Platform.SWITCH,
"name": "Aux Heating",
- "icon": "mdi:heat-wave"
+ "icon": "mdi:heat-wave",
},
CFAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
CFAttributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
- }
+ },
},
0xDA: {
"name": "Top Load Washer",
@@ -1372,90 +1340,90 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
DAAttributes.wash_time: {
"type": Platform.SENSOR,
"name": "wash time",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
DAAttributes.soak_time: {
"type": Platform.SENSOR,
"name": "soak time",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
DAAttributes.dehydration_time: {
"type": Platform.SENSOR,
"name": "dehydration time",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
DAAttributes.dehydration_speed: {
"type": Platform.SENSOR,
"name": "dehydration speed",
- "icon": "mdi:speedometer"
+ "icon": "mdi:speedometer",
},
DAAttributes.error_code: {
"type": Platform.SENSOR,
"name": "error code",
- "icon": "mdi:washing-machine-alert"
+ "icon": "mdi:washing-machine-alert",
},
DAAttributes.rinse_count: {
"type": Platform.SENSOR,
"name": "rinse count",
- "icon": "mdi:water-sync"
+ "icon": "mdi:water-sync",
},
DAAttributes.rinse_level: {
"type": Platform.SENSOR,
"name": "rinse level",
- "icon": "mdi:hydraulic-oil-level"
+ "icon": "mdi:hydraulic-oil-level",
},
DAAttributes.wash_level: {
"type": Platform.SENSOR,
"name": "rinse count",
- "icon": "mdi:hydraulic-oil-level"
+ "icon": "mdi:hydraulic-oil-level",
},
DAAttributes.wash_strength: {
"type": Platform.SENSOR,
"name": "wash strength",
- "icon": "mdi:network-strength-4-cog"
+ "icon": "mdi:network-strength-4-cog",
},
DAAttributes.softener: {
"type": Platform.SENSOR,
"name": "softener",
- "icon": "mdi:tshirt-crew"
+ "icon": "mdi:tshirt-crew",
},
DAAttributes.detergent: {
"type": Platform.SENSOR,
"name": "detergent",
- "icon": "mdi:spray-bottle"
+ "icon": "mdi:spray-bottle",
},
DAAttributes.program: {
"type": Platform.SENSOR,
"name": "Program",
- "icon": "mdi:progress-wrench"
+ "icon": "mdi:progress-wrench",
},
DAAttributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
DAAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
DAAttributes.start: {
"type": Platform.SWITCH,
"name": "Start",
- "icon": "mdi:motion-play-outline"
+ "icon": "mdi:motion-play-outline",
},
- }
+ },
},
0xDB: {
"name": "Front Load Washer",
@@ -1465,24 +1433,24 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
DBAttributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
DBAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
DBAttributes.start: {
"type": Platform.SWITCH,
"name": "Start",
- "icon": "mdi:motion-play-outline"
+ "icon": "mdi:motion-play-outline",
},
- }
+ },
},
0xDC: {
"name": "Clothes Dryer",
@@ -1492,24 +1460,24 @@
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
DCAttributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
DCAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
DCAttributes.start: {
"type": Platform.SWITCH,
"name": "Start",
- "icon": "mdi:motion-play-outline"
+ "icon": "mdi:motion-play-outline",
},
- }
+ },
},
0xE1: {
"name": "Dishwasher",
@@ -1518,81 +1486,78 @@
"type": Platform.BINARY_SENSOR,
"name": "Door",
"icon": "mdi:box-shadow",
- "device_class": BinarySensorDeviceClass.DOOR
+ "device_class": BinarySensorDeviceClass.DOOR,
},
E1Attributes.rinse_aid: {
"type": Platform.BINARY_SENSOR,
"name": "Rinse Aid Shortage",
"icon": "mdi:bottle-tonic",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
E1Attributes.salt: {
"type": Platform.BINARY_SENSOR,
"name": "Salt Shortage",
"icon": "mdi:drag",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
E1Attributes.humidity: {
"type": Platform.SENSOR,
"name": "Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E1Attributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
E1Attributes.status: {
"type": Platform.SENSOR,
"name": "Status",
- "icon": "mdi:information"
+ "icon": "mdi:information",
},
E1Attributes.storage_remaining: {
"type": Platform.SENSOR,
"name": "Storage Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.HOURS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E1Attributes.temperature: {
"type": Platform.SENSOR,
"name": "Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E1Attributes.time_remaining: {
"type": Platform.SENSOR,
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
- },
- E1Attributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
+ "state_class": SensorStateClass.MEASUREMENT,
},
+ E1Attributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
E1Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
E1Attributes.storage: {
"type": Platform.SWITCH,
"name": "Storage",
- "icon": "mdi:repeat-variant"
+ "icon": "mdi:repeat-variant",
},
E1Attributes.mode: {
"type": Platform.SENSOR,
"name": "Working Mode",
- "icon": "mdi:dishwasher"
+ "icon": "mdi:dishwasher",
},
E1Attributes.error_code: {
"type": Platform.SENSOR,
"name": "Error Code",
- "icon": "mdi:alert-box"
+ "icon": "mdi:alert-box",
},
E1Attributes.softwater: {
"type": Platform.SENSOR,
@@ -1602,9 +1567,9 @@
E1Attributes.bright: {
"type": Platform.SENSOR,
"name": "Bright Level",
- "icon": "mdi:star-four-points"
- }
- }
+ "icon": "mdi:star-four-points",
+ },
+ },
},
0xE2: {
"name": "Electric Water Heater",
@@ -1612,70 +1577,70 @@
"water_heater": {
"type": Platform.WATER_HEATER,
"icon": "mdi:meter-electric-outline",
- "default": True
+ "default": True,
},
E2Attributes.heating: {
"type": Platform.BINARY_SENSOR,
"name": "Heating",
"icon": "mdi:heat-wave",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E2Attributes.keep_warm: {
"type": Platform.BINARY_SENSOR,
"name": "Keep Warm",
"icon": "mdi:menu",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E2Attributes.protection: {
"type": Platform.BINARY_SENSOR,
"name": "Protection",
"icon": "mdi:shield-check",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E2Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E2Attributes.heating_time_remaining: {
"type": Platform.SENSOR,
"name": "Heating Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E2Attributes.heating_power: {
"type": Platform.SENSOR,
"name": "Heating Power",
"device_class": SensorDeviceClass.POWER,
"unit": UnitOfPower.WATT,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E2Attributes.water_consumption: {
"type": Platform.SENSOR,
"name": "Water Consumption",
"icon": "mdi:water",
"unit": UnitOfVolume.LITERS,
- "state_class": SensorStateClass.TOTAL_INCREASING
+ "state_class": SensorStateClass.TOTAL_INCREASING,
},
E2Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
E2Attributes.variable_heating: {
"type": Platform.SWITCH,
"name": "Variable Heating",
- "icon": "mdi:waves"
+ "icon": "mdi:waves",
},
E2Attributes.whole_tank_heating: {
"type": Platform.SWITCH,
"name": "Whole Tank Heating",
- "icon": "mdi:restore"
- }
- }
+ "icon": "mdi:restore",
+ },
+ },
},
0xE3: {
"name": "Gas Water Heater",
@@ -1683,48 +1648,48 @@
"water_heater": {
"type": Platform.WATER_HEATER,
"icon": "mdi:meter-gas",
- "default": True
+ "default": True,
},
E3Attributes.burning_state: {
"type": Platform.BINARY_SENSOR,
"name": "Burning State",
"icon": "mdi:fire",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E3Attributes.protection: {
"type": Platform.BINARY_SENSOR,
"name": "Protection",
"icon": "mdi:shield-check",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E3Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E3Attributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
E3Attributes.smart_volume: {
"type": Platform.SWITCH,
"name": "Smart Volume",
- "icon": "mdi:recycle"
+ "icon": "mdi:recycle",
},
E3Attributes.zero_cold_water: {
"type": Platform.SWITCH,
"name": "Zero Cold Water",
- "icon": "mdi:restore"
+ "icon": "mdi:restore",
},
E3Attributes.zero_cold_pulse: {
"type": Platform.SWITCH,
"name": "Zero Cold Water (Pulse)",
- "icon": "mdi:restore-alert"
+ "icon": "mdi:restore-alert",
},
- }
+ },
},
0xE6: {
"name": "Gas Boilers",
@@ -1734,52 +1699,52 @@
"icon": "mdi:meter-gas",
"name": "Heating",
"use": 0,
- "default": True
+ "default": True,
},
"water_heater_bathing": {
"type": Platform.WATER_HEATER,
"icon": "mdi:meter-gas",
"name": "Bathing",
"use": 1,
- "default": True
+ "default": True,
},
E6Attributes.heating_working: {
"type": Platform.BINARY_SENSOR,
"name": "Heating Working Status",
"icon": "mdi:fire",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E6Attributes.bathing_working: {
"type": Platform.BINARY_SENSOR,
"name": "Bathing Working Status",
"icon": "mdi:fire",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
E6Attributes.heating_leaving_temperature: {
"type": Platform.SENSOR,
"name": "Heating Leaving Water Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E6Attributes.bathing_leaving_temperature: {
"type": Platform.SENSOR,
"name": "Bathing Leaving Water Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E6Attributes.main_power: {
"type": Platform.SWITCH,
"name": "Main Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
E6Attributes.heating_power: {
"type": Platform.SWITCH,
"name": "Heating Power",
- "icon": "mdi:heating-coil"
- }
- }
+ "icon": "mdi:heating-coil",
+ },
+ },
},
0xE8: {
"name": "Electric Slow Cooker",
@@ -1793,50 +1758,49 @@
"type": Platform.BINARY_SENSOR,
"name": "Water Shortage",
"icon": "mdi:drag",
- "device_class": BinarySensorDeviceClass.PROBLEM
+ "device_class": BinarySensorDeviceClass.PROBLEM,
},
E8Attributes.status: {
"type": Platform.SENSOR,
"name": "Status",
- "icon": "mdi:information"
+ "icon": "mdi:information",
},
E8Attributes.time_remaining: {
"type": Platform.SENSOR,
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E8Attributes.keep_warm_remaining: {
"type": Platform.SENSOR,
"name": "Keep Warm Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E8Attributes.working_time: {
"type": Platform.SENSOR,
"name": "Working Time",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.SECONDS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E8Attributes.target_temperature: {
"type": Platform.SENSOR,
"name": "Target Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
E8Attributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
-
- }
+ },
},
0xEA: {
"name": "Electric Rice Cooker",
@@ -1845,53 +1809,53 @@
"type": Platform.BINARY_SENSOR,
"name": "Cooking",
"icon": "mdi:fire",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
EAAttributes.keep_warm: {
"type": Platform.BINARY_SENSOR,
"name": "Keep Warm",
"icon": "mdi:menu",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
EAAttributes.bottom_temperature: {
"type": Platform.SENSOR,
"name": "Bottom Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EAAttributes.keep_warm_time: {
"type": Platform.SENSOR,
"name": "Keep Warm Time",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EAAttributes.mode: {
"type": Platform.SENSOR,
"name": "Mode",
- "icon": "mdi:orbit"
+ "icon": "mdi:orbit",
},
EAAttributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
EAAttributes.time_remaining: {
"type": Platform.SENSOR,
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EAAttributes.top_temperature: {
"type": Platform.SENSOR,
"name": "Top Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
- }
+ },
},
0xEC: {
"name": "Electric Pressure Cooker",
@@ -1900,172 +1864,162 @@
"type": Platform.BINARY_SENSOR,
"name": "Cooking",
"icon": "mdi:fire",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
ECAttributes.with_pressure: {
"type": Platform.BINARY_SENSOR,
"name": "With Pressure",
"icon": "mdi:information",
- "device_class": BinarySensorDeviceClass.RUNNING
+ "device_class": BinarySensorDeviceClass.RUNNING,
},
ECAttributes.bottom_temperature: {
"type": Platform.SENSOR,
"name": "Bottom Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
ECAttributes.keep_warm_time: {
"type": Platform.SENSOR,
"name": "Keep Warm Time",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
ECAttributes.mode: {
"type": Platform.SENSOR,
"name": "Mode",
- "icon": "mdi:orbit"
+ "icon": "mdi:orbit",
},
ECAttributes.progress: {
"type": Platform.SENSOR,
"name": "Progress",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
ECAttributes.time_remaining: {
"type": Platform.SENSOR,
"name": "Time Remaining",
"icon": "mdi:progress-clock",
"unit": UnitOfTime.MINUTES,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
ECAttributes.top_temperature: {
"type": Platform.SENSOR,
"name": "Top Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
- }
+ },
},
0xED: {
"name": "Water Drinking Appliance",
"entities": {
- EDAttributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
- },
+ EDAttributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
EDAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
EDAttributes.filter1: {
"type": Platform.SENSOR,
"name": "Filter1 Available Days",
"icon": "mdi:air-filter",
"unit": UnitOfTime.DAYS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.filter2: {
"type": Platform.SENSOR,
"name": "Filter2 Available Days",
"icon": "mdi:air-filter",
"unit": UnitOfTime.DAYS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.filter3: {
"type": Platform.SENSOR,
"name": "Filter3 Available Days",
"icon": "mdi:air-filter",
"unit": UnitOfTime.DAYS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.life1: {
"type": Platform.SENSOR,
"name": "Filter1 Life Level",
"icon": "mdi:percent",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.life2: {
"type": Platform.SENSOR,
"name": "Filter2 Life Level",
"icon": "mdi:percent",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.life3: {
"type": Platform.SENSOR,
"name": "Filter3 Life Level",
"icon": "mdi:percent",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.in_tds: {
"type": Platform.SENSOR,
"name": "In TDS",
"icon": "mdi:water",
"unit": CONCENTRATION_PARTS_PER_MILLION,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.out_tds: {
"type": Platform.SENSOR,
"name": "Out TDS",
"icon": "mdi:water-plus",
"unit": CONCENTRATION_PARTS_PER_MILLION,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
EDAttributes.water_consumption: {
"type": Platform.SENSOR,
"name": "Water Consumption",
"icon": "mdi:water-pump",
"unit": UnitOfVolume.LITERS,
- "state_class": SensorStateClass.TOTAL_INCREASING
- }
- }
+ "state_class": SensorStateClass.TOTAL_INCREASING,
+ },
+ },
},
0xFA: {
"name": "Fan",
"entities": {
- "fan": {
- "type": Platform.FAN,
- "icon": "mdi:fan",
- "default": True
- },
+ "fan": {"type": Platform.FAN, "icon": "mdi:fan", "default": True},
FAAttributes.oscillation_mode: {
"type": Platform.SELECT,
"name": "Oscillation Mode",
"options": "oscillation_modes",
- "icon": "mdi:swap-horizontal-variant"
+ "icon": "mdi:swap-horizontal-variant",
},
FAAttributes.oscillation_angle: {
"type": Platform.SELECT,
"name": "Oscillation Angle",
"options": "oscillation_angles",
- "icon": "mdi:pan-horizontal"
+ "icon": "mdi:pan-horizontal",
},
FAAttributes.tilting_angle: {
"type": Platform.SELECT,
"name": "Tilting Angle",
"options": "tilting_angles",
- "icon": "mdi:pan-vertical"
- },
- FAAttributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
+ "icon": "mdi:pan-vertical",
},
+ FAAttributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
FAAttributes.oscillate: {
"type": Platform.SWITCH,
"name": "Oscillate",
- "icon": "mdi:swap-horizontal-bold"
+ "icon": "mdi:swap-horizontal-bold",
},
FAAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
- }
+ },
},
0xFB: {
"name": "Electric Heater",
@@ -2073,121 +2027,115 @@
"climate": {
"type": Platform.CLIMATE,
"icon": "mdi:air-conditioner",
- "default": True
- },
- FBAttributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
+ "default": True,
},
+ FBAttributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
FBAttributes.heating_level: {
"type": Platform.NUMBER,
"name": "Heating Level",
"icon": "mdi:fire",
"max": 10,
"min": 1,
- "step": 1
+ "step": 1,
},
FBAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
FBAttributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
- }
+ },
},
0xFC: {
"name": "Air Purifier",
"entities": {
- FCAttributes.child_lock: {
- "type": Platform.LOCK,
- "name": "Child Lock"
- },
+ FCAttributes.child_lock: {"type": Platform.LOCK, "name": "Child Lock"},
FCAttributes.anion: {
"type": Platform.SWITCH,
"name": "Anion",
- "icon": "mdi:vanish"
+ "icon": "mdi:vanish",
},
FCAttributes.prompt_tone: {
"type": Platform.SWITCH,
"name": "Prompt Tone",
- "icon": "mdi:bell"
+ "icon": "mdi:bell",
},
FCAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
FCAttributes.standby: {
"type": Platform.SWITCH,
"name": "Standby",
- "icon": "mdi:smoke-detector-variant"
+ "icon": "mdi:smoke-detector-variant",
},
FCAttributes.detect_mode: {
"type": Platform.SELECT,
"name": "Detect Mode",
"options": "detect_modes",
- "icon": "mdi:smoke-detector-variant"
+ "icon": "mdi:smoke-detector-variant",
},
FCAttributes.mode: {
"type": Platform.SELECT,
"name": "Mode",
"options": "modes",
- "icon": "mdi:rotate-360"
+ "icon": "mdi:rotate-360",
},
FCAttributes.fan_speed: {
"type": Platform.SELECT,
"name": "Fan Speed",
"options": "fan_speeds",
- "icon": "mdi:fan"
+ "icon": "mdi:fan",
},
FCAttributes.screen_display: {
"type": Platform.SELECT,
"name": "Screen Display",
"options": "screen_displays",
- "icon": "mdi:television-ambient-light"
+ "icon": "mdi:television-ambient-light",
},
FCAttributes.pm25: {
"type": Platform.SENSOR,
"name": "PM 2.5",
"device_class": SensorDeviceClass.PM25,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
FCAttributes.tvoc: {
"type": Platform.SENSOR,
"name": "TVOC",
"icon": "mdi:heat-wave",
"unit": CONCENTRATION_PARTS_PER_MILLION,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
FCAttributes.hcho: {
"type": Platform.SENSOR,
"name": "Methanal",
"icon": "mdi:molecule",
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
FCAttributes.filter1_life: {
"type": Platform.SENSOR,
"name": "Filter1 Life Level",
"icon": "mdi:air-filter",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
FCAttributes.filter2_life: {
"type": Platform.SENSOR,
"name": "Filter2 Life Level",
"icon": "mdi:air-filter",
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
0xFD: {
"name": "Humidifier",
@@ -2195,49 +2143,49 @@
Platform.HUMIDIFIER: {
"type": Platform.HUMIDIFIER,
"icon": "mdi:air-humidifier",
- "default": True
+ "default": True,
},
FDAttributes.disinfect: {
"type": Platform.SWITCH,
"name": "Disinfect",
- "icon": "mdi:water-plus-outline"
+ "icon": "mdi:water-plus-outline",
},
FDAttributes.prompt_tone: {
"type": Platform.SWITCH,
"name": "Prompt Tone",
- "icon": "mdi:bell"
+ "icon": "mdi:bell",
},
FDAttributes.power: {
"type": Platform.SWITCH,
"name": "Power",
- "icon": "mdi:power"
+ "icon": "mdi:power",
},
FDAttributes.fan_speed: {
"type": Platform.SELECT,
"name": "Fan Speed",
"options": "fan_speeds",
- "icon": "mdi:fan"
+ "icon": "mdi:fan",
},
FDAttributes.screen_display: {
"type": Platform.SELECT,
"name": "Screen Display",
"options": "screen_displays",
- "icon": "mdi:television-ambient-light"
+ "icon": "mdi:television-ambient-light",
},
FDAttributes.current_humidity: {
"type": Platform.SENSOR,
"name": "Current Humidity",
"device_class": SensorDeviceClass.HUMIDITY,
"unit": PERCENTAGE,
- "state_class": SensorStateClass.MEASUREMENT
+ "state_class": SensorStateClass.MEASUREMENT,
},
FDAttributes.current_temperature: {
"type": Platform.SENSOR,
"name": "Current Temperature",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit": UnitOfTemperature.CELSIUS,
- "state_class": SensorStateClass.MEASUREMENT
- }
- }
+ "state_class": SensorStateClass.MEASUREMENT,
+ },
+ },
},
}
diff --git a/custom_components/midea_ac_lan/midea_entity.py b/custom_components/midea_ac_lan/midea_entity.py
index d418b928..678c13e7 100644
--- a/custom_components/midea_ac_lan/midea_entity.py
+++ b/custom_components/midea_ac_lan/midea_entity.py
@@ -1,8 +1,10 @@
+import logging
+
from homeassistant.helpers.entity import Entity
+
from .const import DOMAIN
from .midea_devices import MIDEA_DEVICES
-import logging
_LOGGER = logging.getLogger(__name__)
@@ -25,10 +27,10 @@ def device_info(self):
return {
"manufacturer": "Midea",
"model": f"{MIDEA_DEVICES[self._device.device_type]['name']} "
- f"{self._device.model}"
- f" ({self._device.subtype})",
+ f"{self._device.model}"
+ f" ({self._device.subtype})",
"identifiers": {(DOMAIN, self._device.device_id)},
- "name": self._device_name
+ "name": self._device_name,
}
@property
@@ -41,8 +43,11 @@ def should_poll(self):
@property
def name(self):
- return f"{self._device_name} {self._config.get('name')}" if "name" in self._config \
+ return (
+ f"{self._device_name} {self._config.get('name')}"
+ if "name" in self._config
else self._device_name
+ )
@property
def available(self):
@@ -57,4 +62,6 @@ def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
- _LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
+ _LOGGER.debug(
+ f"Entity {self.entity_id} update_state {repr(e)}, status = {status}"
+ )
diff --git a/custom_components/midea_ac_lan/number.py b/custom_components/midea_ac_lan/number.py
index 987e78eb..dbe8dd19 100644
--- a/custom_components/midea_ac_lan/number.py
+++ b/custom_components/midea_ac_lan/number.py
@@ -1,23 +1,15 @@
-from .midea_entity import MideaEntity
-from .midea_devices import MIDEA_DEVICES
from homeassistant.components.number import NumberEntity
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SWITCHES
-)
-from .const import (
- DOMAIN,
- DEVICES,
-)
+from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
+
+from .const import DEVICES, DOMAIN
+from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
numbers = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.NUMBER and entity_key in extra_switches:
@@ -35,24 +27,39 @@ def __init__(self, device, entity_key: str):
@property
def native_min_value(self):
- return 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)
+ return (
+ 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
def native_max_value(self):
- return 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)
+ return (
+ 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
def native_step(self):
- return 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)
+ return (
+ 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
def native_value(self):
diff --git a/custom_components/midea_ac_lan/select.py b/custom_components/midea_ac_lan/select.py
index 3e44b022..67cf1aec 100644
--- a/custom_components/midea_ac_lan/select.py
+++ b/custom_components/midea_ac_lan/select.py
@@ -1,23 +1,15 @@
-from .midea_entity import MideaEntity
-from .midea_devices import MIDEA_DEVICES
from homeassistant.components.select import SelectEntity
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SWITCHES
-)
-from .const import (
- DOMAIN,
- DEVICES,
-)
+from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
+
+from .const import DEVICES, DOMAIN
+from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
selects = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.SELECT and entity_key in extra_switches:
diff --git a/custom_components/midea_ac_lan/sensor.py b/custom_components/midea_ac_lan/sensor.py
index 956bcb90..78221898 100644
--- a/custom_components/midea_ac_lan/sensor.py
+++ b/custom_components/midea_ac_lan/sensor.py
@@ -1,23 +1,15 @@
-from .midea_entity import MideaEntity
-from .midea_devices import MIDEA_DEVICES
from homeassistant.components.sensor import SensorEntity
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SENSORS
-)
-from .const import (
- DOMAIN,
- DEVICES
-)
+from homeassistant.const import CONF_DEVICE_ID, CONF_SENSORS, Platform
+
+from .const import DEVICES, DOMAIN
+from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_sensors = config_entry.options.get(
- CONF_SENSORS, []
- )
+ extra_sensors = config_entry.options.get(CONF_SENSORS, [])
sensors = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.SENSOR and entity_key in extra_sensors:
diff --git a/custom_components/midea_ac_lan/switch.py b/custom_components/midea_ac_lan/switch.py
index 6c91cadd..c6a24cff 100644
--- a/custom_components/midea_ac_lan/switch.py
+++ b/custom_components/midea_ac_lan/switch.py
@@ -1,23 +1,15 @@
-from .midea_entity import MideaEntity
-from .midea_devices import MIDEA_DEVICES
+from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
from homeassistant.helpers.entity import ToggleEntity
-from homeassistant.const import (
- Platform,
- CONF_DEVICE_ID,
- CONF_SWITCHES
-)
-from .const import (
- DOMAIN,
- DEVICES,
-)
+
+from .const import DEVICES, DOMAIN
+from .midea_devices import MIDEA_DEVICES
+from .midea_entity import MideaEntity
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
switches = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.SWITCH and entity_key in extra_switches:
diff --git a/custom_components/midea_ac_lan/water_heater.py b/custom_components/midea_ac_lan/water_heater.py
index 83fb04db..20d3959c 100644
--- a/custom_components/midea_ac_lan/water_heater.py
+++ b/custom_components/midea_ac_lan/water_heater.py
@@ -1,31 +1,29 @@
import functools as ft
+import logging
from homeassistant.components.water_heater import (
WaterHeaterEntity,
WaterHeaterEntityFeature,
)
from homeassistant.const import (
- Platform,
- UnitOfTemperature,
- PRECISION_WHOLE,
- PRECISION_HALVES,
ATTR_TEMPERATURE,
CONF_DEVICE_ID,
CONF_SWITCHES,
- STATE_ON,
+ PRECISION_HALVES,
+ PRECISION_WHOLE,
STATE_OFF,
+ STATE_ON,
+ Platform,
+ UnitOfTemperature,
)
-from .const import (
- DOMAIN,
- DEVICES
-)
-from .midea.devices.e6.device import DeviceAttributes as E6Attributes
+
+from .const import DEVICES, DOMAIN
from .midea.devices.c3.device import DeviceAttributes as C3Attributes
from .midea.devices.cd.device import DeviceAttributes as CDAttributes
+from .midea.devices.e6.device import DeviceAttributes as E6Attributes
from .midea_devices import MIDEA_DEVICES
from .midea_entity import MideaEntity
-import logging
_LOGGER = logging.getLogger(__name__)
E2_TEMPERATURE_MAX = 75
@@ -37,12 +35,12 @@
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
- extra_switches = config_entry.options.get(
- CONF_SWITCHES, []
- )
+ extra_switches = config_entry.options.get(CONF_SWITCHES, [])
devs = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
- if config["type"] == Platform.WATER_HEATER and (config.get("default") or entity_key in extra_switches):
+ if config["type"] == Platform.WATER_HEATER and (
+ config.get("default") or entity_key in extra_switches
+ ):
if device.device_type == 0xE2:
devs.append(MideaE2WaterHeater(device, entity_key))
elif device.device_type == 0xE3:
@@ -98,7 +96,11 @@ def temperature_unit(self):
@property
def current_operation(self):
- return self._device.get_attribute("mode") if self._device.get_attribute("power") else STATE_OFF
+ return (
+ self._device.get_attribute("mode")
+ if self._device.get_attribute("power")
+ else STATE_OFF
+ )
@property
def current_temperature(self):
@@ -137,7 +139,9 @@ def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
- _LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
+ _LOGGER.debug(
+ f"Entity {self.entity_id} update_state {repr(e)}, status = {status}"
+ )
class MideaE2WaterHeater(MideaWaterHeater):
@@ -176,7 +180,11 @@ def __init__(self, device, entity_key):
@property
def state(self):
- return STATE_ON if self._device.get_attribute(C3Attributes.dhw_power) else STATE_OFF
+ return (
+ STATE_ON
+ if self._device.get_attribute(C3Attributes.dhw_power)
+ else STATE_OFF
+ )
@property
def current_temperature(self):
@@ -225,20 +233,28 @@ def __init__(self, device, entity_key, use):
super().__init__(device, entity_key)
self._use = use
self._power_attr = MideaE6WaterHeater._powers[self._use]
- self._current_temperature_attr = MideaE6WaterHeater._current_temperatures[self._use]
- self._target_temperature_attr = MideaE6WaterHeater._target_temperatures[self._use]
+ self._current_temperature_attr = MideaE6WaterHeater._current_temperatures[
+ self._use
+ ]
+ self._target_temperature_attr = MideaE6WaterHeater._target_temperatures[
+ self._use
+ ]
@property
def state(self):
if self._use == 0: # for heating
- return STATE_ON if \
- self._device.get_attribute(E6Attributes.main_power) and \
- self._device.get_attribute(E6Attributes.heating_power) \
+ return (
+ STATE_ON
+ if self._device.get_attribute(E6Attributes.main_power)
+ and self._device.get_attribute(E6Attributes.heating_power)
else STATE_OFF
+ )
else: # for bathing
- return STATE_ON if \
- self._device.get_attribute(E6Attributes.main_power) \
+ return (
+ STATE_ON
+ if self._device.get_attribute(E6Attributes.main_power)
else STATE_OFF
+ )
@property
def current_temperature(self):
@@ -275,8 +291,10 @@ def __init__(self, device, entity_key):
@property
def supported_features(self):
- return WaterHeaterEntityFeature.TARGET_TEMPERATURE | \
- WaterHeaterEntityFeature.OPERATION_MODE
+ return (
+ WaterHeaterEntityFeature.TARGET_TEMPERATURE
+ | WaterHeaterEntityFeature.OPERATION_MODE
+ )
@property
def min_temp(self):