mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Bump broadlink from 0.16.0 to 0.17.0 (#47779)
This commit is contained in:
parent
92852b9c10
commit
9ca0cd5464
@ -39,11 +39,7 @@ class BroadlinkFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
async def async_set_device(self, device, raise_on_progress=True):
|
async def async_set_device(self, device, raise_on_progress=True):
|
||||||
"""Define a device for the config flow."""
|
"""Define a device for the config flow."""
|
||||||
supported_types = {
|
supported_types = set.union(*DOMAINS_AND_TYPES.values())
|
||||||
device_type
|
|
||||||
for device_types in DOMAINS_AND_TYPES
|
|
||||||
for device_type in device_types[1]
|
|
||||||
}
|
|
||||||
if device.type not in supported_types:
|
if device.type not in supported_types:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Unsupported device: %s. If it worked before, please open "
|
"Unsupported device: %s. If it worked before, please open "
|
||||||
|
@ -5,11 +5,26 @@ from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
|||||||
|
|
||||||
DOMAIN = "broadlink"
|
DOMAIN = "broadlink"
|
||||||
|
|
||||||
DOMAINS_AND_TYPES = (
|
DOMAINS_AND_TYPES = {
|
||||||
(REMOTE_DOMAIN, ("RM2", "RM4")),
|
REMOTE_DOMAIN: {"RM4MINI", "RM4PRO", "RMMINI", "RMMINIB", "RMPRO"},
|
||||||
(SENSOR_DOMAIN, ("A1", "RM2", "RM4")),
|
SENSOR_DOMAIN: {"A1", "RM4MINI", "RM4PRO", "RMPRO"},
|
||||||
(SWITCH_DOMAIN, ("BG1", "MP1", "RM2", "RM4", "SP1", "SP2", "SP4", "SP4B")),
|
SWITCH_DOMAIN: {
|
||||||
)
|
"BG1",
|
||||||
|
"MP1",
|
||||||
|
"RM4MINI",
|
||||||
|
"RM4PRO",
|
||||||
|
"RMMINI",
|
||||||
|
"RMMINIB",
|
||||||
|
"RMPRO",
|
||||||
|
"SP1",
|
||||||
|
"SP2",
|
||||||
|
"SP2S",
|
||||||
|
"SP3",
|
||||||
|
"SP3S",
|
||||||
|
"SP4",
|
||||||
|
"SP4B",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
DEFAULT_PORT = 80
|
DEFAULT_PORT = 80
|
||||||
DEFAULT_TIMEOUT = 5
|
DEFAULT_TIMEOUT = 5
|
||||||
|
@ -22,9 +22,9 @@ from .updater import get_update_manager
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_domains(device_type):
|
def get_domains(dev_type):
|
||||||
"""Return the domains available for a device type."""
|
"""Return the domains available for a device type."""
|
||||||
return {domain for domain, types in DOMAINS_AND_TYPES if device_type in types}
|
return {d for d, t in DOMAINS_AND_TYPES.items() if dev_type in t}
|
||||||
|
|
||||||
|
|
||||||
class BroadlinkDevice:
|
class BroadlinkDevice:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "broadlink",
|
"domain": "broadlink",
|
||||||
"name": "Broadlink",
|
"name": "Broadlink",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/broadlink",
|
"documentation": "https://www.home-assistant.io/integrations/broadlink",
|
||||||
"requirements": ["broadlink==0.16.0"],
|
"requirements": ["broadlink==0.17.0"],
|
||||||
"codeowners": ["@danielhiversen", "@felipediel"],
|
"codeowners": ["@danielhiversen", "@felipediel"],
|
||||||
"config_flow": true
|
"config_flow": true
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ from homeassistant.components.remote import (
|
|||||||
DOMAIN as RM_DOMAIN,
|
DOMAIN as RM_DOMAIN,
|
||||||
PLATFORM_SCHEMA,
|
PLATFORM_SCHEMA,
|
||||||
SERVICE_DELETE_COMMAND,
|
SERVICE_DELETE_COMMAND,
|
||||||
|
SERVICE_LEARN_COMMAND,
|
||||||
|
SERVICE_SEND_COMMAND,
|
||||||
SUPPORT_DELETE_COMMAND,
|
SUPPORT_DELETE_COMMAND,
|
||||||
SUPPORT_LEARN_COMMAND,
|
SUPPORT_LEARN_COMMAND,
|
||||||
RemoteEntity,
|
RemoteEntity,
|
||||||
@ -129,6 +131,7 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||||||
self._codes = {}
|
self._codes = {}
|
||||||
self._flags = defaultdict(int)
|
self._flags = defaultdict(int)
|
||||||
self._state = True
|
self._state = True
|
||||||
|
self._lock = asyncio.Lock()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -171,39 +174,44 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||||||
"sw_version": self._device.fw_version,
|
"sw_version": self._device.fw_version,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_code(self, command, device):
|
def _extract_codes(self, commands, device=None):
|
||||||
"""Return a code and a boolean indicating a toggle command.
|
"""Extract a list of codes.
|
||||||
|
|
||||||
If the command starts with `b64:`, extract the code from it.
|
If the command starts with `b64:`, extract the code from it.
|
||||||
Otherwise, extract the code from the dictionary, using the device
|
Otherwise, extract the code from storage, using the command and
|
||||||
and command as keys.
|
device as keys.
|
||||||
|
|
||||||
You need to change the flag whenever a toggle command is sent
|
The codes are returned in sublists. For toggle commands, the
|
||||||
successfully. Use `self._flags[device] ^= 1`.
|
sublist contains two codes that must be sent alternately with
|
||||||
|
each call.
|
||||||
"""
|
"""
|
||||||
if command.startswith("b64:"):
|
code_list = []
|
||||||
code, is_toggle_cmd = command[4:], False
|
for cmd in commands:
|
||||||
|
if cmd.startswith("b64:"):
|
||||||
|
codes = [cmd[4:]]
|
||||||
|
|
||||||
else:
|
|
||||||
if device is None:
|
|
||||||
raise KeyError("You need to specify a device")
|
|
||||||
|
|
||||||
try:
|
|
||||||
code = self._codes[device][command]
|
|
||||||
except KeyError as err:
|
|
||||||
raise KeyError("Command not found") from err
|
|
||||||
|
|
||||||
# For toggle commands, alternate between codes in a list.
|
|
||||||
if isinstance(code, list):
|
|
||||||
code = code[self._flags[device]]
|
|
||||||
is_toggle_cmd = True
|
|
||||||
else:
|
else:
|
||||||
is_toggle_cmd = False
|
if device is None:
|
||||||
|
raise ValueError("You need to specify a device")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return data_packet(code), is_toggle_cmd
|
codes = self._codes[device][cmd]
|
||||||
except ValueError as err:
|
except KeyError as err:
|
||||||
raise ValueError("Invalid code") from err
|
raise ValueError(f"Command not found: {repr(cmd)}") from err
|
||||||
|
|
||||||
|
if isinstance(codes, list):
|
||||||
|
codes = codes[:]
|
||||||
|
else:
|
||||||
|
codes = [codes]
|
||||||
|
|
||||||
|
for idx, code in enumerate(codes):
|
||||||
|
try:
|
||||||
|
codes[idx] = data_packet(code)
|
||||||
|
except ValueError as err:
|
||||||
|
raise ValueError(f"Invalid code: {repr(code)}") from err
|
||||||
|
|
||||||
|
code_list.append(codes)
|
||||||
|
return code_list
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def get_codes(self):
|
def get_codes(self):
|
||||||
@ -261,44 +269,50 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||||||
device = kwargs.get(ATTR_DEVICE)
|
device = kwargs.get(ATTR_DEVICE)
|
||||||
repeat = kwargs[ATTR_NUM_REPEATS]
|
repeat = kwargs[ATTR_NUM_REPEATS]
|
||||||
delay = kwargs[ATTR_DELAY_SECS]
|
delay = kwargs[ATTR_DELAY_SECS]
|
||||||
|
service = f"{RM_DOMAIN}.{SERVICE_SEND_COMMAND}"
|
||||||
|
|
||||||
if not self._state:
|
if not self._state:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"remote.send_command canceled: %s entity is turned off", self.entity_id
|
"%s canceled: %s entity is turned off", service, self.entity_id
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
should_delay = False
|
try:
|
||||||
|
code_list = self._extract_codes(commands, device)
|
||||||
|
except ValueError as err:
|
||||||
|
_LOGGER.error("Failed to call %s: %s", service, err)
|
||||||
|
raise
|
||||||
|
|
||||||
for _, cmd in product(range(repeat), commands):
|
rf_flags = {0xB2, 0xD7}
|
||||||
if should_delay:
|
if not hasattr(self._device.api, "sweep_frequency") and any(
|
||||||
|
c[0] in rf_flags for codes in code_list for c in codes
|
||||||
|
):
|
||||||
|
err_msg = f"{self.entity_id} doesn't support sending RF commands"
|
||||||
|
_LOGGER.error("Failed to call %s: %s", service, err_msg)
|
||||||
|
raise ValueError(err_msg)
|
||||||
|
|
||||||
|
at_least_one_sent = False
|
||||||
|
for _, codes in product(range(repeat), code_list):
|
||||||
|
if at_least_one_sent:
|
||||||
await asyncio.sleep(delay)
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
try:
|
if len(codes) > 1:
|
||||||
code, is_toggle_cmd = self.get_code(cmd, device)
|
code = codes[self._flags[device]]
|
||||||
|
else:
|
||||||
except (KeyError, ValueError) as err:
|
code = codes[0]
|
||||||
_LOGGER.error("Failed to send '%s': %s", cmd, err)
|
|
||||||
should_delay = False
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self._device.async_request(self._device.api.send_data, code)
|
await self._device.async_request(self._device.api.send_data, code)
|
||||||
|
except (BroadlinkException, OSError) as err:
|
||||||
except (AuthorizationError, NetworkTimeoutError, OSError) as err:
|
_LOGGER.error("Error during %s: %s", service, err)
|
||||||
_LOGGER.error("Failed to send '%s': %s", cmd, err)
|
|
||||||
break
|
break
|
||||||
|
|
||||||
except BroadlinkException as err:
|
if len(codes) > 1:
|
||||||
_LOGGER.error("Failed to send '%s': %s", cmd, err)
|
|
||||||
should_delay = False
|
|
||||||
continue
|
|
||||||
|
|
||||||
should_delay = True
|
|
||||||
if is_toggle_cmd:
|
|
||||||
self._flags[device] ^= 1
|
self._flags[device] ^= 1
|
||||||
|
at_least_one_sent = True
|
||||||
|
|
||||||
self._flag_storage.async_delay_save(self.get_flags, FLAG_SAVE_DELAY)
|
if at_least_one_sent:
|
||||||
|
self._flag_storage.async_delay_save(self.get_flags, FLAG_SAVE_DELAY)
|
||||||
|
|
||||||
async def async_learn_command(self, **kwargs):
|
async def async_learn_command(self, **kwargs):
|
||||||
"""Learn a list of commands from a remote."""
|
"""Learn a list of commands from a remote."""
|
||||||
@ -307,39 +321,47 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||||||
command_type = kwargs[ATTR_COMMAND_TYPE]
|
command_type = kwargs[ATTR_COMMAND_TYPE]
|
||||||
device = kwargs[ATTR_DEVICE]
|
device = kwargs[ATTR_DEVICE]
|
||||||
toggle = kwargs[ATTR_ALTERNATIVE]
|
toggle = kwargs[ATTR_ALTERNATIVE]
|
||||||
|
service = f"{RM_DOMAIN}.{SERVICE_LEARN_COMMAND}"
|
||||||
|
|
||||||
if not self._state:
|
if not self._state:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"remote.learn_command canceled: %s entity is turned off", self.entity_id
|
"%s canceled: %s entity is turned off", service, self.entity_id
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if command_type == COMMAND_TYPE_IR:
|
async with self._lock:
|
||||||
learn_command = self._async_learn_ir_command
|
if command_type == COMMAND_TYPE_IR:
|
||||||
else:
|
learn_command = self._async_learn_ir_command
|
||||||
learn_command = self._async_learn_rf_command
|
|
||||||
|
|
||||||
should_store = False
|
elif hasattr(self._device.api, "sweep_frequency"):
|
||||||
|
learn_command = self._async_learn_rf_command
|
||||||
|
|
||||||
for command in commands:
|
else:
|
||||||
try:
|
err_msg = f"{self.entity_id} doesn't support learning RF commands"
|
||||||
code = await learn_command(command)
|
_LOGGER.error("Failed to call %s: %s", service, err_msg)
|
||||||
if toggle:
|
raise ValueError(err_msg)
|
||||||
code = [code, await learn_command(command)]
|
|
||||||
|
|
||||||
except (AuthorizationError, NetworkTimeoutError, OSError) as err:
|
should_store = False
|
||||||
_LOGGER.error("Failed to learn '%s': %s", command, err)
|
|
||||||
break
|
|
||||||
|
|
||||||
except BroadlinkException as err:
|
for command in commands:
|
||||||
_LOGGER.error("Failed to learn '%s': %s", command, err)
|
try:
|
||||||
continue
|
code = await learn_command(command)
|
||||||
|
if toggle:
|
||||||
|
code = [code, await learn_command(command)]
|
||||||
|
|
||||||
self._codes.setdefault(device, {}).update({command: code})
|
except (AuthorizationError, NetworkTimeoutError, OSError) as err:
|
||||||
should_store = True
|
_LOGGER.error("Failed to learn '%s': %s", command, err)
|
||||||
|
break
|
||||||
|
|
||||||
if should_store:
|
except BroadlinkException as err:
|
||||||
await self._code_storage.async_save(self._codes)
|
_LOGGER.error("Failed to learn '%s': %s", command, err)
|
||||||
|
continue
|
||||||
|
|
||||||
|
self._codes.setdefault(device, {}).update({command: code})
|
||||||
|
should_store = True
|
||||||
|
|
||||||
|
if should_store:
|
||||||
|
await self._code_storage.async_save(self._codes)
|
||||||
|
|
||||||
async def _async_learn_ir_command(self, command):
|
async def _async_learn_ir_command(self, command):
|
||||||
"""Learn an infrared command."""
|
"""Learn an infrared command."""
|
||||||
|
@ -109,7 +109,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
"""Set up the Broadlink switch."""
|
"""Set up the Broadlink switch."""
|
||||||
device = hass.data[DOMAIN].devices[config_entry.entry_id]
|
device = hass.data[DOMAIN].devices[config_entry.entry_id]
|
||||||
|
|
||||||
if device.api.type in {"RM2", "RM4"}:
|
if device.api.type in {"RM4MINI", "RM4PRO", "RMMINI", "RMMINIB", "RMPRO"}:
|
||||||
platform_data = hass.data[DOMAIN].platforms.get(SWITCH_DOMAIN, {})
|
platform_data = hass.data[DOMAIN].platforms.get(SWITCH_DOMAIN, {})
|
||||||
user_defined_switches = platform_data.get(device.api.mac, {})
|
user_defined_switches = platform_data.get(device.api.mac, {})
|
||||||
switches = [
|
switches = [
|
||||||
@ -119,12 +119,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
elif device.api.type == "SP1":
|
elif device.api.type == "SP1":
|
||||||
switches = [BroadlinkSP1Switch(device)]
|
switches = [BroadlinkSP1Switch(device)]
|
||||||
|
|
||||||
elif device.api.type == "SP2":
|
elif device.api.type in {"SP2", "SP2S", "SP3", "SP3S", "SP4", "SP4B"}:
|
||||||
switches = [BroadlinkSP2Switch(device)]
|
switches = [BroadlinkSP2Switch(device)]
|
||||||
|
|
||||||
elif device.api.type in {"SP4", "SP4B"}:
|
|
||||||
switches = [BroadlinkSP4Switch(device)]
|
|
||||||
|
|
||||||
elif device.api.type == "BG1":
|
elif device.api.type == "BG1":
|
||||||
switches = [BroadlinkBG1Slot(device, slot) for slot in range(1, 3)]
|
switches = [BroadlinkBG1Slot(device, slot) for slot in range(1, 3)]
|
||||||
|
|
||||||
@ -143,7 +140,6 @@ class BroadlinkSwitch(SwitchEntity, RestoreEntity, ABC):
|
|||||||
self._command_on = command_on
|
self._command_on = command_on
|
||||||
self._command_off = command_off
|
self._command_off = command_off
|
||||||
self._coordinator = device.update_manager.coordinator
|
self._coordinator = device.update_manager.coordinator
|
||||||
self._device_class = None
|
|
||||||
self._state = None
|
self._state = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -174,7 +170,7 @@ class BroadlinkSwitch(SwitchEntity, RestoreEntity, ABC):
|
|||||||
@property
|
@property
|
||||||
def device_class(self):
|
def device_class(self):
|
||||||
"""Return device class."""
|
"""Return device class."""
|
||||||
return self._device_class
|
return DEVICE_CLASS_SWITCH
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self):
|
||||||
@ -254,7 +250,6 @@ class BroadlinkSP1Switch(BroadlinkSwitch):
|
|||||||
def __init__(self, device):
|
def __init__(self, device):
|
||||||
"""Initialize the switch."""
|
"""Initialize the switch."""
|
||||||
super().__init__(device, 1, 0)
|
super().__init__(device, 1, 0)
|
||||||
self._device_class = DEVICE_CLASS_OUTLET
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self):
|
||||||
@ -277,10 +272,8 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch):
|
|||||||
def __init__(self, device, *args, **kwargs):
|
def __init__(self, device, *args, **kwargs):
|
||||||
"""Initialize the switch."""
|
"""Initialize the switch."""
|
||||||
super().__init__(device, *args, **kwargs)
|
super().__init__(device, *args, **kwargs)
|
||||||
self._state = self._coordinator.data["state"]
|
self._state = self._coordinator.data["pwr"]
|
||||||
self._load_power = self._coordinator.data["load_power"]
|
self._load_power = self._coordinator.data.get("power")
|
||||||
if device.api.model == "SC1":
|
|
||||||
self._device_class = DEVICE_CLASS_SWITCH
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def assumed_state(self):
|
def assumed_state(self):
|
||||||
@ -292,33 +285,12 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch):
|
|||||||
"""Return the current power usage in Watt."""
|
"""Return the current power usage in Watt."""
|
||||||
return self._load_power
|
return self._load_power
|
||||||
|
|
||||||
@callback
|
|
||||||
def update_data(self):
|
|
||||||
"""Update data."""
|
|
||||||
if self._coordinator.last_update_success:
|
|
||||||
self._state = self._coordinator.data["state"]
|
|
||||||
self._load_power = self._coordinator.data["load_power"]
|
|
||||||
self.async_write_ha_state()
|
|
||||||
|
|
||||||
|
|
||||||
class BroadlinkSP4Switch(BroadlinkSP1Switch):
|
|
||||||
"""Representation of a Broadlink SP4 switch."""
|
|
||||||
|
|
||||||
def __init__(self, device, *args, **kwargs):
|
|
||||||
"""Initialize the switch."""
|
|
||||||
super().__init__(device, *args, **kwargs)
|
|
||||||
self._state = self._coordinator.data["pwr"]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def assumed_state(self):
|
|
||||||
"""Return True if unable to access real state of the switch."""
|
|
||||||
return False
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def update_data(self):
|
def update_data(self):
|
||||||
"""Update data."""
|
"""Update data."""
|
||||||
if self._coordinator.last_update_success:
|
if self._coordinator.last_update_success:
|
||||||
self._state = self._coordinator.data["pwr"]
|
self._state = self._coordinator.data["pwr"]
|
||||||
|
self._load_power = self._coordinator.data.get("power")
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
@ -330,7 +302,6 @@ class BroadlinkMP1Slot(BroadlinkSwitch):
|
|||||||
super().__init__(device, 1, 0)
|
super().__init__(device, 1, 0)
|
||||||
self._slot = slot
|
self._slot = slot
|
||||||
self._state = self._coordinator.data[f"s{slot}"]
|
self._state = self._coordinator.data[f"s{slot}"]
|
||||||
self._device_class = DEVICE_CLASS_OUTLET
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self):
|
||||||
@ -374,7 +345,6 @@ class BroadlinkBG1Slot(BroadlinkSwitch):
|
|||||||
super().__init__(device, 1, 0)
|
super().__init__(device, 1, 0)
|
||||||
self._slot = slot
|
self._slot = slot
|
||||||
self._state = self._coordinator.data[f"pwr{slot}"]
|
self._state = self._coordinator.data[f"pwr{slot}"]
|
||||||
self._device_class = DEVICE_CLASS_OUTLET
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self):
|
def unique_id(self):
|
||||||
@ -391,6 +361,11 @@ class BroadlinkBG1Slot(BroadlinkSwitch):
|
|||||||
"""Return True if unable to access real state of the switch."""
|
"""Return True if unable to access real state of the switch."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_class(self):
|
||||||
|
"""Return device class."""
|
||||||
|
return DEVICE_CLASS_OUTLET
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def update_data(self):
|
def update_data(self):
|
||||||
"""Update data."""
|
"""Update data."""
|
||||||
|
@ -1,17 +1,9 @@
|
|||||||
"""Support for fetching data from Broadlink devices."""
|
"""Support for fetching data from Broadlink devices."""
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from functools import partial
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import broadlink as blk
|
from broadlink.exceptions import AuthorizationError, BroadlinkException
|
||||||
from broadlink.exceptions import (
|
|
||||||
AuthorizationError,
|
|
||||||
BroadlinkException,
|
|
||||||
CommandNotSupportedError,
|
|
||||||
NetworkTimeoutError,
|
|
||||||
StorageError,
|
|
||||||
)
|
|
||||||
|
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
from homeassistant.util import dt
|
from homeassistant.util import dt
|
||||||
@ -21,17 +13,20 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
def get_update_manager(device):
|
def get_update_manager(device):
|
||||||
"""Return an update manager for a given Broadlink device."""
|
"""Return an update manager for a given Broadlink device."""
|
||||||
if device.api.model.startswith("RM mini"):
|
|
||||||
return BroadlinkRMMini3UpdateManager(device)
|
|
||||||
|
|
||||||
update_managers = {
|
update_managers = {
|
||||||
"A1": BroadlinkA1UpdateManager,
|
"A1": BroadlinkA1UpdateManager,
|
||||||
"BG1": BroadlinkBG1UpdateManager,
|
"BG1": BroadlinkBG1UpdateManager,
|
||||||
"MP1": BroadlinkMP1UpdateManager,
|
"MP1": BroadlinkMP1UpdateManager,
|
||||||
"RM2": BroadlinkRMUpdateManager,
|
"RM4MINI": BroadlinkRMUpdateManager,
|
||||||
"RM4": BroadlinkRMUpdateManager,
|
"RM4PRO": BroadlinkRMUpdateManager,
|
||||||
|
"RMMINI": BroadlinkRMUpdateManager,
|
||||||
|
"RMMINIB": BroadlinkRMUpdateManager,
|
||||||
|
"RMPRO": BroadlinkRMUpdateManager,
|
||||||
"SP1": BroadlinkSP1UpdateManager,
|
"SP1": BroadlinkSP1UpdateManager,
|
||||||
"SP2": BroadlinkSP2UpdateManager,
|
"SP2": BroadlinkSP2UpdateManager,
|
||||||
|
"SP2S": BroadlinkSP2UpdateManager,
|
||||||
|
"SP3": BroadlinkSP2UpdateManager,
|
||||||
|
"SP3S": BroadlinkSP2UpdateManager,
|
||||||
"SP4": BroadlinkSP4UpdateManager,
|
"SP4": BroadlinkSP4UpdateManager,
|
||||||
"SP4B": BroadlinkSP4UpdateManager,
|
"SP4B": BroadlinkSP4UpdateManager,
|
||||||
}
|
}
|
||||||
@ -114,28 +109,18 @@ class BroadlinkMP1UpdateManager(BroadlinkUpdateManager):
|
|||||||
return await self.device.async_request(self.device.api.check_power)
|
return await self.device.async_request(self.device.api.check_power)
|
||||||
|
|
||||||
|
|
||||||
class BroadlinkRMMini3UpdateManager(BroadlinkUpdateManager):
|
|
||||||
"""Manages updates for Broadlink RM mini 3 devices."""
|
|
||||||
|
|
||||||
async def async_fetch_data(self):
|
|
||||||
"""Fetch data from the device."""
|
|
||||||
hello = partial(
|
|
||||||
blk.discover,
|
|
||||||
discover_ip_address=self.device.api.host[0],
|
|
||||||
timeout=self.device.api.timeout,
|
|
||||||
)
|
|
||||||
devices = await self.device.hass.async_add_executor_job(hello)
|
|
||||||
if not devices:
|
|
||||||
raise NetworkTimeoutError("The device is offline")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class BroadlinkRMUpdateManager(BroadlinkUpdateManager):
|
class BroadlinkRMUpdateManager(BroadlinkUpdateManager):
|
||||||
"""Manages updates for Broadlink RM2 and RM4 devices."""
|
"""Manages updates for Broadlink remotes."""
|
||||||
|
|
||||||
async def async_fetch_data(self):
|
async def async_fetch_data(self):
|
||||||
"""Fetch data from the device."""
|
"""Fetch data from the device."""
|
||||||
return await self.device.async_request(self.device.api.check_sensors)
|
device = self.device
|
||||||
|
|
||||||
|
if hasattr(device.api, "check_sensors"):
|
||||||
|
return await device.async_request(device.api.check_sensors)
|
||||||
|
|
||||||
|
await device.async_request(device.api.update)
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
class BroadlinkSP1UpdateManager(BroadlinkUpdateManager):
|
class BroadlinkSP1UpdateManager(BroadlinkUpdateManager):
|
||||||
@ -151,14 +136,14 @@ class BroadlinkSP2UpdateManager(BroadlinkUpdateManager):
|
|||||||
|
|
||||||
async def async_fetch_data(self):
|
async def async_fetch_data(self):
|
||||||
"""Fetch data from the device."""
|
"""Fetch data from the device."""
|
||||||
|
device = self.device
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
data["state"] = await self.device.async_request(self.device.api.check_power)
|
data["pwr"] = await device.async_request(device.api.check_power)
|
||||||
try:
|
|
||||||
data["load_power"] = await self.device.async_request(
|
if hasattr(device.api, "get_energy"):
|
||||||
self.device.api.get_energy
|
data["power"] = await device.async_request(device.api.get_energy)
|
||||||
)
|
|
||||||
except (CommandNotSupportedError, StorageError):
|
|
||||||
data["load_power"] = None
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ boto3==1.9.252
|
|||||||
bravia-tv==1.0.8
|
bravia-tv==1.0.8
|
||||||
|
|
||||||
# homeassistant.components.broadlink
|
# homeassistant.components.broadlink
|
||||||
broadlink==0.16.0
|
broadlink==0.17.0
|
||||||
|
|
||||||
# homeassistant.components.brother
|
# homeassistant.components.brother
|
||||||
brother==0.2.1
|
brother==0.2.1
|
||||||
|
@ -211,7 +211,7 @@ bond-api==0.1.11
|
|||||||
bravia-tv==1.0.8
|
bravia-tv==1.0.8
|
||||||
|
|
||||||
# homeassistant.components.broadlink
|
# homeassistant.components.broadlink
|
||||||
broadlink==0.16.0
|
broadlink==0.17.0
|
||||||
|
|
||||||
# homeassistant.components.brother
|
# homeassistant.components.brother
|
||||||
brother==0.2.1
|
brother==0.2.1
|
||||||
|
@ -12,7 +12,7 @@ BROADLINK_DEVICES = {
|
|||||||
"34ea34befc25",
|
"34ea34befc25",
|
||||||
"RM mini 3",
|
"RM mini 3",
|
||||||
"Broadlink",
|
"Broadlink",
|
||||||
"RM2",
|
"RMMINI",
|
||||||
0x2737,
|
0x2737,
|
||||||
57,
|
57,
|
||||||
8,
|
8,
|
||||||
@ -22,7 +22,7 @@ BROADLINK_DEVICES = {
|
|||||||
"34ea34b43b5a",
|
"34ea34b43b5a",
|
||||||
"RM mini 3",
|
"RM mini 3",
|
||||||
"Broadlink",
|
"Broadlink",
|
||||||
"RM4",
|
"RMMINIB",
|
||||||
0x5F36,
|
0x5F36,
|
||||||
44017,
|
44017,
|
||||||
10,
|
10,
|
||||||
@ -32,7 +32,7 @@ BROADLINK_DEVICES = {
|
|||||||
"34ea34b43d22",
|
"34ea34b43d22",
|
||||||
"RM pro",
|
"RM pro",
|
||||||
"Broadlink",
|
"Broadlink",
|
||||||
"RM2",
|
"RMPRO",
|
||||||
0x2787,
|
0x2787,
|
||||||
20025,
|
20025,
|
||||||
7,
|
7,
|
||||||
@ -42,7 +42,7 @@ BROADLINK_DEVICES = {
|
|||||||
"34ea34c43f31",
|
"34ea34c43f31",
|
||||||
"RM4 pro",
|
"RM4 pro",
|
||||||
"Broadlink",
|
"Broadlink",
|
||||||
"RM4",
|
"RM4PRO",
|
||||||
0x6026,
|
0x6026,
|
||||||
52,
|
52,
|
||||||
4,
|
4,
|
||||||
@ -62,7 +62,7 @@ BROADLINK_DEVICES = {
|
|||||||
"34ea34b61d2c",
|
"34ea34b61d2c",
|
||||||
"LB1",
|
"LB1",
|
||||||
"Broadlink",
|
"Broadlink",
|
||||||
"SmartBulb",
|
"LB1",
|
||||||
0x504E,
|
0x504E,
|
||||||
57,
|
57,
|
||||||
5,
|
5,
|
||||||
@ -96,9 +96,6 @@ class BroadlinkDevice:
|
|||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.broadlink.device.blk.gendevice",
|
"homeassistant.components.broadlink.device.blk.gendevice",
|
||||||
return_value=mock_api,
|
return_value=mock_api,
|
||||||
), patch(
|
|
||||||
"homeassistant.components.broadlink.updater.blk.discover",
|
|
||||||
return_value=[mock_api],
|
|
||||||
):
|
):
|
||||||
await hass.config_entries.async_setup(mock_entry.entry_id)
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user