Skip to content

Add Facebox teach service#14998

Merged
MartinHjelmare merged 22 commits intohome-assistant:devfrom
robmarkcole:facebox-teach-service
Jul 10, 2018
Merged

Add Facebox teach service#14998
MartinHjelmare merged 22 commits intohome-assistant:devfrom
robmarkcole:facebox-teach-service

Conversation

@robmarkcole
Copy link
Copy Markdown
Contributor

@robmarkcole robmarkcole commented Jun 16, 2018

Description:

This PR adds the service image_processing.facebox_teach_face that can be used to teach Facebox faces, as described in this blog post. Example valid service data is:

{
  "entity_id": "image_processing.facebox_local_file",
  "name": "superman",
  "file_path": "/Users/robincole/.homeassistant/images/superman_1.jpeg"
}

An image_processing.teach_classifier event is fired for each service call, providing feedback on whether teaching has been successful or unsuccessful. In the unsuccessful case, the message field of the event_data will contain info on the cause of failure, and a warning is also published in the HA logs.

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#5553

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox. Your PR cannot be merged unless tests pass

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

@robmarkcole
Copy link
Copy Markdown
Contributor Author

robmarkcole commented Jun 16, 2018

This PR adds functions to both validate that a file_path is valid, and that a file is an image file. Are these methods available already in the HA API?

@robmarkcole
Copy link
Copy Markdown
Contributor Author

OK I removed the text of image type as the API can actually handle a wide range of image types, and will return an error if an invalid type is posted, to that case is handled.

try:
cv.isfile(file_path)
return True
except:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

do not use bare except'

"""
import base64
import logging
import os
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

'os' imported but unused

import pytest
import requests
import requests_mock
from unittest import mock
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

'unittest.mock' imported but unused

@robmarkcole robmarkcole requested a review from fabaff June 18, 2018 06:06
@pvizeli
Copy link
Copy Markdown
Member

pvizeli commented Jun 18, 2018

You need use: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/core.py#L1064
hass.config.is_allowed_path

@robmarkcole
Copy link
Copy Markdown
Contributor Author

ping @pvizeli comment addressed

facebox.teach(name, file_path)
return True

hass.services.register(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This won't work. Only one service is registered per domain and service name key. Move this out of the for loop.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ok

"""Teach a facebox a name."""
name = call.data.get(ATTR_NAME)
file_path = call.data.get(FILE_PATH)
facebox.teach(name, file_path)
Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare Jun 20, 2018

Choose a reason for hiding this comment

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

We should lookup which entity should be used. See other platforms that register services for examples.

Move the service handler out of the for loop.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Something like hass.data[DOMAIN].facebox.teach(name, file_path) I'm guessing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Appears you use SonosData to access all SonosDevice objects, so I gather I will need an equivalent to access my FaceClassifyEntity objects in the service handler?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, you need to store them in hass.data since a platform can be setup multiple times, adding more entities each time.

CLASSIFIER = 'facebox'
EVENT_CLASSIFIER_TEACH = 'image_processing.teach_classifier'
FILE_PATH = 'file_path'
SERVICE_FACEBOX_TEACH_FACE = 'facebox_teach_face'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Simplify constant name to SERVICE_TEACH_FACE. Don't change the string though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ok

@MartinHjelmare
Copy link
Copy Markdown
Member

We can replace the decorators with these fixtures:

@pytest.fixture
def mock_isfile():
    """Mock os.path.isfile."""
    with patch('os.path.isfile', Mock(return_value=True)) as _mock_isfile:
        yield _mock_isfile


@pytest.fixture
def mock_access():
    """Mock os.access."""
    with patch('os.access', Mock(return_value=True)) as _mock_access:
        yield _mock_access

@robmarkcole
Copy link
Copy Markdown
Contributor Author

@MartinHjelmare I don't understand why but test_teach_service fails to setup the component, despite being identical to the other tests which do successfully perform setup, any ideas?

@robmarkcole
Copy link
Copy Markdown
Contributor Author

@MartinHjelmare the line which is causing the setup to fail on the final test is:

async def test_teach_service(hass, mock_image, mock_isfile, mock_access):

If I remove mock_isfile, mock_access then setup is successful, but only when I also move that test before test_setup_platform_with_name. So it appears there are a couple of funny things going on?

@dgomes @OttoWinter

assert state.attributes.get('matched_faces') == {}


async def test_teach_service(hass, mock_image): # mock_isfile, mock_access
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

at least two spaces before inline comment

Removes the fixtures which were causing `setup` to fail, replace with `@patch`
@robmarkcole
Copy link
Copy Markdown
Contributor Author

ping @pvizeli @MartinHjelmare


@patch('os.access', Mock(return_value=True))
@patch('os.path.isfile', Mock(return_value=True))
async def test_teach_service(hass, mock_image):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This test is never awaited. Please run the tests locally, eg with script/lazytox.py. You'll see the warning in the pytest warning summary.

Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

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

I've fixed the test. We were patching the wrong things and didn't patch the call to open file.

@MartinHjelmare
Copy link
Copy Markdown
Member

Can be merged when build passes.

@MartinHjelmare MartinHjelmare changed the title Adds Facebox teach service Add Facebox teach service Jul 9, 2018
@MartinHjelmare
Copy link
Copy Markdown
Member

Merging. Coverage calc is not accurate.

@MartinHjelmare MartinHjelmare merged commit df8c594 into home-assistant:dev Jul 10, 2018
@ghost ghost removed the in progress label Jul 10, 2018
@robmarkcole robmarkcole deleted the facebox-teach-service branch July 10, 2018 04:52
@robmarkcole
Copy link
Copy Markdown
Contributor Author

Many thanks @MartinHjelmare :-)

awarecan pushed a commit to awarecan/home-assistant that referenced this pull request Jul 16, 2018
* Adds service

* Address pylint

* Update facebox.py

* patch tests

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Adds total_matched_faces

* Update test_facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Remove fixtures

Removes the fixtures which were causing `setup` to fail, replace with `@patch`

* Fix teach service test and lint issues
@balloob balloob mentioned this pull request Jul 20, 2018
michaeldavie pushed a commit to michaeldavie/home-assistant that referenced this pull request Jul 31, 2018
* Adds service

* Address pylint

* Update facebox.py

* patch tests

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Adds total_matched_faces

* Update test_facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Remove fixtures

Removes the fixtures which were causing `setup` to fail, replace with `@patch`

* Fix teach service test and lint issues
girlpunk pushed a commit to girlpunk/home-assistant that referenced this pull request Sep 4, 2018
* Adds service

* Address pylint

* Update facebox.py

* patch tests

* Update facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Update facebox.py

* Adds total_matched_faces

* Update test_facebox.py

* Update facebox.py

* Update test_facebox.py

* Update test_facebox.py

* Remove fixtures

Removes the fixtures which were causing `setup` to fail, replace with `@patch`

* Fix teach service test and lint issues
@home-assistant home-assistant locked and limited conversation to collaborators Dec 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants