diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index 736bcec1e9c..6a15510cf54 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -189,74 +189,26 @@ async def async_setup(hass, config): hass.helpers.event.async_track_time_interval( update_tokens, TOKEN_CHANGE_INTERVAL) - async def async_handle_camera_service(service): - """Handle calls to the camera services.""" - target_cameras = component.async_extract_from_service(service) - - update_tasks = [] - for camera in target_cameras: - if service.service == SERVICE_ENABLE_MOTION: - await camera.async_enable_motion_detection() - elif service.service == SERVICE_DISABLE_MOTION: - await camera.async_disable_motion_detection() - elif service.service == SERVICE_TURN_OFF and \ - camera.supported_features & SUPPORT_ON_OFF: - await camera.async_turn_off() - elif service.service == SERVICE_TURN_ON and \ - camera.supported_features & SUPPORT_ON_OFF: - await camera.async_turn_on() - - if not camera.should_poll: - continue - update_tasks.append(camera.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - async def async_handle_snapshot_service(service): - """Handle snapshot services calls.""" - target_cameras = component.async_extract_from_service(service) - filename = service.data[ATTR_FILENAME] - filename.hass = hass - - for camera in target_cameras: - snapshot_file = filename.async_render( - variables={ATTR_ENTITY_ID: camera}) - - # check if we allow to access to that file - if not hass.config.is_allowed_path(snapshot_file): - _LOGGER.error( - "Can't write %s, no access to path!", snapshot_file) - continue - - image = await camera.async_camera_image() - - def _write_image(to_file, image_data): - """Executor helper to write image.""" - with open(to_file, 'wb') as img_file: - img_file.write(image_data) - - try: - await hass.async_add_job( - _write_image, snapshot_file, image) - except OSError as err: - _LOGGER.error("Can't write image to file: %s", err) - - hass.services.async_register( - DOMAIN, SERVICE_TURN_OFF, async_handle_camera_service, - schema=CAMERA_SERVICE_SCHEMA) - hass.services.async_register( - DOMAIN, SERVICE_TURN_ON, async_handle_camera_service, - schema=CAMERA_SERVICE_SCHEMA) - hass.services.async_register( - DOMAIN, SERVICE_ENABLE_MOTION, async_handle_camera_service, - schema=CAMERA_SERVICE_SCHEMA) - hass.services.async_register( - DOMAIN, SERVICE_DISABLE_MOTION, async_handle_camera_service, - schema=CAMERA_SERVICE_SCHEMA) - hass.services.async_register( - DOMAIN, SERVICE_SNAPSHOT, async_handle_snapshot_service, - schema=CAMERA_SERVICE_SNAPSHOT) + component.async_register_entity_service( + SERVICE_ENABLE_MOTION, CAMERA_SERVICE_SCHEMA, + 'async_enable_motion_detection' + ) + component.async_register_entity_service( + SERVICE_DISABLE_MOTION, CAMERA_SERVICE_SCHEMA, + 'async_disable_motion_detection' + ) + component.async_register_entity_service( + SERVICE_TURN_OFF, CAMERA_SERVICE_SCHEMA, + 'async_turn_off' + ) + component.async_register_entity_service( + SERVICE_TURN_ON, CAMERA_SERVICE_SCHEMA, + 'async_turn_on' + ) + component.async_register_entity_service( + SERVICE_SNAPSHOT, CAMERA_SERVICE_SNAPSHOT, + async_handle_snapshot_service + ) return True @@ -553,3 +505,32 @@ def websocket_camera_thumbnail(hass, connection, msg): msg['id'], 'image_fetch_failed', 'Unable to fetch image')) hass.async_add_job(send_camera_still()) + + +async def async_handle_snapshot_service(camera, service): + """Handle snapshot services calls.""" + hass = camera.hass + filename = service.data[ATTR_FILENAME] + filename.hass = hass + + snapshot_file = filename.async_render( + variables={ATTR_ENTITY_ID: camera}) + + # check if we allow to access to that file + if not hass.config.is_allowed_path(snapshot_file): + _LOGGER.error( + "Can't write %s, no access to path!", snapshot_file) + return + + image = await camera.async_camera_image() + + def _write_image(to_file, image_data): + """Executor helper to write image.""" + with open(to_file, 'wb') as img_file: + img_file.write(image_data) + + try: + await hass.async_add_executor_job( + _write_image, snapshot_file, image) + except OSError as err: + _LOGGER.error("Can't write image to file: %s", err) diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 9584422e2b4..90abe2343d2 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -4,7 +4,6 @@ Provides functionality to interact with climate devices. For more details about this component, please refer to the documentation at https://home-assistant.io/components/climate/ """ -import asyncio from datetime import timedelta import logging import functools as ft @@ -250,209 +249,46 @@ async def async_setup(hass, config): EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL) await component.async_setup(config) - async def async_away_mode_set_service(service): - """Set away mode on target climate devices.""" - target_climate = component.async_extract_from_service(service) - - away_mode = service.data.get(ATTR_AWAY_MODE) - - update_tasks = [] - for climate in target_climate: - if away_mode: - await climate.async_turn_away_mode_on() - else: - await climate.async_turn_away_mode_off() - - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_AWAY_MODE, async_away_mode_set_service, - schema=SET_AWAY_MODE_SCHEMA) - - async def async_hold_mode_set_service(service): - """Set hold mode on target climate devices.""" - target_climate = component.async_extract_from_service(service) - - hold_mode = service.data.get(ATTR_HOLD_MODE) - - update_tasks = [] - for climate in target_climate: - await climate.async_set_hold_mode(hold_mode) - - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_HOLD_MODE, async_hold_mode_set_service, - schema=SET_HOLD_MODE_SCHEMA) - - async def async_aux_heat_set_service(service): - """Set auxiliary heater on target climate devices.""" - target_climate = component.async_extract_from_service(service) - - aux_heat = service.data.get(ATTR_AUX_HEAT) - - update_tasks = [] - for climate in target_climate: - if aux_heat: - await climate.async_turn_aux_heat_on() - else: - await climate.async_turn_aux_heat_off() - - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_AUX_HEAT, async_aux_heat_set_service, - schema=SET_AUX_HEAT_SCHEMA) - - async def async_temperature_set_service(service): - """Set temperature on the target climate devices.""" - target_climate = component.async_extract_from_service(service) - - update_tasks = [] - for climate in target_climate: - kwargs = {} - for value, temp in service.data.items(): - if value in CONVERTIBLE_ATTRIBUTE: - kwargs[value] = convert_temperature( - temp, - hass.config.units.temperature_unit, - climate.temperature_unit - ) - else: - kwargs[value] = temp - - await climate.async_set_temperature(**kwargs) - - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_TEMPERATURE, async_temperature_set_service, - schema=SET_TEMPERATURE_SCHEMA) - - async def async_humidity_set_service(service): - """Set humidity on the target climate devices.""" - target_climate = component.async_extract_from_service(service) - - humidity = service.data.get(ATTR_HUMIDITY) - - update_tasks = [] - for climate in target_climate: - await climate.async_set_humidity(humidity) - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_HUMIDITY, async_humidity_set_service, - schema=SET_HUMIDITY_SCHEMA) - - async def async_fan_mode_set_service(service): - """Set fan mode on target climate devices.""" - target_climate = component.async_extract_from_service(service) - - fan = service.data.get(ATTR_FAN_MODE) - - update_tasks = [] - for climate in target_climate: - await climate.async_set_fan_mode(fan) - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_FAN_MODE, async_fan_mode_set_service, - schema=SET_FAN_MODE_SCHEMA) - - async def async_operation_set_service(service): - """Set operating mode on the target climate devices.""" - target_climate = component.async_extract_from_service(service) - - operation_mode = service.data.get(ATTR_OPERATION_MODE) - - update_tasks = [] - for climate in target_climate: - await climate.async_set_operation_mode(operation_mode) - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_OPERATION_MODE, async_operation_set_service, - schema=SET_OPERATION_MODE_SCHEMA) - - async def async_swing_set_service(service): - """Set swing mode on the target climate devices.""" - target_climate = component.async_extract_from_service(service) - - swing_mode = service.data.get(ATTR_SWING_MODE) - - update_tasks = [] - for climate in target_climate: - await climate.async_set_swing_mode(swing_mode) - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_SET_SWING_MODE, async_swing_set_service, - schema=SET_SWING_MODE_SCHEMA) - - async def async_on_off_service(service): - """Handle on/off calls.""" - target_climate = component.async_extract_from_service(service) - - update_tasks = [] - for climate in target_climate: - if service.service == SERVICE_TURN_ON: - await climate.async_turn_on() - elif service.service == SERVICE_TURN_OFF: - await climate.async_turn_off() - - if not climate.should_poll: - continue - update_tasks.append(climate.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - hass.services.async_register( - DOMAIN, SERVICE_TURN_OFF, async_on_off_service, - schema=ON_OFF_SERVICE_SCHEMA) - hass.services.async_register( - DOMAIN, SERVICE_TURN_ON, async_on_off_service, - schema=ON_OFF_SERVICE_SCHEMA) + component.async_register_entity_service( + SERVICE_SET_AWAY_MODE, SET_AWAY_MODE_SCHEMA, + async_service_away_mode + ) + component.async_register_entity_service( + SERVICE_SET_HOLD_MODE, SET_HOLD_MODE_SCHEMA, + 'async_set_hold_mode' + ) + component.async_register_entity_service( + SERVICE_SET_AUX_HEAT, SET_AUX_HEAT_SCHEMA, + async_service_aux_heat + ) + component.async_register_entity_service( + SERVICE_SET_TEMPERATURE, SET_TEMPERATURE_SCHEMA, + async_service_temperature_set + ) + component.async_register_entity_service( + SERVICE_SET_HUMIDITY, SET_HUMIDITY_SCHEMA, + 'async_set_humidity' + ) + component.async_register_entity_service( + SERVICE_SET_FAN_MODE, SET_FAN_MODE_SCHEMA, + 'async_set_fan_mode' + ) + component.async_register_entity_service( + SERVICE_SET_OPERATION_MODE, SET_OPERATION_MODE_SCHEMA, + 'async_set_operation_mode' + ) + component.async_register_entity_service( + SERVICE_SET_SWING_MODE, SET_SWING_MODE_SCHEMA, + 'async_set_swing_mode' + ) + component.async_register_entity_service( + SERVICE_TURN_OFF, ON_OFF_SERVICE_SCHEMA, + 'async_turn_off' + ) + component.async_register_entity_service( + SERVICE_TURN_ON, ON_OFF_SERVICE_SCHEMA, + 'async_turn_on' + ) return True @@ -812,3 +648,37 @@ class ClimateDevice(Entity): def max_humidity(self): """Return the maximum humidity.""" return DEFAULT_MAX_HUMIDITY + + +async def async_service_away_mode(entity, service): + """Handle away mode service.""" + if service.data[ATTR_AWAY_MODE]: + await entity.async_turn_away_mode_on() + else: + await entity.async_turn_away_mode_off() + + +async def async_service_aux_heat(entity, service): + """Handle aux heat service.""" + if service.data[ATTR_AUX_HEAT]: + await entity.async_turn_aux_heat_on() + else: + await entity.async_turn_aux_heat_off() + + +async def async_service_temperature_set(entity, service): + """Handle set temperature service.""" + hass = entity.hass + kwargs = {} + + for value, temp in service.data.items(): + if value in CONVERTIBLE_ATTRIBUTE: + kwargs[value] = convert_temperature( + temp, + hass.config.units.temperature_unit, + entity.temperature_unit + ) + else: + kwargs[value] = temp + + await entity.async_set_temperature(**kwargs) diff --git a/homeassistant/components/fan/__init__.py b/homeassistant/components/fan/__init__.py index db0e8c590fd..f2704e84bc5 100644 --- a/homeassistant/components/fan/__init__.py +++ b/homeassistant/components/fan/__init__.py @@ -89,33 +89,6 @@ FAN_SET_DIRECTION_SCHEMA = vol.Schema({ vol.Optional(ATTR_DIRECTION): cv.string }) # type: dict -SERVICE_TO_METHOD = { - SERVICE_TURN_ON: { - 'method': 'async_turn_on', - 'schema': FAN_TURN_ON_SCHEMA, - }, - SERVICE_TURN_OFF: { - 'method': 'async_turn_off', - 'schema': FAN_TURN_OFF_SCHEMA, - }, - SERVICE_TOGGLE: { - 'method': 'async_toggle', - 'schema': FAN_TOGGLE_SCHEMA, - }, - SERVICE_SET_SPEED: { - 'method': 'async_set_speed', - 'schema': FAN_SET_SPEED_SCHEMA, - }, - SERVICE_OSCILLATE: { - 'method': 'async_oscillate', - 'schema': FAN_OSCILLATE_SCHEMA, - }, - SERVICE_SET_DIRECTION: { - 'method': 'async_set_direction', - 'schema': FAN_SET_DIRECTION_SCHEMA, - }, -} - @bind_hass def is_on(hass, entity_id: str = None) -> bool: @@ -204,30 +177,30 @@ def async_setup(hass, config: dict): yield from component.async_setup(config) - @asyncio.coroutine - def async_handle_fan_service(service): - """Handle service call for fans.""" - method = SERVICE_TO_METHOD.get(service.service) - params = service.data.copy() - - # Convert the entity ids to valid fan ids - target_fans = component.async_extract_from_service(service) - params.pop(ATTR_ENTITY_ID, None) - - update_tasks = [] - for fan in target_fans: - yield from getattr(fan, method['method'])(**params) - if not fan.should_poll: - continue - update_tasks.append(fan.async_update_ha_state(True)) - - if update_tasks: - yield from asyncio.wait(update_tasks, loop=hass.loop) - - for service_name in SERVICE_TO_METHOD: - schema = SERVICE_TO_METHOD[service_name].get('schema') - hass.services.async_register( - DOMAIN, service_name, async_handle_fan_service, schema=schema) + component.async_register_entity_service( + SERVICE_TURN_ON, FAN_TURN_ON_SCHEMA, + 'async_turn_on' + ) + component.async_register_entity_service( + SERVICE_TURN_OFF, FAN_TURN_OFF_SCHEMA, + 'async_turn_off' + ) + component.async_register_entity_service( + SERVICE_TOGGLE, FAN_TOGGLE_SCHEMA, + 'async_toggle' + ) + component.async_register_entity_service( + SERVICE_SET_SPEED, FAN_SET_SPEED_SCHEMA, + 'async_set_speed' + ) + component.async_register_entity_service( + SERVICE_OSCILLATE, FAN_OSCILLATE_SCHEMA, + 'async_oscillate' + ) + component.async_register_entity_service( + SERVICE_SET_DIRECTION, FAN_SET_DIRECTION_SCHEMA, + 'async_set_direction' + ) return True diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index 8b4b2137711..456ad6d69be 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -332,8 +332,8 @@ async def async_setup(hass, config): if not profiles_valid: return False - async def async_handle_light_service(service): - """Handle a turn light on or off service call.""" + async def async_handle_light_on_service(service): + """Handle a turn light on service call.""" # Get the validated data params = service.data.copy() @@ -345,17 +345,12 @@ async def async_setup(hass, config): update_tasks = [] for light in target_lights: - if service.service == SERVICE_TURN_ON: - pars = params - if not pars: - pars = params.copy() - pars[ATTR_PROFILE] = Profiles.get_default(light.entity_id) - preprocess_turn_on_alternatives(pars) - await light.async_turn_on(**pars) - elif service.service == SERVICE_TURN_OFF: - await light.async_turn_off(**params) - else: - await light.async_toggle(**params) + pars = params + if not pars: + pars = params.copy() + pars[ATTR_PROFILE] = Profiles.get_default(light.entity_id) + preprocess_turn_on_alternatives(pars) + await light.async_turn_on(**pars) if not light.should_poll: continue @@ -368,16 +363,18 @@ async def async_setup(hass, config): # Listen for light on and light off service calls. hass.services.async_register( - DOMAIN, SERVICE_TURN_ON, async_handle_light_service, + DOMAIN, SERVICE_TURN_ON, async_handle_light_on_service, schema=LIGHT_TURN_ON_SCHEMA) - hass.services.async_register( - DOMAIN, SERVICE_TURN_OFF, async_handle_light_service, - schema=LIGHT_TURN_OFF_SCHEMA) + component.async_register_entity_service( + SERVICE_TURN_OFF, LIGHT_TURN_OFF_SCHEMA, + 'async_turn_off' + ) - hass.services.async_register( - DOMAIN, SERVICE_TOGGLE, async_handle_light_service, - schema=LIGHT_TOGGLE_SCHEMA) + component.async_register_entity_service( + SERVICE_TOGGLE, LIGHT_TOGGLE_SCHEMA, + 'async_toggle' + ) hass.helpers.intent.async_register(SetIntentHandler()) diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index c475291227a..31c254c0a39 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -151,42 +151,6 @@ MEDIA_PLAYER_SET_SHUFFLE_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({ vol.Required(ATTR_MEDIA_SHUFFLE): cv.boolean, }) -SERVICE_TO_METHOD = { - SERVICE_TURN_ON: {'method': 'async_turn_on'}, - SERVICE_TURN_OFF: {'method': 'async_turn_off'}, - SERVICE_TOGGLE: {'method': 'async_toggle'}, - SERVICE_VOLUME_UP: {'method': 'async_volume_up'}, - SERVICE_VOLUME_DOWN: {'method': 'async_volume_down'}, - SERVICE_MEDIA_PLAY_PAUSE: {'method': 'async_media_play_pause'}, - SERVICE_MEDIA_PLAY: {'method': 'async_media_play'}, - SERVICE_MEDIA_PAUSE: {'method': 'async_media_pause'}, - SERVICE_MEDIA_STOP: {'method': 'async_media_stop'}, - SERVICE_MEDIA_NEXT_TRACK: {'method': 'async_media_next_track'}, - SERVICE_MEDIA_PREVIOUS_TRACK: {'method': 'async_media_previous_track'}, - SERVICE_CLEAR_PLAYLIST: {'method': 'async_clear_playlist'}, - SERVICE_VOLUME_SET: { - 'method': 'async_set_volume_level', - 'schema': MEDIA_PLAYER_SET_VOLUME_SCHEMA}, - SERVICE_VOLUME_MUTE: { - 'method': 'async_mute_volume', - 'schema': MEDIA_PLAYER_MUTE_VOLUME_SCHEMA}, - SERVICE_MEDIA_SEEK: { - 'method': 'async_media_seek', - 'schema': MEDIA_PLAYER_MEDIA_SEEK_SCHEMA}, - SERVICE_SELECT_SOURCE: { - 'method': 'async_select_source', - 'schema': MEDIA_PLAYER_SELECT_SOURCE_SCHEMA}, - SERVICE_SELECT_SOUND_MODE: { - 'method': 'async_select_sound_mode', - 'schema': MEDIA_PLAYER_SELECT_SOUND_MODE_SCHEMA}, - SERVICE_PLAY_MEDIA: { - 'method': 'async_play_media', - 'schema': MEDIA_PLAYER_PLAY_MEDIA_SCHEMA}, - SERVICE_SHUFFLE_SET: { - 'method': 'async_set_shuffle', - 'schema': MEDIA_PLAYER_SET_SHUFFLE_SCHEMA}, -} - ATTR_TO_PROPERTY = [ ATTR_MEDIA_VOLUME_LEVEL, ATTR_MEDIA_VOLUME_MUTED, @@ -409,50 +373,89 @@ async def async_setup(hass, config): await component.async_setup(config) - async def async_service_handler(service): - """Map services to methods on MediaPlayerDevice.""" - method = SERVICE_TO_METHOD.get(service.service) - if not method: - return - - params = {} - if service.service == SERVICE_VOLUME_SET: - params['volume'] = service.data.get(ATTR_MEDIA_VOLUME_LEVEL) - elif service.service == SERVICE_VOLUME_MUTE: - params['mute'] = service.data.get(ATTR_MEDIA_VOLUME_MUTED) - elif service.service == SERVICE_MEDIA_SEEK: - params['position'] = service.data.get(ATTR_MEDIA_SEEK_POSITION) - elif service.service == SERVICE_SELECT_SOURCE: - params['source'] = service.data.get(ATTR_INPUT_SOURCE) - elif service.service == SERVICE_SELECT_SOUND_MODE: - params['sound_mode'] = service.data.get(ATTR_SOUND_MODE) - elif service.service == SERVICE_PLAY_MEDIA: - params['media_type'] = \ - service.data.get(ATTR_MEDIA_CONTENT_TYPE) - params['media_id'] = service.data.get(ATTR_MEDIA_CONTENT_ID) - params[ATTR_MEDIA_ENQUEUE] = \ - service.data.get(ATTR_MEDIA_ENQUEUE) - elif service.service == SERVICE_SHUFFLE_SET: - params[ATTR_MEDIA_SHUFFLE] = \ - service.data.get(ATTR_MEDIA_SHUFFLE) - target_players = component.async_extract_from_service(service) - - update_tasks = [] - for player in target_players: - await getattr(player, method['method'])(**params) - if not player.should_poll: - continue - update_tasks.append(player.async_update_ha_state(True)) - - if update_tasks: - await asyncio.wait(update_tasks, loop=hass.loop) - - for service in SERVICE_TO_METHOD: - schema = SERVICE_TO_METHOD[service].get( - 'schema', MEDIA_PLAYER_SCHEMA) - hass.services.async_register( - DOMAIN, service, async_service_handler, - schema=schema) + component.async_register_entity_service( + SERVICE_TURN_ON, MEDIA_PLAYER_SCHEMA, + 'async_turn_on' + ) + component.async_register_entity_service( + SERVICE_TURN_OFF, MEDIA_PLAYER_SCHEMA, + 'async_turn_off' + ) + component.async_register_entity_service( + SERVICE_TOGGLE, MEDIA_PLAYER_SCHEMA, + 'async_toggle' + ) + component.async_register_entity_service( + SERVICE_VOLUME_UP, MEDIA_PLAYER_SCHEMA, + 'async_volume_up' + ) + component.async_register_entity_service( + SERVICE_VOLUME_DOWN, MEDIA_PLAYER_SCHEMA, + 'async_volume_down' + ) + component.async_register_entity_service( + SERVICE_MEDIA_PLAY_PAUSE, MEDIA_PLAYER_SCHEMA, + 'async_media_play_pause' + ) + component.async_register_entity_service( + SERVICE_MEDIA_PLAY, MEDIA_PLAYER_SCHEMA, + 'async_media_play' + ) + component.async_register_entity_service( + SERVICE_MEDIA_PAUSE, MEDIA_PLAYER_SCHEMA, + 'async_media_pause' + ) + component.async_register_entity_service( + SERVICE_MEDIA_STOP, MEDIA_PLAYER_SCHEMA, + 'async_media_stop' + ) + component.async_register_entity_service( + SERVICE_MEDIA_NEXT_TRACK, MEDIA_PLAYER_SCHEMA, + 'async_media_next_track' + ) + component.async_register_entity_service( + SERVICE_MEDIA_PREVIOUS_TRACK, MEDIA_PLAYER_SCHEMA, + 'async_media_previous_track' + ) + component.async_register_entity_service( + SERVICE_CLEAR_PLAYLIST, MEDIA_PLAYER_SCHEMA, + 'async_clear_playlist' + ) + component.async_register_entity_service( + SERVICE_VOLUME_SET, MEDIA_PLAYER_SET_VOLUME_SCHEMA, + lambda entity, call: entity.async_set_volume_level( + volume=call.data[ATTR_MEDIA_VOLUME_LEVEL]) + ) + component.async_register_entity_service( + SERVICE_VOLUME_MUTE, MEDIA_PLAYER_MUTE_VOLUME_SCHEMA, + lambda entity, call: entity.async_mute_volume( + mute=call.data[ATTR_MEDIA_VOLUME_MUTED]) + ) + component.async_register_entity_service( + SERVICE_MEDIA_SEEK, MEDIA_PLAYER_MEDIA_SEEK_SCHEMA, + lambda entity, call: entity.async_media_seek( + position=call.data[ATTR_MEDIA_SEEK_POSITION]) + ) + component.async_register_entity_service( + SERVICE_SELECT_SOURCE, MEDIA_PLAYER_SELECT_SOURCE_SCHEMA, + 'async_select_source' + ) + component.async_register_entity_service( + SERVICE_SELECT_SOUND_MODE, MEDIA_PLAYER_SELECT_SOUND_MODE_SCHEMA, + 'async_select_sound_mode' + ) + component.async_register_entity_service( + SERVICE_PLAY_MEDIA, MEDIA_PLAYER_PLAY_MEDIA_SCHEMA, + lambda entity, call: entity.async_play_media( + media_type=call.data[ATTR_MEDIA_CONTENT_TYPE], + media_id=call.data[ATTR_MEDIA_CONTENT_ID], + enqueue=call.data.get(ATTR_MEDIA_ENQUEUE) + ) + ) + component.async_register_entity_service( + SERVICE_SHUFFLE_SET, MEDIA_PLAYER_SET_SHUFFLE_SCHEMA, + 'async_set_shuffle' + ) return True diff --git a/tests/components/camera/test_demo.py b/tests/components/camera/test_demo.py index b901b723c0b..63c70ddc6ca 100644 --- a/tests/components/camera/test_demo.py +++ b/tests/components/camera/test_demo.py @@ -1,5 +1,5 @@ """The tests for local file camera component.""" -from unittest.mock import mock_open, patch, PropertyMock +from unittest.mock import mock_open, patch import pytest @@ -67,19 +67,6 @@ async def test_turn_off_invalid_camera(hass, demo_camera): assert demo_camera.state == STATE_STREAMING -async def test_turn_off_unsupport_camera(hass, demo_camera): - """Turn off unsupported camera should quietly fail.""" - assert demo_camera.state == STATE_STREAMING - with patch('homeassistant.components.camera.demo.DemoCamera' - '.supported_features', new_callable=PropertyMock) as m: - m.return_value = 0 - - await camera.async_turn_off(hass, demo_camera.entity_id) - await hass.async_block_till_done() - - assert demo_camera.state == STATE_STREAMING - - async def test_motion_detection(hass): """Test motion detection services.""" # Setup platform diff --git a/tests/components/light/test_rflink.py b/tests/components/light/test_rflink.py index a6e6d3c1a85..c55c16077e0 100644 --- a/tests/components/light/test_rflink.py +++ b/tests/components/light/test_rflink.py @@ -356,11 +356,10 @@ def test_signal_repetitions_cancelling(hass, monkeypatch): yield from hass.async_block_till_done() - print(protocol.send_command_ack.call_args_list) - assert protocol.send_command_ack.call_args_list[0][0][1] == 'off' - assert protocol.send_command_ack.call_args_list[1][0][1] == 'on' - assert protocol.send_command_ack.call_args_list[2][0][1] == 'on' - assert protocol.send_command_ack.call_args_list[3][0][1] == 'on' + assert protocol.send_command_ack.call_args_list[0][0][1] == 'on' + assert protocol.send_command_ack.call_args_list[1][0][1] == 'off' + assert protocol.send_command_ack.call_args_list[2][0][1] == 'off' + assert protocol.send_command_ack.call_args_list[3][0][1] == 'off' @asyncio.coroutine