Skip to content
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 device automation condition #26313

Merged

Conversation

emontnemery
Copy link
Contributor

@emontnemery emontnemery commented Aug 31, 2019

Description:

Add websock command to query device for conditions.

Conditions can be provided by the integration that provided the device or the entity integrations that the device has entities with.

As an example of the latter, this PR also adds turn_on and turn_off conditions to light entities.

This PR is intended as a step towards home-assistant/architecture#178

Pull request with documentation for home-assistant.io (if applicable): home-assistant/home-assistant.io#<home-assistant.io PR number goes here>

Example entry for configuration.yaml (if applicable):

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist

If user exposed functionality or configuration variables are added/changed:

If the code does not interact with devices:

  • Tests have been added to verify that the new code works.

@emontnemery emontnemery requested a review from a team as a code owner August 31, 2019 08:19
@project-bot project-bot bot added this to Needs review in Dev Aug 31, 2019
Dev automation moved this from Needs review to Cancelled Aug 31, 2019
@emontnemery emontnemery reopened this Aug 31, 2019
Dev automation moved this from Cancelled to Needs review Aug 31, 2019
@MartinHjelmare MartinHjelmare moved this from Needs review to Incoming in Dev Aug 31, 2019
check_factory = check_factory.func

if asyncio.iscoroutinefunction(check_factory):
return await cast(Callable[..., bool], factory(hass, config, config_validation))
return cast(Callable[..., bool], factory(config, config_validation))


from_config = _threaded_factory(async_from_config)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now broken because async_from_config is a coroutine function. Is this used anywhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can remove all of those.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, removed.

@@ -134,23 +141,20 @@ def if_and_condition(
and_from_config = _threaded_factory(async_and_from_config)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now broken because async_and_from_config is a coroutine function. Is this used anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

@@ -166,6 +170,17 @@ def if_or_condition(
or_from_config = _threaded_factory(async_or_from_config)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now broken because async_or_from_config is a coroutine function. Is this used anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

homeassistant/helpers/condition.py Show resolved Hide resolved


async def async_get_device_automation_triggers(hass, device_id):
"""List device triggers."""
async def async_get_device_automations(hass, fname, device_id):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function is only used in this file, let's prefix it with _.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

conditions = await async_get_device_automations(
hass, "async_get_conditions", device_id
)
connection.send_result(msg["id"], {"conditions": conditions})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we add this to a dictionary? We should just send the list.

Suggested change
connection.send_result(msg["id"], {"conditions": conditions})
connection.send_result(msg["id"], conditions)

We should do the same for triggers (which I thought we already did)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

vol.Optional(CONF_DEVICE_ID): str,
vol.Required(CONF_DOMAIN): DOMAIN,
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_TYPE): vol.In([CONF_TURN_OFF, CONF_TURN_ON]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels a bit weird, shouldn't this be is_on and is_off ?

I also wonder if we should move some generic constants to device_automation/const.py

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You say fixed but then we should update these constants to be CONF_IS_ON CONF_IS_OFF ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
vol.Required(CONF_TYPE): vol.In([CONF_TURN_OFF, CONF_TURN_ON]),
vol.Required(CONF_TYPE): vol.In([CONF_IS_OFF, CONF_IS_ON]),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, now properly fixed!

@@ -21,7 +21,7 @@ def entity_reg(hass):
return mock_registry(hass)


def _same_triggers(a, b):
def _same_dicts(a, b):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only tests that the keys are the same, not the values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -1,5 +1,9 @@
{
"device_automation": {
"condition_type": {
"turn_on": "{name} turned on",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"turn_on": "{name} turned on",
"turn_on": "{name} is on",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -1,5 +1,9 @@
{
"device_automation": {
"condition_type": {
"turn_on": "{name} turned on",
"turn_off": "{name} turned off"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"turn_off": "{name} turned off"
"turn_off": "{name} is off"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -163,7 +161,18 @@ def if_or_condition(
return if_or_condition


or_from_config = _threaded_factory(async_or_from_config)
async def async_device_from_config(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be part of the condition helper, instead I think it should be part of components/device_automation/__init__.py

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved.

Copy link
Member

@balloob balloob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, only a few minor comments left. Ok to merge after this?

Dev automation moved this from Incoming to Reviewer approved Sep 5, 2019
@emontnemery emontnemery changed the title WIP: Device automation condition Device automation condition Sep 5, 2019
@emontnemery emontnemery changed the title Device automation condition Add device automation condition Sep 5, 2019
@emontnemery
Copy link
Contributor Author

Fixed the remaining comments.

@emontnemery emontnemery merged commit f7dc537 into home-assistant:dev Sep 5, 2019
Dev automation moved this from Reviewer approved to Done Sep 5, 2019
@emontnemery emontnemery deleted the device_automation_condition branch September 6, 2019 10:02
@lock lock bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Dev
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants