147 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
"""
 | 
						|
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')
 | 
						|
 | 
						|
        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.ClientError):
 | 
						|
            _LOGGER.error("Timeout for openalpr api.")
 | 
						|
            return
 | 
						|
 | 
						|
        # 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)
 |