-
-
Notifications
You must be signed in to change notification settings - Fork 37.5k
Enhance Dynalite Integration after review #31760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
990f7c7
fixes per Martin Hjelmare
ziv1234 c60b5b3
pylint fix
ziv1234 9018a3b
final fixes per request
ziv1234 e74acf9
fixed unit tests for new config flow
ziv1234 084da2f
Added unit-tests to increase coverage. at 97% now
ziv1234 4d7c1c0
Added unit tests for 100% coverage of component
ziv1234 7f3e015
removed configured_host function and updated config_flow unit tests
ziv1234 bb58c48
added a pylint directive since it tells me by mistake DOMAIN is not used
ziv1234 7dac86b
fixed path (removed __init__)
ziv1234 9032162
Update homeassistant/components/dynalite/light.py
ziv1234 ddb16a0
Update homeassistant/components/dynalite/light.py
ziv1234 6a0606b
fixed the test as we moved from schedule_update_... to async_schedule
ziv1234 dc683ac
Update homeassistant/components/dynalite/bridge.py
ziv1234 21fb245
removed context from config_flow
ziv1234 bd33b26
Merge branch 'dev' of https://github.com/ziv1234/home-assistant into dev
ziv1234 ed99d82
moved test_light to also use the core interfaces
ziv1234 0081599
moved to config_entries.async_unload
ziv1234 a768ed1
additional fixes for the tests
ziv1234 86f8dd2
pylint fix and removed unnecessary code
ziv1234 29b6e29
Update tests/components/dynalite/test_light.py
ziv1234 fda4222
Update tests/components/dynalite/test_light.py
ziv1234 a55cb03
Update tests/components/dynalite/test_light.py
ziv1234 411c9af
Update tests/components/dynalite/test_light.py
ziv1234 206e78b
Update tests/components/dynalite/test_light.py
ziv1234 871f165
Update tests/components/dynalite/test_light.py
ziv1234 29a7569
Update tests/components/dynalite/test_light.py
ziv1234 1756010
Update tests/components/dynalite/test_light.py
ziv1234 189693b
Update tests/components/dynalite/test_light.py
ziv1234 4c96671
added break in loop
ziv1234 c2d4a37
removed last mock_coro reference
ziv1234 9535d03
added coverage for try_connect
ziv1234 2df398c
added check for a successful connection before bridge.async_setup suc…
ziv1234 73bb948
changed log level
ziv1234 5c27a8f
fixed accidental chmod I did
ziv1234 a203c3d
fixed accidental change
ziv1234 935371f
not storing config in bridge
ziv1234 5daa573
not patching asyncio
ziv1234 f98f232
moved CONFIG_SCHEMA into component
ziv1234 f045564
moved all logs to start capitalized (and revised some of them)
ziv1234 745f893
moved test_config_flow to not patch the DynaliteBridge
ziv1234 89b9f88
also took DynaliteBridge patching out of test_init
ziv1234 559ff1a
removed NO_WAIT
ziv1234 98f2c8e
fixes to SCHEMA
ziv1234 34af622
changed _ in multi-word CONF
ziv1234 4e508b1
removed tries
ziv1234 9d1f58b
removed redundant tests
ziv1234 6dd05a0
fixed some small change i broke in the library. only version update
ziv1234 8a08131
fixed rewuirements
ziv1234 b2c239c
Update tests/components/dynalite/test_config_flow.py
ziv1234 8e7667f
Update tests/components/dynalite/test_light.py
ziv1234 9c74232
Update tests/components/dynalite/test_config_flow.py
ziv1234 4223584
removed HIDDEN_ENTITY
ziv1234 1243e22
Merge branch 'dev' of https://github.com/ziv1234/home-assistant into dev
ziv1234 1abef5f
black fixes
ziv1234 a33185d
removed final piece of hidden_entity from light
ziv1234 4db8c59
removed DATA_CONFIGS - no longer necessary
ziv1234 6bcb2f3
pylint fixes
ziv1234 3d3e318
added coverage
ziv1234 5af5bc5
use abort in config_flow
ziv1234 9d35e5f
test update
ziv1234 4868e96
removed logs
ziv1234 ba6cd6b
test that update actually updates the entry
ziv1234 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,118 +1,82 @@ | ||
| """Code to handle a Dynalite bridge.""" | ||
|
|
||
| import asyncio | ||
|
|
||
| from dynalite_devices_lib import DynaliteDevices | ||
| from dynalite_lib import CONF_ALL | ||
|
|
||
| from homeassistant.const import CONF_HOST | ||
| from homeassistant.core import callback | ||
| from homeassistant.helpers.dispatcher import async_dispatcher_send | ||
|
|
||
| from .const import DATA_CONFIGS, DOMAIN, LOGGER | ||
| from .light import DynaliteLight | ||
|
|
||
|
|
||
| class BridgeError(Exception): | ||
| """Class to throw exceptions from DynaliteBridge.""" | ||
| from .const import CONF_ALL, CONF_HOST, LOGGER | ||
|
|
||
| def __init__(self, message): | ||
| """Initialize the exception.""" | ||
| super().__init__() | ||
| self.message = message | ||
| CONNECT_TIMEOUT = 30 | ||
| CONNECT_INTERVAL = 1 | ||
|
|
||
|
|
||
| class DynaliteBridge: | ||
| """Manages a single Dynalite bridge.""" | ||
|
|
||
| def __init__(self, hass, config_entry): | ||
| def __init__(self, hass, config): | ||
| """Initialize the system based on host parameter.""" | ||
| self.config_entry = config_entry | ||
| self.hass = hass | ||
| self.area = {} | ||
| self.async_add_entities = None | ||
| self.waiting_entities = [] | ||
| self.all_entities = {} | ||
| self.config = None | ||
| self.host = config_entry.data[CONF_HOST] | ||
| if self.host not in hass.data[DOMAIN][DATA_CONFIGS]: | ||
| LOGGER.info("invalid host - %s", self.host) | ||
| raise BridgeError(f"invalid host - {self.host}") | ||
| self.config = hass.data[DOMAIN][DATA_CONFIGS][self.host] | ||
| self.async_add_devices = None | ||
| self.waiting_devices = [] | ||
| self.host = config[CONF_HOST] | ||
| # Configure the dynalite devices | ||
| self.dynalite_devices = DynaliteDevices( | ||
| config=self.config, | ||
| newDeviceFunc=self.add_devices, | ||
| config=config, | ||
| newDeviceFunc=self.add_devices_when_registered, | ||
| updateDeviceFunc=self.update_device, | ||
| ) | ||
|
|
||
| async def async_setup(self, tries=0): | ||
| async def async_setup(self): | ||
| """Set up a Dynalite bridge.""" | ||
| # Configure the dynalite devices | ||
| await self.dynalite_devices.async_setup() | ||
|
|
||
| self.hass.async_create_task( | ||
| self.hass.config_entries.async_forward_entry_setup( | ||
| self.config_entry, "light" | ||
| ) | ||
| ) | ||
|
|
||
| return True | ||
|
|
||
| @callback | ||
| def add_devices(self, devices): | ||
| """Call when devices should be added to home assistant.""" | ||
| added_entities = [] | ||
| return await self.dynalite_devices.async_setup() | ||
|
|
||
| for device in devices: | ||
| if device.category == "light": | ||
| entity = DynaliteLight(device, self) | ||
| else: | ||
| LOGGER.debug("Illegal device category %s", device.category) | ||
| continue | ||
| added_entities.append(entity) | ||
| self.all_entities[entity.unique_id] = entity | ||
|
|
||
| if added_entities: | ||
| self.add_entities_when_registered(added_entities) | ||
| def update_signal(self, device=None): | ||
| """Create signal to use to trigger entity update.""" | ||
| if device: | ||
| signal = f"dynalite-update-{self.host}-{device.unique_id}" | ||
| else: | ||
| signal = f"dynalite-update-{self.host}" | ||
| return signal | ||
|
|
||
| @callback | ||
| def update_device(self, device): | ||
| """Call when a device or all devices should be updated.""" | ||
| if device == CONF_ALL: | ||
| # This is used to signal connection or disconnection, so all devices may become available or not. | ||
| if self.dynalite_devices.available: | ||
| LOGGER.info("Connected to dynalite host") | ||
| else: | ||
| LOGGER.info("Disconnected from dynalite host") | ||
| for uid in self.all_entities: | ||
| self.all_entities[uid].try_schedule_ha() | ||
| log_string = ( | ||
| "Connected" if self.dynalite_devices.available else "Disconnected" | ||
| ) | ||
| LOGGER.info("%s to dynalite host", log_string) | ||
| async_dispatcher_send(self.hass, self.update_signal()) | ||
| else: | ||
| uid = device.unique_id | ||
| if uid in self.all_entities: | ||
| self.all_entities[uid].try_schedule_ha() | ||
| async_dispatcher_send(self.hass, self.update_signal(device)) | ||
|
|
||
| async def try_connection(self): | ||
| """Try to connect to dynalite with timeout.""" | ||
| # Currently by polling. Future - will need to change the library to be proactive | ||
| for _ in range(0, CONNECT_TIMEOUT): | ||
| if self.dynalite_devices.available: | ||
| return True | ||
| await asyncio.sleep(CONNECT_INTERVAL) | ||
| return False | ||
|
|
||
| @callback | ||
| def register_add_entities(self, async_add_entities): | ||
| def register_add_devices(self, async_add_devices): | ||
| """Add an async_add_entities for a category.""" | ||
| self.async_add_entities = async_add_entities | ||
| if self.waiting_entities: | ||
| self.async_add_entities(self.waiting_entities) | ||
| self.async_add_devices = async_add_devices | ||
| if self.waiting_devices: | ||
| self.async_add_devices(self.waiting_devices) | ||
|
|
||
| def add_entities_when_registered(self, entities): | ||
| """Add the entities to HA if async_add_entities was registered, otherwise queue until it is.""" | ||
| if not entities: | ||
| def add_devices_when_registered(self, devices): | ||
| """Add the devices to HA if the add devices callback was registered, otherwise queue until it is.""" | ||
| if not devices: | ||
| return | ||
| if self.async_add_entities: | ||
| self.async_add_entities(entities) | ||
| if self.async_add_devices: | ||
| self.async_add_devices(devices) | ||
| else: # handle it later when it is registered | ||
| self.waiting_entities.extend(entities) | ||
|
|
||
| async def async_reset(self): | ||
| """Reset this bridge to default state. | ||
|
|
||
| Will cancel any scheduled setup retry and will unload | ||
| the config entry. | ||
| """ | ||
| result = await self.hass.config_entries.async_forward_entry_unload( | ||
| self.config_entry, "light" | ||
| ) | ||
| # None and True are OK | ||
| return result | ||
| self.waiting_devices.extend(devices) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.