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
This commit is contained in:
zhumuht 2019-08-16 15:26:11 +08:00 committed by Daniel Høyer Iversen
parent 26c99454a6
commit 90d493a51a

View File

@ -34,7 +34,9 @@ TIME_BETWEEN_UPDATES = timedelta(seconds=5)
DEFAULT_NAME = "Broadlink switch" DEFAULT_NAME = "Broadlink switch"
DEFAULT_TIMEOUT = 10 DEFAULT_TIMEOUT = 10
DEFAULT_RETRY = 2
CONF_SLOTS = "slots" CONF_SLOTS = "slots"
CONF_RETRY = "retry"
RM_TYPES = [ RM_TYPES = [
"rm", "rm",
@ -82,6 +84,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Optional(CONF_FRIENDLY_NAME, default=DEFAULT_NAME): cv.string, 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_TYPE, default=SWITCH_TYPES[0]): vol.In(SWITCH_TYPES),
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int, 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) friendly_name = config.get(CONF_FRIENDLY_NAME)
mac_addr = binascii.unhexlify(config.get(CONF_MAC).encode().replace(b":", b"")) mac_addr = binascii.unhexlify(config.get(CONF_MAC).encode().replace(b":", b""))
switch_type = config.get(CONF_TYPE) switch_type = config.get(CONF_TYPE)
retry_times = config.get(CONF_RETRY)
def _get_mp1_slot_name(switch_friendly_name, slot): def _get_mp1_slot_name(switch_friendly_name, slot):
"""Get slot name.""" """Get slot name."""
@ -116,21 +120,26 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
broadlink_device, broadlink_device,
device_config.get(CONF_COMMAND_ON), device_config.get(CONF_COMMAND_ON),
device_config.get(CONF_COMMAND_OFF), device_config.get(CONF_COMMAND_OFF),
retry_times,
) )
) )
elif switch_type in SP1_TYPES: elif switch_type in SP1_TYPES:
broadlink_device = broadlink.sp1((ip_addr, 80), mac_addr, None) 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: elif switch_type in SP2_TYPES:
broadlink_device = broadlink.sp2((ip_addr, 80), mac_addr, None) 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: elif switch_type in MP1_TYPES:
switches = [] switches = []
broadlink_device = broadlink.mp1((ip_addr, 80), mac_addr, None) 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): for i in range(1, 5):
slot = BroadlinkMP1Slot( 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) switches.append(slot)
@ -146,7 +155,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
class BroadlinkRMSwitch(SwitchDevice, RestoreEntity): class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
"""Representation of an Broadlink switch.""" """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.""" """Initialize the switch."""
self.entity_id = ENTITY_ID_FORMAT.format(slugify(name)) self.entity_id = ENTITY_ID_FORMAT.format(slugify(name))
self._name = friendly_name self._name = friendly_name
@ -155,6 +166,8 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
self._command_off = command_off self._command_off = command_off
self._device = device self._device = device
self._is_available = False self._is_available = False
self._retry_times = retry_times
_LOGGER.debug("_retry_times : %s", self._retry_times)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Call when entity about to be added to hass.""" """Call when entity about to be added to hass."""
@ -190,17 +203,17 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
"""Turn the device on.""" """Turn the device on."""
if self._sendpacket(self._command_on): if self._sendpacket(self._command_on, self._retry_times):
self._state = True self._state = True
self.schedule_update_ha_state() self.schedule_update_ha_state()
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
"""Turn the device off.""" """Turn the device off."""
if self._sendpacket(self._command_off): if self._sendpacket(self._command_off, self._retry_times):
self._state = False self._state = False
self.schedule_update_ha_state() self.schedule_update_ha_state()
def _sendpacket(self, packet, retry=2): def _sendpacket(self, packet, retry):
"""Send packet to device.""" """Send packet to device."""
if packet is None: if packet is None:
_LOGGER.debug("Empty packet") _LOGGER.debug("Empty packet")
@ -211,12 +224,13 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
if retry < 1: if retry < 1:
_LOGGER.error("Error during sending a packet: %s", error) _LOGGER.error("Error during sending a packet: %s", error)
return False return False
if not self._auth(): if not self._auth(self._retry_times):
return False return False
return self._sendpacket(packet, retry - 1) return self._sendpacket(packet, retry - 1)
return True return True
def _auth(self, retry=2): def _auth(self, retry):
_LOGGER.debug("_auth : retry=%s", retry)
try: try:
auth = self._device.auth() auth = self._device.auth()
except OSError: except OSError:
@ -231,14 +245,14 @@ class BroadlinkRMSwitch(SwitchDevice, RestoreEntity):
class BroadlinkSP1Switch(BroadlinkRMSwitch): class BroadlinkSP1Switch(BroadlinkRMSwitch):
"""Representation of an Broadlink switch.""" """Representation of an Broadlink switch."""
def __init__(self, friendly_name, device): def __init__(self, friendly_name, device, retry_times):
"""Initialize the switch.""" """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_on = 1
self._command_off = 0 self._command_off = 0
self._load_power = None self._load_power = None
def _sendpacket(self, packet, retry=2): def _sendpacket(self, packet, retry):
"""Send packet to device.""" """Send packet to device."""
try: try:
self._device.set_power(packet) self._device.set_power(packet)
@ -246,7 +260,7 @@ class BroadlinkSP1Switch(BroadlinkRMSwitch):
if retry < 1: if retry < 1:
_LOGGER.error("Error during sending a packet: %s", error) _LOGGER.error("Error during sending a packet: %s", error)
return False return False
if not self._auth(): if not self._auth(self._retry_times):
return False return False
return self._sendpacket(packet, retry - 1) return self._sendpacket(packet, retry - 1)
return True return True
@ -275,10 +289,11 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch):
def update(self): def update(self):
"""Synchronize state with switch.""" """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.""" """Update the state of the device."""
_LOGGER.debug("_update : retry=%s", retry)
try: try:
state = self._device.check_power() state = self._device.check_power()
load_power = self._device.get_energy() load_power = self._device.get_energy()
@ -287,7 +302,7 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch):
_LOGGER.error("Error during updating the state: %s", error) _LOGGER.error("Error during updating the state: %s", error)
self._is_available = False self._is_available = False
return return
if not self._auth(): if not self._auth(self._retry_times):
return return
return self._update(retry - 1) return self._update(retry - 1)
if state is None and retry > 0: if state is None and retry > 0:
@ -300,9 +315,9 @@ class BroadlinkSP2Switch(BroadlinkSP1Switch):
class BroadlinkMP1Slot(BroadlinkRMSwitch): class BroadlinkMP1Slot(BroadlinkRMSwitch):
"""Representation of a slot of Broadlink switch.""" """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.""" """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_on = 1
self._command_off = 0 self._command_off = 0
self._slot = slot self._slot = slot
@ -313,7 +328,7 @@ class BroadlinkMP1Slot(BroadlinkRMSwitch):
"""Return true if unable to access real state of entity.""" """Return true if unable to access real state of entity."""
return False return False
def _sendpacket(self, packet, retry=2): def _sendpacket(self, packet, retry):
"""Send packet to device.""" """Send packet to device."""
try: try:
self._device.set_power(self._slot, packet) self._device.set_power(self._slot, packet)
@ -322,7 +337,7 @@ class BroadlinkMP1Slot(BroadlinkRMSwitch):
_LOGGER.error("Error during sending a packet: %s", error) _LOGGER.error("Error during sending a packet: %s", error)
self._is_available = False self._is_available = False
return False return False
if not self._auth(): if not self._auth(self._retry_times):
return False return False
return self._sendpacket(packet, max(0, retry - 1)) return self._sendpacket(packet, max(0, retry - 1))
self._is_available = True self._is_available = True
@ -346,10 +361,11 @@ class BroadlinkMP1Slot(BroadlinkRMSwitch):
class BroadlinkMP1Switch: class BroadlinkMP1Switch:
"""Representation of a Broadlink switch - To fetch states of all slots.""" """Representation of a Broadlink switch - To fetch states of all slots."""
def __init__(self, device): def __init__(self, device, retry_times):
"""Initialize the switch.""" """Initialize the switch."""
self._device = device self._device = device
self._states = None self._states = None
self._retry_times = retry_times
def get_outlet_status(self, slot): def get_outlet_status(self, slot):
"""Get status of outlet from cached status list.""" """Get status of outlet from cached status list."""
@ -360,9 +376,9 @@ class BroadlinkMP1Switch:
@Throttle(TIME_BETWEEN_UPDATES) @Throttle(TIME_BETWEEN_UPDATES)
def update(self): def update(self):
"""Fetch new state data for this device.""" """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.""" """Update the state of the device."""
try: try:
states = self._device.check_power() states = self._device.check_power()
@ -370,14 +386,14 @@ class BroadlinkMP1Switch:
if retry < 1: if retry < 1:
_LOGGER.error("Error during updating the state: %s", error) _LOGGER.error("Error during updating the state: %s", error)
return return
if not self._auth(): if not self._auth(self._retry_times):
return return
return self._update(max(0, retry - 1)) return self._update(max(0, retry - 1))
if states is None and retry > 0: if states is None and retry > 0:
return self._update(max(0, retry - 1)) return self._update(max(0, retry - 1))
self._states = states self._states = states
def _auth(self, retry=2): def _auth(self, retry):
"""Authenticate the device.""" """Authenticate the device."""
try: try:
auth = self._device.auth() auth = self._device.auth()