hass-core/homeassistant/components/image_processing/openalpr_cloud.py

153 lines
4.1 KiB
Python
Raw Normal View History

"""
Component that will help set the openalpr cloud for alpr processing.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/image_processing.openalpr_cloud/
"""
import asyncio
from base64 import b64encode
import logging
import aiohttp
import async_timeout
import voluptuous as vol
from homeassistant.core import split_entity_id
from homeassistant.const import CONF_API_KEY
from homeassistant.components.image_processing import (
PLATFORM_SCHEMA, CONF_CONFIDENCE, CONF_SOURCE, CONF_ENTITY_ID, CONF_NAME)
from homeassistant.components.image_processing.openalpr_local import (
ImageProcessingAlprEntity)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
OPENALPR_API_URL = "https://api.openalpr.com/v1/recognize"
OPENALPR_REGIONS = [
'au',
'auwide',
'br',
'eu',
'fr',
'gb',
'kr',
'kr2',
'mx',
'sg',
'us',
'vn2'
]
CONF_REGION = 'region'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_REGION):
vol.All(vol.Lower, vol.In(OPENALPR_REGIONS)),
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up the openalpr cloud api platform."""
confidence = config[CONF_CONFIDENCE]
params = {
'secret_key': config[CONF_API_KEY],
'tasks': "plate",
'return_image': 0,
'country': config[CONF_REGION],
}
entities = []
for camera in config[CONF_SOURCE]:
entities.append(OpenAlprCloudEntity(
camera[CONF_ENTITY_ID], params, confidence, camera.get(CONF_NAME)
))
async_add_devices(entities)
class OpenAlprCloudEntity(ImageProcessingAlprEntity):
"""OpenAlpr cloud entity."""
def __init__(self, camera_entity, params, confidence, name=None):
"""Initialize openalpr local api."""
super().__init__()
self._params = params
self._camera = camera_entity
self._confidence = confidence
if name:
self._name = name
else:
self._name = "OpenAlpr {0}".format(
split_entity_id(camera_entity)[1])
@property
def confidence(self):
"""Return minimum confidence for send events."""
return self._confidence
@property
def camera_entity(self):
"""Return camera entity id from process pictures."""
return self._camera
@property
def name(self):
"""Return the name of the entity."""
return self._name
@asyncio.coroutine
def async_process_image(self, image):
"""Process image.
This method is a coroutine.
"""
websession = async_get_clientsession(self.hass)
params = self._params.copy()
params['image_bytes'] = str(b64encode(image), 'utf-8')
data = None
request = None
try:
with async_timeout.timeout(self.timeout, loop=self.hass.loop):
request = yield from websession.post(
OPENALPR_API_URL, params=params
)
data = yield from request.json()
if request.status != 200:
_LOGGER.error("Error %d -> %s.",
request.status, data.get('error'))
return
except (asyncio.TimeoutError, aiohttp.errors.ClientError):
_LOGGER.error("Timeout for openalpr api.")
return
finally:
if request is not None:
yield from request.release()
# processing api data
vehicles = 0
result = {}
for row in data['plate']['results']:
vehicles += 1
for p_data in row['candidates']:
try:
result.update(
{p_data['plate']: float(p_data['confidence'])})
except ValueError:
continue
self.async_process_plates(result, vehicles)