diff --git a/.coveragerc b/.coveragerc index 2f1bcf735613bf85d2b4ee6c985517ddded488c5..cd15ecb052b987beef8a0af8f8abf2abe72b2610 100644 --- a/.coveragerc +++ b/.coveragerc @@ -95,15 +95,16 @@ omit = homeassistant/components/knx.py homeassistant/components/*/knx.py + homeassistant/components/ffmpeg.py + homeassistant/components/*/ffmpeg.py + homeassistant/components/alarm_control_panel/alarmdotcom.py homeassistant/components/alarm_control_panel/nx584.py homeassistant/components/alarm_control_panel/simplisafe.py homeassistant/components/binary_sensor/arest.py - homeassistant/components/binary_sensor/ffmpeg.py homeassistant/components/binary_sensor/rest.py homeassistant/components/browser.py homeassistant/components/camera/bloomsky.py - homeassistant/components/camera/ffmpeg.py homeassistant/components/camera/foscam.py homeassistant/components/camera/mjpeg.py homeassistant/components/camera/rpi_camera.py diff --git a/homeassistant/components/binary_sensor/ffmpeg.py b/homeassistant/components/binary_sensor/ffmpeg.py index cedb978cc6830cf771700f18056917df169bf2fa..ce89ae2e4db74b42ea0c5b60d7a6fa7b3c23595d 100644 --- a/homeassistant/components/binary_sensor/ffmpeg.py +++ b/homeassistant/components/binary_sensor/ffmpeg.py @@ -10,13 +10,17 @@ from os import path import voluptuous as vol import homeassistant.helpers.config_validation as cv -from homeassistant.components.binary_sensor import (BinarySensorDevice, - PLATFORM_SCHEMA, DOMAIN) +from homeassistant.components.binary_sensor import ( + BinarySensorDevice, PLATFORM_SCHEMA, DOMAIN) +from homeassistant.components.ffmpeg import ( + get_binary, run_test, CONF_INPUT, CONF_OUTPUT, CONF_EXTRA_ARGUMENTS) from homeassistant.config import load_yaml_config_file from homeassistant.const import (EVENT_HOMEASSISTANT_STOP, CONF_NAME, ATTR_ENTITY_ID) -REQUIREMENTS = ["ha-ffmpeg==0.12"] +DEPENDENCIES = ['ffmpeg'] + +_LOGGER = logging.getLogger(__name__) SERVICE_RESTART = 'ffmpeg_restart' @@ -29,26 +33,19 @@ MAP_FFMPEG_BIN = [ ] CONF_TOOL = 'tool' -CONF_INPUT = 'input' -CONF_FFMPEG_BIN = 'ffmpeg_bin' -CONF_EXTRA_ARGUMENTS = 'extra_arguments' -CONF_OUTPUT = 'output' CONF_PEAK = 'peak' CONF_DURATION = 'duration' CONF_RESET = 'reset' CONF_CHANGES = 'changes' CONF_REPEAT = 'repeat' CONF_REPEAT_TIME = 'repeat_time' -CONF_RUN_TEST = 'run_test' -DEFAULT_RUN_TEST = True +DEFAULT_NAME = 'FFmpeg' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_TOOL): vol.In(MAP_FFMPEG_BIN), vol.Required(CONF_INPUT): cv.string, - vol.Optional(CONF_FFMPEG_BIN, default="ffmpeg"): cv.string, - vol.Optional(CONF_NAME, default="FFmpeg"): cv.string, - vol.Optional(CONF_RUN_TEST, default=DEFAULT_RUN_TEST): cv.boolean, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_EXTRA_ARGUMENTS): cv.string, vol.Optional(CONF_OUTPUT): cv.string, vol.Optional(CONF_PEAK, default=-30): vol.Coerce(int), @@ -69,22 +66,23 @@ SERVICE_RESTART_SCHEMA = vol.Schema({ }) +def restart(hass, entity_id=None): + """Restart a ffmpeg process on entity.""" + data = {ATTR_ENTITY_ID: entity_id} if entity_id else {} + hass.services.call(DOMAIN, SERVICE_RESTART, data) + + # list of all ffmpeg sensors DEVICES = [] -_LOGGER = logging.getLogger(__name__) - def setup_platform(hass, config, add_entities, discovery_info=None): """Create the binary sensor.""" - from haffmpeg import Test, SensorNoise, SensorMotion + from haffmpeg import SensorNoise, SensorMotion # check source - if config.get(CONF_RUN_TEST): - test = Test(config.get(CONF_FFMPEG_BIN)) - if not test.run_test(config.get(CONF_INPUT)): - _LOGGER.error("FFmpeg '%s' test fails!", config.get(CONF_INPUT)) - return + if not run_test(config.get(CONF_INPUT)): + return # generate sensor object if config.get(CONF_TOOL) == FFMPEG_SENSOR_NOISE: @@ -117,7 +115,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): _devices = DEVICES for device in _devices: - device.reset_ffmpeg() + device.restart_ffmpeg() hass.services.register(DOMAIN, SERVICE_RESTART, _service_handle_restart, @@ -133,7 +131,7 @@ class FFmpegBinarySensor(BinarySensorDevice): self._state = False self._config = config self._name = config.get(CONF_NAME) - self._ffmpeg = ffobj(config.get(CONF_FFMPEG_BIN), self._callback) + self._ffmpeg = ffobj(get_binary(), self._callback) self._start_ffmpeg(config) @@ -150,7 +148,7 @@ class FFmpegBinarySensor(BinarySensorDevice): """For STOP event to shutdown ffmpeg.""" self._ffmpeg.close() - def reset_ffmpeg(self): + def restart_ffmpeg(self): """Restart ffmpeg with new config.""" self._ffmpeg.close() self._start_ffmpeg(self._config) diff --git a/homeassistant/components/camera/ffmpeg.py b/homeassistant/components/camera/ffmpeg.py index a0cbe1ca4362a9ed756eb1e9938518115698f41b..1115bc2d2c166af635408feb99aae4e30544d6a5 100644 --- a/homeassistant/components/camera/ffmpeg.py +++ b/homeassistant/components/camera/ffmpeg.py @@ -9,42 +9,28 @@ import logging import voluptuous as vol from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA) +from homeassistant.components.ffmpeg import ( + run_test, get_binary, CONF_INPUT, CONF_EXTRA_ARGUMENTS) import homeassistant.helpers.config_validation as cv from homeassistant.const import CONF_NAME -REQUIREMENTS = ['ha-ffmpeg==0.12'] +DEPENDENCIES = ['ffmpeg'] _LOGGER = logging.getLogger(__name__) -CONF_INPUT = 'input' -CONF_FFMPEG_BIN = 'ffmpeg_bin' -CONF_EXTRA_ARGUMENTS = 'extra_arguments' -CONF_RUN_TEST = 'run_test' - -DEFAULT_BINARY = 'ffmpeg' DEFAULT_NAME = 'FFmpeg' -DEFAULT_RUN_TEST = True PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_INPUT): cv.string, vol.Optional(CONF_EXTRA_ARGUMENTS): cv.string, - vol.Optional(CONF_FFMPEG_BIN, default=DEFAULT_BINARY): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_RUN_TEST, default=DEFAULT_RUN_TEST): cv.boolean, }) def setup_platform(hass, config, add_devices, discovery_info=None): """Setup a FFmpeg Camera.""" - from haffmpeg import Test - - # run Test - if config.get(CONF_RUN_TEST): - test = Test(config.get(CONF_FFMPEG_BIN)) - if not test.run_test(config.get(CONF_INPUT)): - _LOGGER.error("FFmpeg '%s' test fails!", config.get(CONF_INPUT)) - return - + if not run_test(config.get(CONF_INPUT)): + return add_devices([FFmpegCamera(config)]) @@ -57,12 +43,11 @@ class FFmpegCamera(Camera): self._name = config.get(CONF_NAME) self._input = config.get(CONF_INPUT) self._extra_arguments = config.get(CONF_EXTRA_ARGUMENTS) - self._ffmpeg_bin = config.get(CONF_FFMPEG_BIN) def camera_image(self): """Return a still image response from the camera.""" from haffmpeg import ImageSingle, IMAGE_JPEG - ffmpeg = ImageSingle(self._ffmpeg_bin) + ffmpeg = ImageSingle(get_binary()) return ffmpeg.get_image(self._input, output_format=IMAGE_JPEG, extra_cmd=self._extra_arguments) @@ -71,7 +56,7 @@ class FFmpegCamera(Camera): """Generate an HTTP MJPEG stream from the camera.""" from haffmpeg import CameraMjpeg - stream = CameraMjpeg(self._ffmpeg_bin) + stream = CameraMjpeg(get_binary()) stream.open_camera(self._input, extra_cmd=self._extra_arguments) return response( stream, diff --git a/homeassistant/components/ffmpeg.py b/homeassistant/components/ffmpeg.py new file mode 100644 index 0000000000000000000000000000000000000000..03bf1db885fe787d8ee52457e4fb950349945c5f --- /dev/null +++ b/homeassistant/components/ffmpeg.py @@ -0,0 +1,68 @@ +""" +Component that will help set the ffmpeg component. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/ffmpeg/ +""" +import logging + +import voluptuous as vol + +import homeassistant.helpers.config_validation as cv + +DOMAIN = 'ffmpeg' +REQUIREMENTS = ["ha-ffmpeg==0.12"] + +_LOGGER = logging.getLogger(__name__) + +CONF_INPUT = 'input' +CONF_FFMPEG_BIN = 'ffmpeg_bin' +CONF_EXTRA_ARGUMENTS = 'extra_arguments' +CONF_OUTPUT = 'output' +CONF_RUN_TEST = 'run_test' + +DEFAULT_BINARY = 'ffmpeg' +DEFAULT_RUN_TEST = True + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Optional(CONF_FFMPEG_BIN, default=DEFAULT_BINARY): cv.string, + vol.Optional(CONF_RUN_TEST, default=DEFAULT_RUN_TEST): cv.boolean, + }), +}, extra=vol.ALLOW_EXTRA) + + +FFMPEG_CONFIG = {} +FFMPEG_TEST_CACHE = {} + + +def setup(hass, config): + """Setup the FFmpeg component.""" + global FFMPEG_CONFIG + + FFMPEG_CONFIG = config.get(DOMAIN) + return True + + +def get_binary(): + """Return ffmpeg binary from config.""" + return FFMPEG_CONFIG.get(CONF_FFMPEG_BIN) + + +def run_test(input_source): + """Run test on this input. TRUE is deactivate or run correct.""" + from haffmpeg import Test + + if FFMPEG_CONFIG.get(CONF_RUN_TEST): + # if in cache + if input_source in FFMPEG_TEST_CACHE: + return FFMPEG_TEST_CACHE[input_source] + + # run test + test = Test(get_binary()) + if not test.run_test(input_source): + _LOGGER.error("FFmpeg '%s' test fails!", input_source) + FFMPEG_TEST_CACHE[input_source] = False + return False + FFMPEG_TEST_CACHE[input_source] = True + return True diff --git a/requirements_all.txt b/requirements_all.txt index 1ecf40624630a96fe20d2eeb927db2f868fc1f59..bfbeaae0296bd6c35eb02c21f5269f011c319e94 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -114,8 +114,7 @@ googlemaps==2.4.4 # homeassistant.components.sensor.gpsd gps3==0.33.3 -# homeassistant.components.binary_sensor.ffmpeg -# homeassistant.components.camera.ffmpeg +# homeassistant.components.ffmpeg ha-ffmpeg==0.12 # homeassistant.components.mqtt.server