From 90d493a51a042ee8f3ab6cab2736a286eea6d9c7 Mon Sep 17 00:00:00 2001 From: zhumuht <40521367+zhumuht@users.noreply.github.com> Date: Fri, 16 Aug 2019 15:26:11 +0800 Subject: [PATCH] Add broadlink switch retry time option (#25873) * add broadlink switch retry time in configuration * add broadlink switch retry time in configuration * formatted code by black tool * Change retry default value to 2 to keep the current behavior --- homeassistant/components/broadlink/switch.py | 68 ++++++++++++-------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/broadlink/switch.py b/homeassistant/components/broadlink/switch.py index 4d3fa644f47..277260c0336 100644 --- a/homeassistant/components/broadlink/switch.py +++ b/homeassistant/components/broadlink/switch.py @@ -34,7 +34,9 @@ TIME_BETWEEN_UPDATES = timedelta(seconds=5) DEFAULT_NAME = "Broadlink switch" DEFAULT_TIMEOUT = 10 +DEFAULT_RETRY = 2 CONF_SLOTS = "slots" +CONF_RETRY = "retry" RM_TYPES = [ "rm", @@ -82,6 +84,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( vol.Optional(CONF_FRIENDLY_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_TYPE, default=SWITCH_TYPES[0]): vol.In(SWITCH_TYPES), vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int, + vol.Optional(CONF_RETRY, default=DEFAULT_RETRY): cv.positive_int, } ) @@ -96,6 +99,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): friendly_name = config.get(CONF_FRIENDLY_NAME) mac_addr = binascii.unhexlify(config.get(CONF_MAC).encode().replace(b":", b"")) switch_type = config.get(CONF_TYPE) + retry_times = config.get(CONF_RETRY) def _get_mp1_slot_name(switch_friendly_name, slot): """Get slot name.""" @@ -116,21 +120,26 @@ def setup_platform(hass, config, add_entities, discovery_info=None): broadlink_device, device_config.get(CONF_COMMAND_ON), device_config.get(CONF_COMMAND_OFF), + retry_times, ) ) elif switch_type in SP1_TYPES: broadlink_device = broadlink.sp1((ip_addr, 80), mac_addr, None) - switches = [BroadlinkSP1Switch(friendly_name, broadlink_device)] + switches = [BroadlinkSP1Switch(friendly_name, broadlink_device, retry_times)] elif switch_type in SP2_TYPES: broadlink_device = broadlink.sp2((ip_addr, 80), mac_addr, None) - switches = [BroadlinkSP2Switch(friendly_name, broadlink_device)] + switches = [BroadlinkSP2Switch(friendly_name, broadlink_device, retry_times)] elif switch_type in MP1_TYPES: switches = [] broadlink_device = broadlink.mp1((ip_addr, 80), mac_addr, None) - parent_device = BroadlinkMP1Switch(broadlink_device) + parent_device = BroadlinkMP1Switch(broadlink_device, retry_times) for i in range(1, 5): slot = BroadlinkMP1Slot( - _get_mp1_slot_name(friendly_name, i), broadlink_device, i, parent_device + _get_mp1_slot_name(friendly_name, i), + broadlink_device, + i, + parent_device, + retry_times, ) switches.append(slot) @@ -146,7 +155,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None): class BroadlinkRMSwitch(SwitchDevice, RestoreEntity): """Representation of an Broadlink switch.""" - def __init__(self, name, friendly_name, device, command_on, command_off): + def __init__( + self, name, friendly_name, device, command_on, command_off, retry_times + ): """Initialize the switch.""" self.entity_id = ENTITY_ID_FORMAT.format(slugify(name)) self._name = friendly_name @@ -155,6 +166,8 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity): self._command_off = command_off self._device = device self._is_available = False + self._retry_times = retry_times + _LOGGER.debug("_retry_times : %s", self._retry_times) async def async_added_to_hass(self): """Call when entity about to be added to hass.""" @@ -190,17 +203,17 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity): def turn_on(self, **kwargs): """Turn the device on.""" - if self._sendpacket(self._command_on): + if self._sendpacket(self._command_on, self._retry_times): self._state = True self.schedule_update_ha_state() def turn_off(self, **kwargs): """Turn the device off.""" - if self._sendpacket(self._command_off): + if self._sendpacket(self._command_off, self._retry_times): self._state = False self.schedule_update_ha_state() - def _sendpacket(self, packet, retry=2): + def _sendpacket(self, packet, retry): """Send packet to device.""" if packet is None: _LOGGER.debug("Empty packet") @@ -211,12 +224,13 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity): if retry < 1: _LOGGER.error("Error during sending a packet: %s", error) return False - if not self._auth(): + if not self._auth(self._retry_times): return False return self._sendpacket(packet, retry - 1) return True - def _auth(self, retry=2): + def _auth(self, retry): + _LOGGER.debug("_auth : retry=%s", retry) try: auth = self._device.auth() except OSError: @@ -231,14 +245,14 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity): class BroadlinkSP1Switch(BroadlinkRMSwitch): """Representation of an Broadlink switch.""" - def __init__(self, friendly_name, device): + def __init__(self, friendly_name, device, retry_times): """Initialize the switch.""" - super().__init__(friendly_name, friendly_name, device, None, None) + super().__init__(friendly_name, friendly_name, device, None, None, retry_times) self._command_on = 1 self._command_off = 0 self._load_power = None - def _sendpacket(self, packet, retry=2): + def _sendpacket(self, packet, retry): """Send packet to device.""" try: self._device.set_power(packet) @@ -246,7 +260,7 @@ class BroadlinkSP1Switch(BroadlinkRMSwitch): if retry < 1: _LOGGER.error("Error during sending a packet: %s", error) return False - if not self._auth(): + if not self._auth(self._retry_times): return False return self._sendpacket(packet, retry - 1) return True @@ -275,10 +289,11 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch): def update(self): """Synchronize state with switch.""" - self._update() + self._update(self._retry_times) - def _update(self, retry=2): + def _update(self, retry): """Update the state of the device.""" + _LOGGER.debug("_update : retry=%s", retry) try: state = self._device.check_power() load_power = self._device.get_energy() @@ -287,7 +302,7 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch): _LOGGER.error("Error during updating the state: %s", error) self._is_available = False return - if not self._auth(): + if not self._auth(self._retry_times): return return self._update(retry - 1) if state is None and retry > 0: @@ -300,9 +315,9 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch): class BroadlinkMP1Slot(BroadlinkRMSwitch): """Representation of a slot of Broadlink switch.""" - def __init__(self, friendly_name, device, slot, parent_device): + def __init__(self, friendly_name, device, slot, parent_device, retry_times): """Initialize the slot of switch.""" - super().__init__(friendly_name, friendly_name, device, None, None) + super().__init__(friendly_name, friendly_name, device, None, None, retry_times) self._command_on = 1 self._command_off = 0 self._slot = slot @@ -313,7 +328,7 @@ class BroadlinkMP1Slot(BroadlinkRMSwitch): """Return true if unable to access real state of entity.""" return False - def _sendpacket(self, packet, retry=2): + def _sendpacket(self, packet, retry): """Send packet to device.""" try: self._device.set_power(self._slot, packet) @@ -322,7 +337,7 @@ class BroadlinkMP1Slot(BroadlinkRMSwitch): _LOGGER.error("Error during sending a packet: %s", error) self._is_available = False return False - if not self._auth(): + if not self._auth(self._retry_times): return False return self._sendpacket(packet, max(0, retry - 1)) self._is_available = True @@ -346,10 +361,11 @@ class BroadlinkMP1Slot(BroadlinkRMSwitch): class BroadlinkMP1Switch: """Representation of a Broadlink switch - To fetch states of all slots.""" - def __init__(self, device): + def __init__(self, device, retry_times): """Initialize the switch.""" self._device = device self._states = None + self._retry_times = retry_times def get_outlet_status(self, slot): """Get status of outlet from cached status list.""" @@ -360,9 +376,9 @@ class BroadlinkMP1Switch: @Throttle(TIME_BETWEEN_UPDATES) def update(self): """Fetch new state data for this device.""" - self._update() + self._update(self._retry_times) - def _update(self, retry=2): + def _update(self, retry): """Update the state of the device.""" try: states = self._device.check_power() @@ -370,14 +386,14 @@ class BroadlinkMP1Switch: if retry < 1: _LOGGER.error("Error during updating the state: %s", error) return - if not self._auth(): + if not self._auth(self._retry_times): return return self._update(max(0, retry - 1)) if states is None and retry > 0: return self._update(max(0, retry - 1)) self._states = states - def _auth(self, retry=2): + def _auth(self, retry): """Authenticate the device.""" try: auth = self._device.auth()