Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
cfd69c6
Adds Facebox
robmarkcole Apr 29, 2018
fe17997
Update to ImageProcessingFaceEntity
robmarkcole Apr 29, 2018
ed4d850
Remove confidence
robmarkcole Apr 29, 2018
1937b16
Adds facebox
robmarkcole May 2, 2018
b2ad686
Fix Python 3.6 compatibility for HomeKit controller (#14160)
mjg59 Apr 29, 2018
dd18b4c
deCONZ allow unloading of config entry (#14115)
Kane610 Apr 29, 2018
fadc845
Upgrade netdisco to 1.4.0 (#14152)
fabaff Apr 29, 2018
04a3322
Add precipitation to OpenWeatherMap forecast (#13971)
escoand Apr 29, 2018
5d37c32
Allow transitioning to colour temp for tradfri (#14157)
Hate-Usernames Apr 29, 2018
4d48c99
Add mitemp_bt to coverage
balloob Apr 29, 2018
bb2a4db
Another coverage fix
balloob Apr 29, 2018
93d9d7b
Added update_interval to maxcube (#14143)
dingusdk Apr 29, 2018
713fce6
Revert Hue color state to be xy-based (#14154)
amelchio Apr 29, 2018
f2e8954
zha: Support remotes/buttons (#12528)
rcloran Apr 30, 2018
5b36d29
Upgrade numpy to 1.14.3 (#14187)
fabaff Apr 30, 2018
d323257
Improve chromecast disconnection logic (#14190)
OttoWinter Apr 30, 2018
bf8d205
Added CONF_IP_ADDRESS to HomeKit (#14163)
cdce8p Apr 30, 2018
37e8b7d
Do not sync entities with an empty name (#14181)
balloob Apr 30, 2018
f26ff86
Fix poorly formatted automations (#14196)
balloob Apr 30, 2018
a42269d
Updating darksky default update interval to 5 mins (#14195)
msubra Apr 30, 2018
43058e5
Fix TypeError on round(self.humidity) (fixes #13116) (#14174)
mvn23 Apr 30, 2018
c04a087
Add room hint support to Google Assistant cloud (#14180)
balloob Apr 30, 2018
ae5b9be
Update CODEOWNERS (#14214)
pschmitt May 1, 2018
e035ffa
Fixes #14169 (Upgrade pyupnp-async to 0.1.0.2) (#14210)
dgomes May 1, 2018
3ba805a
zha: Clean up binary_sensor listener registration/state updates (#14197)
rcloran May 1, 2018
3aae289
HomematicIP cloud: Add logic to check accesspoint connection state (#…
sander76 May 1, 2018
4b8f2d5
Foundation for users (#13968)
balloob May 1, 2018
5d780b1
Allow easy extension of websocket API (#14186)
balloob May 1, 2018
5d48d6b
Change the divisor for total consumption output (#14215)
CM000n May 1, 2018
95bc039
Upgrade mypy to 0.590 (#14207)
fabaff May 1, 2018
e615efa
Template Sensor add device_class support (#14034)
OttoWinter May 1, 2018
10873be
Add more parameters for DSMR sensor (#13967)
rubenvandeven May 1, 2018
03a9ac7
Support setting explicit mute value for Panasonic Viera TV (#13954)
blackwind May 1, 2018
150719d
Allow to set a desired update interval for camera_proxy_stream view (…
NovapaX May 1, 2018
5412505
panasonic_viera: Provide unique_id from SSDP UDN, if available (#13541)
scop May 1, 2018
e69e930
Custom component loading cleanup (#14211)
balloob May 1, 2018
577cc88
Buienradar improvements: continuous sensors and unique ID's (#13249)
corneyl May 1, 2018
f59da19
add volumio discovery (#14220)
escoand May 1, 2018
6b8216a
Converts RainMachine to hub model (part 2) (#14225)
bachya May 1, 2018
584714a
Add MQTT Sensor device_class (#14033)
OttoWinter May 1, 2018
7657a37
Allow independent control of white level on flux_led component (#13985)
oblogic7 May 1, 2018
205fcfa
Add Social Blade Sensor (#14060)
meauxt May 1, 2018
4a19476
UPnP code cleanup (#14235)
dgomes May 2, 2018
f9ba730
Improve config schema of the blackbird component (#14007)
syssi May 2, 2018
8d42074
Fix Hue color state for missing xy (#14230)
amelchio May 2, 2018
05b0719
Add support for tracking devices on Netgear access points (#13331)
MatMaul May 2, 2018
f6b44f2
WUnderground unique ids (#13311)
OttoWinter May 2, 2018
3ae85c6
Add PostNL sensor (Dutch Postal Services) (#12366)
iMicknl May 2, 2018
dd1548a
python_openzwave update config service (#12060)
perosb May 2, 2018
aa6dba3
Add unique_id to zwave node entity (#14201)
andrey-git May 2, 2018
9adbf71
Add prereqs for HomeKit Controller (#14172)
marthoc May 2, 2018
c33511c
Restores switch state, case the switch is optimistic (#14151)
dgomes May 2, 2018
4927309
Issue/add template fans (#12027)
giangvo May 2, 2018
3fec8d5
Make facebox_face_detect
robmarkcole May 3, 2018
87db0e7
Merge remote-tracking branch 'home-assistant/dev' into facebox
robmarkcole May 3, 2018
a69a4c5
Put name in correct place
robmarkcole May 3, 2018
ff5d76d
Merge remote-tracking branch 'home-assistant/dev' into facebox
robmarkcole May 4, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions homeassistant/components/image_processing/facebox_face_detect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""
Component that will perform facial detection via a local facebox instance.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/image_processing.facebox_face_detect
"""
import base64
import requests
import logging
import time
import voluptuous as vol

from homeassistant.core import split_entity_id
import homeassistant.helpers.config_validation as cv
from homeassistant.components.image_processing import (
PLATFORM_SCHEMA, CONF_SOURCE, CONF_ENTITY_ID,
CONF_NAME)
from homeassistant.const import (CONF_IP_ADDRESS, CONF_PORT)
from homeassistant.components.image_processing.microsoft_face_identify import (
ImageProcessingFaceEntity)

_LOGGER = logging.getLogger(__name__)

ROUNDING_DECIMALS = 2

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_IP_ADDRESS): cv.string,
vol.Required(CONF_PORT): cv.string,
})


def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the classifier."""
entities = []
for camera in config[CONF_SOURCE]:
entities.append(FaceboxFaceDetectEntity(
config[CONF_IP_ADDRESS],
config[CONF_PORT],
camera[CONF_ENTITY_ID],
camera.get(CONF_NAME)
))
add_devices(entities)


class FaceboxFaceDetectEntity(ImageProcessingFaceEntity):
"""Perform a classification via a Facebox."""

def __init__(self, ip, port, camera_entity, name=None):
"""Init with the API key and model id"""
super().__init__()
self._url = "http://{}:{}/facebox/check".format(ip, port)
self._camera = camera_entity
if name:
self._name = name
else:
self._name = "Facebox {0}".format(
split_entity_id(camera_entity)[1])
self._response_time = None
self.total_faces = 0
self.faces = []

def process_image(self, image):
"""Process an image."""
timer_start = time.perf_counter()
response = {}
try:
response = requests.post(
self._url,
json=self.encode_image(image),
timeout=30
).json()
except requests.exceptions.ConnectionError:
_LOGGER.error("ConnectionError: Is Facebox running?")
response['success'] = False

if response['success']:
elapsed_time = time.perf_counter() - timer_start
self._response_time = "{} seconds".format(
str(round(elapsed_time, 1)))
self.total_faces = response['facesCount']
self.faces = response['faces']

else:
self.total_faces = "Request_failed"
self.faces = []

def encode_image(self, image):
"""base64 encode an image stream."""
base64_img = base64.b64encode(image).decode('ascii')
return {"base64": base64_img}

@property
def camera_entity(self):
"""Return camera entity id from process pictures."""
return self._camera

@property
def name(self):
"""Return the name of the sensor."""
return self._name

@property
def device_state_attributes(self):
"""Return the other state attributes."""
return {
'response_time': self._response_time,
}
68 changes: 68 additions & 0 deletions tests/components/image_processing/test_facebox_face_detect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""The tests for the facebox component."""
import requests_mock

from homeassistant.const import (CONF_IP_ADDRESS, CONF_PORT)
from homeassistant.setup import setup_component
import homeassistant.components.image_processing as ip

from tests.common import (
get_test_home_assistant, assert_setup_component)

MOCK_IP = '192.168.0.1'
MOCK_PORT = '8080'

MOCK_RESPONSE = """
{"facesCount": 1,
"success": True,
"faces":['face_data']}
"""

VALID_ENTITY_ID = 'image_processing.facebox_demo_camera'
VALID_CONFIG = {
ip.DOMAIN: {
'platform': 'facebox_face_detect',
CONF_IP_ADDRESS: MOCK_IP,
CONF_PORT: MOCK_PORT,
ip.CONF_SOURCE: {
ip.CONF_ENTITY_ID: 'camera.demo_camera'}
},
'camera': {
'platform': 'demo'
}
}


class TestFaceboxSetup(object):
"""Test class for image processing."""

def setup_method(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()

def test_setup_platform(self):
"""Setup platform with one entity."""

with assert_setup_component(1, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, VALID_CONFIG)

assert self.hass.states.get(VALID_ENTITY_ID)

def test_process_image(self):
"""Test processing of an image."""

with assert_setup_component(1, ip.DOMAIN):
setup_component(self.hass, ip.DOMAIN, VALID_CONFIG)
assert self.hass.states.get(VALID_ENTITY_ID)

with requests_mock.Mocker() as mock_req:
url = "http://{}:{}/facebox/check".format(MOCK_IP, MOCK_PORT)
mock_req.get(url, text=MOCK_RESPONSE)
ip.scan(self.hass, entity_id=VALID_ENTITY_ID)
self.hass.block_till_done()

state = self.hass.states.get(VALID_ENTITY_ID)
assert state.state == '1'

def teardown_method(self):
"""Stop everything that was started."""
self.hass.stop()