-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
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
Add deako integration using pydeako #102190
Conversation
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joostlek I believe I have addressed your comments. Usually I would let the reviewer resolve them, is that the process here? |
If you think you resolved comments, feel free to resolve them |
|
||
async def _async_has_devices(hass: HomeAssistant) -> bool: | ||
"""Return if there are devices that can be discovered.""" | ||
_zc = await zeroconf.async_get_instance(hass) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're using zeroconf, why aren't we setting up the devices with 1 device = 1 config entry? (note, I don't have much experience with zeroconf, but please explain a bit more on how the device works)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah for sure. Good question. We have some devices that can discovered with mdns. We pick one to the be "bridge". It can be any of them that are on wifi at the time. That device is then responsible for bridging tcp to ble as not all deako devices are on wifi at all times. Once a device is selected to be the bridge, it will stay on wifi as the local integration device. All other devices periodically get on wifi to check in, send logs, etc.
Since we only really connect to one device, one config entry. All other devices are then exposed through that device using the local API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if that bridge node breaks down? What will happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pydeako
library handles that. There's a connection watch that if for whatever reason the socket disconnects, another one is spawned, grabbing another address from zeroconf advertisements. All of the connection logic is wrapped in a client which Home Assistant gets an instance of.
In the case that the device that was connected to goes offline (ie power pulled, etc), its mdns entry is removed and so that address wouldn't be picked again, but rather some other address that is active and advertising.
|
||
connection = Deako(discoverer.get_address) | ||
|
||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this to under ConfigEntryNotReady
? This way we only populate the hass.data
when everything succeeds.
# Base component constants | ||
NAME = "Deako" | ||
DOMAIN = "deako" | ||
DOMAIN_DATA = f"{DOMAIN}_data" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused
DOMAIN_DATA = f"{DOMAIN}_data" | ||
|
||
# Data keys | ||
CONNECTION_ID = "connection_id" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused
if len(devices) == 0: | ||
# If deako devices are advertising on mdns, we should be able to get at least one device | ||
_LOGGER.warning("No devices found from local integration") | ||
await client.disconnect() | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't we check for this in the __init__.py
?
|
||
_attr_has_entity_name = True | ||
_attr_name = None | ||
_attr_is_on = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be False? I think the default is None
which is unknown which looks like a more valid state
if mock_devices.get_state(device_uuid).get("dim") is not None: | ||
# test that internal dim of 0-100 gets converted properly | ||
assert ( | ||
state.attributes.get(ATTR_BRIGHTNESS) | ||
== mock_devices.get_state(device_uuid)["convertedDim"] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idem
if mock_devices.get_state(device_uuid).get("dim") is not None: | ||
assert ColorMode.BRIGHTNESS in entity.capabilities.get("supported_color_modes") | ||
assert state.attributes["color_mode"] == ColorMode.BRIGHTNESS | ||
else: | ||
assert ColorMode.ONOFF in entity.capabilities.get("supported_color_modes") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idem
assert ( | ||
device.model == "dimmer" | ||
if mock_devices.get_state(device_uuid).get("dim") is not None | ||
else "smart" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idem
await hass.config_entries.async_setup(mock_config_entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
hass.data[DOMAIN][mock_config_entry.entry_id] = pydeako_deako_mock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't access internals
await hass.config_entries.async_setup(mock_config_entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
hass.data[DOMAIN][mock_config_entry.entry_id] = pydeako_deako_mock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idem
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. |
Planning on coming back to this soon! |
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. |
Proposed change
Add Deako integration to connect to Deako devices locally and interact with them. Uses the
pydeako
library.Type of change
Additional information
Checklist
black --fast homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
..coveragerc
.To help with the load of incoming pull requests: