core/homeassistant/components/broadlink/helpers.py

50 lines
1.4 KiB
Python
Raw Normal View History

Implement config flow in the Broadlink integration (#36914) * Implement config flow in the Broadlink integration * General improvements to the Broadlink config flow * Remove unnecessary else after return * Fix translations * Rename device to device_entry * Add tests for the config flow * Improve docstrings * Test we do not accept more than one config entry per device * Improve helpers * Allow empty packets * Allow multiple config files for switches related to the same device * Rename mock_device to mock_api * General improvements * Make new attempts before marking the device as unavailable * Let the name be the template for the entity_id * Handle OSError * Test network unavailable in the configuration flow * Rename lock attribute * Update manifest.json * Import devices from platforms * Test import flow * Add deprecation warnings * General improvements * Rename deprecate to discontinue * Test device setup * Add type attribute to mock api * Test we handle an update failure at startup * Remove BroadlinkDevice from tests * Remove device.py from .coveragerc * Add tests for the config flow * Add tests for the device * Test device registry and update listener * Test MAC address validation * Add tests for the device * Extract domains and types to a helper function * Do not patch integration details * Add tests for the device * Set device classes where appropriate * Set an appropriate connection class * Do not set device class for custom switches * Fix tests and improve code readability * Use RM4 to test authentication errors * Handle BroadlinkException in the authentication
2020-08-20 15:30:41 +00:00
"""Helper functions for the Broadlink integration."""
from base64 import b64decode
from homeassistant import config_entries
from homeassistant.const import CONF_HOST
from homeassistant.helpers import config_validation as cv
Implement config flow in the Broadlink integration (#36914) * Implement config flow in the Broadlink integration * General improvements to the Broadlink config flow * Remove unnecessary else after return * Fix translations * Rename device to device_entry * Add tests for the config flow * Improve docstrings * Test we do not accept more than one config entry per device * Improve helpers * Allow empty packets * Allow multiple config files for switches related to the same device * Rename mock_device to mock_api * General improvements * Make new attempts before marking the device as unavailable * Let the name be the template for the entity_id * Handle OSError * Test network unavailable in the configuration flow * Rename lock attribute * Update manifest.json * Import devices from platforms * Test import flow * Add deprecation warnings * General improvements * Rename deprecate to discontinue * Test device setup * Add type attribute to mock api * Test we handle an update failure at startup * Remove BroadlinkDevice from tests * Remove device.py from .coveragerc * Add tests for the config flow * Add tests for the device * Test device registry and update listener * Test MAC address validation * Add tests for the device * Extract domains and types to a helper function * Do not patch integration details * Add tests for the device * Set device classes where appropriate * Set an appropriate connection class * Do not set device class for custom switches * Fix tests and improve code readability * Use RM4 to test authentication errors * Handle BroadlinkException in the authentication
2020-08-20 15:30:41 +00:00
from .const import DOMAIN
def data_packet(value):
"""Decode a data packet given for a Broadlink remote."""
value = cv.string(value)
extra = len(value) % 4
if extra > 0:
value = value + ("=" * (4 - extra))
return b64decode(value)
def mac_address(mac):
"""Validate and convert a MAC address to bytes."""
mac = cv.string(mac)
if len(mac) == 17:
mac = "".join(mac[i : i + 2] for i in range(0, 17, 3))
elif len(mac) == 14:
mac = "".join(mac[i : i + 4] for i in range(0, 14, 5))
elif len(mac) != 12:
raise ValueError("Invalid MAC address")
return bytes.fromhex(mac)
def format_mac(mac):
"""Format a MAC address."""
return ":".join([format(octet, "02x") for octet in mac])
def import_device(hass, host):
"""Create a config flow for a device."""
configured_hosts = {
entry.data.get(CONF_HOST) for entry in hass.config_entries.async_entries(DOMAIN)
}
if host not in configured_hosts:
task = hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={CONF_HOST: host},
)
hass.async_create_task(task)