diff --git a/homeassistant/components/alarm_control_panel/demo.py b/homeassistant/components/alarm_control_panel/demo.py index a3fbe49477e..fb4dccc1c86 100644 --- a/homeassistant/components/alarm_control_panel/demo.py +++ b/homeassistant/components/alarm_control_panel/demo.py @@ -13,9 +13,10 @@ from homeassistant.const import ( CONF_PENDING_TIME, CONF_TRIGGER_TIME) -def setup_platform(hass, config, add_entities, discovery_info=None): +async def async_setup_platform(hass, config, async_add_entities, + discovery_info=None): """Set up the Demo alarm control panel platform.""" - add_entities([ + async_add_entities([ manual.ManualAlarm(hass, 'Alarm', '1234', None, False, { STATE_ALARM_ARMED_AWAY: { CONF_DELAY_TIME: datetime.timedelta(seconds=0), diff --git a/tests/components/alarm_control_panel/common.py b/tests/components/alarm_control_panel/common.py index cf2de857076..829c05fef31 100644 --- a/tests/components/alarm_control_panel/common.py +++ b/tests/components/alarm_control_panel/common.py @@ -9,6 +9,21 @@ from homeassistant.const import ( SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY, SERVICE_ALARM_ARM_NIGHT, SERVICE_ALARM_ARM_CUSTOM_BYPASS) from homeassistant.loader import bind_hass +from homeassistant.core import callback + + +@callback +@bind_hass +def async_alarm_disarm(hass, code=None, entity_id=None): + """Send the alarm the command for disarm.""" + data = {} + if code: + data[ATTR_CODE] = code + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.async_create_task( + hass.services.async_call(DOMAIN, SERVICE_ALARM_DISARM, data)) @bind_hass @@ -23,6 +38,20 @@ def alarm_disarm(hass, code=None, entity_id=None): hass.services.call(DOMAIN, SERVICE_ALARM_DISARM, data) +@callback +@bind_hass +def async_alarm_arm_home(hass, code=None, entity_id=None): + """Send the alarm the command for disarm.""" + data = {} + if code: + data[ATTR_CODE] = code + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.async_create_task( + hass.services.async_call(DOMAIN, SERVICE_ALARM_ARM_HOME, data)) + + @bind_hass def alarm_arm_home(hass, code=None, entity_id=None): """Send the alarm the command for arm home.""" @@ -35,6 +64,20 @@ def alarm_arm_home(hass, code=None, entity_id=None): hass.services.call(DOMAIN, SERVICE_ALARM_ARM_HOME, data) +@callback +@bind_hass +def async_alarm_arm_away(hass, code=None, entity_id=None): + """Send the alarm the command for disarm.""" + data = {} + if code: + data[ATTR_CODE] = code + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.async_create_task( + hass.services.async_call(DOMAIN, SERVICE_ALARM_ARM_AWAY, data)) + + @bind_hass def alarm_arm_away(hass, code=None, entity_id=None): """Send the alarm the command for arm away.""" @@ -47,6 +90,20 @@ def alarm_arm_away(hass, code=None, entity_id=None): hass.services.call(DOMAIN, SERVICE_ALARM_ARM_AWAY, data) +@callback +@bind_hass +def async_alarm_arm_night(hass, code=None, entity_id=None): + """Send the alarm the command for disarm.""" + data = {} + if code: + data[ATTR_CODE] = code + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.async_create_task( + hass.services.async_call(DOMAIN, SERVICE_ALARM_ARM_NIGHT, data)) + + @bind_hass def alarm_arm_night(hass, code=None, entity_id=None): """Send the alarm the command for arm night.""" @@ -59,6 +116,20 @@ def alarm_arm_night(hass, code=None, entity_id=None): hass.services.call(DOMAIN, SERVICE_ALARM_ARM_NIGHT, data) +@callback +@bind_hass +def async_alarm_trigger(hass, code=None, entity_id=None): + """Send the alarm the command for disarm.""" + data = {} + if code: + data[ATTR_CODE] = code + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.async_create_task( + hass.services.async_call(DOMAIN, SERVICE_ALARM_TRIGGER, data)) + + @bind_hass def alarm_trigger(hass, code=None, entity_id=None): """Send the alarm the command for trigger.""" @@ -71,6 +142,21 @@ def alarm_trigger(hass, code=None, entity_id=None): hass.services.call(DOMAIN, SERVICE_ALARM_TRIGGER, data) +@callback +@bind_hass +def async_alarm_arm_custom_bypass(hass, code=None, entity_id=None): + """Send the alarm the command for disarm.""" + data = {} + if code: + data[ATTR_CODE] = code + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.async_create_task( + hass.services.async_call( + DOMAIN, SERVICE_ALARM_ARM_CUSTOM_BYPASS, data)) + + @bind_hass def alarm_arm_custom_bypass(hass, code=None, entity_id=None): """Send the alarm the command for arm custom bypass.""" diff --git a/tests/components/alarm_control_panel/test_manual.py b/tests/components/alarm_control_panel/test_manual.py index b39d4ecbbe9..36bae21dc32 100644 --- a/tests/components/alarm_control_panel/test_manual.py +++ b/tests/components/alarm_control_panel/test_manual.py @@ -1,16 +1,15 @@ """The tests for the manual Alarm Control Panel component.""" from datetime import timedelta -import unittest from unittest.mock import patch, MagicMock from homeassistant.components.alarm_control_panel import demo -from homeassistant.setup import setup_component, async_setup_component +from homeassistant.setup import async_setup_component from homeassistant.const import ( STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED) from homeassistant.components import alarm_control_panel import homeassistant.util.dt as dt_util -from tests.common import (fire_time_changed, get_test_home_assistant, +from tests.common import (async_fire_time_changed, mock_component, mock_restore_cache) from tests.components.alarm_control_panel import common from homeassistant.core import State, CoreState @@ -18,1306 +17,1326 @@ from homeassistant.core import State, CoreState CODE = 'HELLO_CODE' -class TestAlarmControlPanelManual(unittest.TestCase): - """Test the manual alarm module.""" +async def test_setup_demo_platform(hass): + """Test setup.""" + mock = MagicMock() + add_entities = mock.MagicMock() + await demo.async_setup_platform(hass, {}, add_entities) + assert add_entities.call_count == 1 - def setUp(self): # pylint: disable=invalid-name - """Set up things to be run when tests are started.""" - self.hass = get_test_home_assistant() - def tearDown(self): # pylint: disable=invalid-name - """Stop down everything that was started.""" - self.hass.stop() +async def test_arm_home_no_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) - def test_setup_demo_platform(self): - """Test setup.""" - mock = MagicMock() - add_entities = mock.MagicMock() - demo.setup_platform(self.hass, {}, add_entities) - assert add_entities.call_count == 1 + entity_id = 'alarm_control_panel.test' - def test_arm_home_no_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state - entity_id = 'alarm_control_panel.test' + common.async_alarm_arm_home(hass, CODE) + await hass.async_block_till_done() - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state + assert STATE_ALARM_ARMED_HOME == \ + hass.states.get(entity_id).state - common.alarm_arm_home(self.hass, CODE) - self.hass.block_till_done() - assert STATE_ALARM_ARMED_HOME == \ - self.hass.states.get(entity_id).state +async def test_arm_home_with_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) - def test_arm_home_with_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_home(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + state = hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_HOME + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_HOME + + +async def test_arm_home_with_invalid_code(hass): + """Attempt to arm home without a valid code.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_home(hass, CODE + '2') + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_arm_away_no_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + +async def test_arm_home_with_template_code(hass): + """Attempt to arm with a template-based code.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code_template': '{{ "abc" }}', + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_home(hass, 'abc') + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_ARMED_HOME == state.state + + +async def test_arm_away_with_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + state = hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_AWAY + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_AWAY + + +async def test_arm_away_with_invalid_code(hass): + """Attempt to arm away without a valid code.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE + '2') + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_arm_night_no_pending(hass): + """Test arm night method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_night(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_NIGHT == \ + hass.states.get(entity_id).state + + +async def test_arm_night_with_pending(hass): + """Test arm night method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_night(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + state = hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == \ + STATE_ALARM_ARMED_NIGHT + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_NIGHT + + # Do not go to the pending state when updating to the same state + common.async_alarm_arm_night(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_NIGHT == \ + hass.states.get(entity_id).state + + +async def test_arm_night_with_invalid_code(hass): + """Attempt to night home without a valid code.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_night(hass, CODE + '2') + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_no_pending(hass): + """Test triggering when no pending submitted method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=60) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_delay(hass): + """Test trigger method and switch from pending to triggered.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'delay_time': 1, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_PENDING == state.state + assert STATE_ALARM_TRIGGERED == \ + state.attributes['post_pending_state'] + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_TRIGGERED == state.state + + +async def test_trigger_zero_trigger_time(hass): + """Test disabled trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 0, + 'trigger_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_zero_trigger_time_with_pending(hass): + """Test disabled trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 2, + 'trigger_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 2, + 'trigger_time': 3, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + state = hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED + + future = dt_util.utcnow() + timedelta(seconds=2) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_TRIGGERED + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_DISARMED + + +async def test_trigger_with_unused_specific_delay(hass): + """Test trigger method and switch from pending to triggered.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'delay_time': 5, + 'pending_time': 0, + 'armed_home': { + 'delay_time': 10 + }, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_PENDING == state.state + assert STATE_ALARM_TRIGGERED == \ + state.attributes['post_pending_state'] + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_TRIGGERED + + +async def test_trigger_with_specific_delay(hass): + """Test trigger method and switch from pending to triggered.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'delay_time': 10, + 'pending_time': 0, + 'armed_away': { + 'delay_time': 1 + }, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_PENDING == state.state + assert STATE_ALARM_TRIGGERED == \ + state.attributes['post_pending_state'] + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_TRIGGERED + + +async def test_trigger_with_pending_and_delay(hass): + """Test trigger method and switch from pending to triggered.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'delay_time': 1, + 'pending_time': 0, + 'triggered': { + 'pending_time': 1 + }, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_PENDING + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_PENDING + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED + + future += timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_TRIGGERED + + +async def test_trigger_with_pending_and_specific_delay(hass): + """Test trigger method and switch from pending to triggered.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'delay_time': 10, + 'pending_time': 0, + 'armed_away': { + 'delay_time': 1 + }, + 'triggered': { + 'pending_time': 1 + }, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_PENDING + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_PENDING + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED + + future += timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_TRIGGERED + + +async def test_armed_home_with_specific_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 10, + 'armed_home': { + 'pending_time': 2 + } + }}) + + entity_id = 'alarm_control_panel.test' + + common.async_alarm_arm_home(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=2) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_HOME == \ + hass.states.get(entity_id).state + + +async def test_armed_away_with_specific_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 10, + 'armed_away': { + 'pending_time': 2 + } + }}) + + entity_id = 'alarm_control_panel.test' + + common.async_alarm_arm_away(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=2) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + +async def test_armed_night_with_specific_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 10, + 'armed_night': { + 'pending_time': 2 + } + }}) + + entity_id = 'alarm_control_panel.test' + + common.async_alarm_arm_night(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=2) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_NIGHT == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_specific_pending(hass): + """Test arm home method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 10, + 'triggered': { + 'pending_time': 2 + }, + 'trigger_time': 3, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + common.async_alarm_trigger(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=2) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_disarm_after_trigger(hass): + """Test disarm after trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 5, + 'pending_time': 0, + 'disarm_after_trigger': True + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_zero_specific_trigger_time(hass): + """Test trigger method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 5, + 'disarmed': { + 'trigger_time': 0 + }, + 'pending_time': 0, + 'disarm_after_trigger': True + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_unused_zero_specific_trigger_time(hass): + """Test disarm after trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 5, + 'armed_home': { + 'trigger_time': 0 + }, + 'pending_time': 0, + 'disarm_after_trigger': True + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_specific_trigger_time(hass): + """Test disarm after trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'disarmed': { + 'trigger_time': 5 + }, + 'pending_time': 0, + 'disarm_after_trigger': True + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_trigger_with_no_disarm_after_trigger(hass): + """Test disarm after trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 5, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + +async def test_back_to_back_trigger_with_no_disarm_after_trigger(hass): + """Test disarm after trigger.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 5, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_AWAY == \ + hass.states.get(entity_id).state + + +async def test_disarm_while_pending_trigger(hass): + """Test disarming while pending state.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'trigger_time': 5, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + common.async_alarm_disarm(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_disarm_during_trigger_with_invalid_code(hass): + """Test disarming while code is invalid.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 5, + 'code': CODE + '2', + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_trigger(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + common.async_alarm_disarm(hass, entity_id=entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=5) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_TRIGGERED == \ + hass.states.get(entity_id).state + + +async def test_disarm_with_template_code(hass): + """Attempt to disarm with a valid or invalid template-based code.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code_template': + '{{ "" if from_state == "disarmed" else "abc" }}', + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_home(hass, 'def') + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_ARMED_HOME == state.state + + common.async_alarm_disarm(hass, 'def') + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_ARMED_HOME == state.state + + common.async_alarm_disarm(hass, 'abc') + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_DISARMED == state.state + + +async def test_arm_custom_bypass_no_pending(hass): + """Test arm custom bypass method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 0, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_custom_bypass(hass, CODE) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_CUSTOM_BYPASS == \ + hass.states.get(entity_id).state + + +async def test_arm_custom_bypass_with_pending(hass): + """Test arm custom bypass method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_custom_bypass(hass, CODE, entity_id) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + state = hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == \ + STATE_ALARM_ARMED_CUSTOM_BYPASS + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_CUSTOM_BYPASS + + +async def test_arm_custom_bypass_with_invalid_code(hass): + """Attempt to custom bypass without a valid code.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 1, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_custom_bypass(hass, CODE + '2') + await hass.async_block_till_done() + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + +async def test_armed_custom_bypass_with_specific_pending(hass): + """Test arm custom bypass method.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'pending_time': 10, + 'armed_custom_bypass': { + 'pending_time': 2 + } + }}) + + entity_id = 'alarm_control_panel.test' + + common.async_alarm_arm_custom_bypass(hass) + await hass.async_block_till_done() + + assert STATE_ALARM_PENDING == \ + hass.states.get(entity_id).state + + future = dt_util.utcnow() + timedelta(seconds=2) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + assert STATE_ALARM_ARMED_CUSTOM_BYPASS == \ + hass.states.get(entity_id).state + + +async def test_arm_away_after_disabled_disarmed(hass): + """Test pending state with and without zero trigger time.""" + assert await async_setup_component( + hass, alarm_control_panel.DOMAIN, + {'alarm_control_panel': { + 'platform': 'manual', + 'name': 'test', + 'code': CODE, + 'pending_time': 0, + 'delay_time': 1, + 'armed_away': { 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_home(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - state = self.hass.states.get(entity_id) - assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_HOME - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_ARMED_HOME - - def test_arm_home_with_invalid_code(self): - """Attempt to arm home without a valid code.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_home(self.hass, CODE + '2') - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_arm_away_no_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - def test_arm_home_with_template_code(self): - """Attempt to arm with a template-based code.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code_template': '{{ "abc" }}', - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - self.hass.start() - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_home(self.hass, 'abc') - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_ARMED_HOME == state.state - - def test_arm_away_with_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - state = self.hass.states.get(entity_id) - assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_AWAY - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_ARMED_AWAY - - def test_arm_away_with_invalid_code(self): - """Attempt to arm away without a valid code.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE + '2') - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_arm_night_no_pending(self): - """Test arm night method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_night(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_NIGHT == \ - self.hass.states.get(entity_id).state - - def test_arm_night_with_pending(self): - """Test arm night method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_night(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - state = self.hass.states.get(entity_id) - assert state.attributes['post_pending_state'] == \ - STATE_ALARM_ARMED_NIGHT - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_ARMED_NIGHT - - # Do not go to the pending state when updating to the same state - common.alarm_arm_night(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_NIGHT == \ - self.hass.states.get(entity_id).state - - def test_arm_night_with_invalid_code(self): - """Attempt to night home without a valid code.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_night(self.hass, CODE + '2') - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_no_pending(self): - """Test triggering when no pending submitted method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=60) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_delay(self): - """Test trigger method and switch from pending to triggered.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'delay_time': 1, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) + }, + 'disarmed': { + 'trigger_time': 0 + }, + 'disarm_after_trigger': False + }}) + + entity_id = 'alarm_control_panel.test' + + assert STATE_ALARM_DISARMED == \ + hass.states.get(entity_id).state + + common.async_alarm_arm_away(hass, CODE) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_PENDING == state.state + assert STATE_ALARM_DISARMED == \ + state.attributes['pre_pending_state'] + assert STATE_ALARM_ARMED_AWAY == \ + state.attributes['post_pending_state'] + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_PENDING == state.state + assert STATE_ALARM_DISARMED == \ + state.attributes['pre_pending_state'] + assert STATE_ALARM_ARMED_AWAY == \ + state.attributes['post_pending_state'] + + future = dt_util.utcnow() + timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) + assert STATE_ALARM_ARMED_AWAY == state.state + + common.async_alarm_trigger(hass, entity_id=entity_id) + await hass.async_block_till_done() + + state = hass.states.get(entity_id) assert STATE_ALARM_PENDING == state.state - assert STATE_ALARM_TRIGGERED == \ - state.attributes['post_pending_state'] - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_TRIGGERED == state.state - - def test_trigger_zero_trigger_time(self): - """Test disabled trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 0, - 'trigger_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_zero_trigger_time_with_pending(self): - """Test disabled trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 2, - 'trigger_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 2, - 'trigger_time': 3, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - state = self.hass.states.get(entity_id) - assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED - - future = dt_util.utcnow() + timedelta(seconds=2) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_TRIGGERED - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_DISARMED - - def test_trigger_with_unused_specific_delay(self): - """Test trigger method and switch from pending to triggered.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'delay_time': 5, - 'pending_time': 0, - 'armed_home': { - 'delay_time': 10 - }, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_PENDING == state.state - assert STATE_ALARM_TRIGGERED == \ - state.attributes['post_pending_state'] - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_TRIGGERED - - def test_trigger_with_specific_delay(self): - """Test trigger method and switch from pending to triggered.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'delay_time': 10, - 'pending_time': 0, - 'armed_away': { - 'delay_time': 1 - }, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_PENDING == state.state - assert STATE_ALARM_TRIGGERED == \ - state.attributes['post_pending_state'] - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_TRIGGERED - - def test_trigger_with_pending_and_delay(self): - """Test trigger method and switch from pending to triggered.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'delay_time': 1, - 'pending_time': 0, - 'triggered': { - 'pending_time': 1 - }, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_PENDING - assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_PENDING - assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED - - future += timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_TRIGGERED - - def test_trigger_with_pending_and_specific_delay(self): - """Test trigger method and switch from pending to triggered.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'delay_time': 10, - 'pending_time': 0, - 'armed_away': { - 'delay_time': 1 - }, - 'triggered': { - 'pending_time': 1 - }, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_PENDING - assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_PENDING - assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED - - future += timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_TRIGGERED - - def test_armed_home_with_specific_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 10, - 'armed_home': { - 'pending_time': 2 - } - }}) - - entity_id = 'alarm_control_panel.test' - - common.alarm_arm_home(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=2) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_HOME == \ - self.hass.states.get(entity_id).state - - def test_armed_away_with_specific_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 10, - 'armed_away': { - 'pending_time': 2 - } - }}) - - entity_id = 'alarm_control_panel.test' - - common.alarm_arm_away(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=2) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - def test_armed_night_with_specific_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 10, - 'armed_night': { - 'pending_time': 2 - } - }}) - - entity_id = 'alarm_control_panel.test' - - common.alarm_arm_night(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=2) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_NIGHT == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_specific_pending(self): - """Test arm home method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 10, - 'triggered': { - 'pending_time': 2 - }, - 'trigger_time': 3, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - common.alarm_trigger(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=2) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_disarm_after_trigger(self): - """Test disarm after trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 5, - 'pending_time': 0, - 'disarm_after_trigger': True - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_zero_specific_trigger_time(self): - """Test trigger method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 5, - 'disarmed': { - 'trigger_time': 0 - }, - 'pending_time': 0, - 'disarm_after_trigger': True - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_unused_zero_specific_trigger_time(self): - """Test disarm after trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 5, - 'armed_home': { - 'trigger_time': 0 - }, - 'pending_time': 0, - 'disarm_after_trigger': True - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_specific_trigger_time(self): - """Test disarm after trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'disarmed': { - 'trigger_time': 5 - }, - 'pending_time': 0, - 'disarm_after_trigger': True - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_trigger_with_no_disarm_after_trigger(self): - """Test disarm after trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 5, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - def test_back_to_back_trigger_with_no_disarm_after_trigger(self): - """Test disarm after trigger.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 5, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_AWAY == \ - self.hass.states.get(entity_id).state - - def test_disarm_while_pending_trigger(self): - """Test disarming while pending state.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'trigger_time': 5, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - common.alarm_disarm(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_disarm_during_trigger_with_invalid_code(self): - """Test disarming while code is invalid.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 5, - 'code': CODE + '2', - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_trigger(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - common.alarm_disarm(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=5) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_TRIGGERED == \ - self.hass.states.get(entity_id).state - - def test_disarm_with_template_code(self): - """Attempt to disarm with a valid or invalid template-based code.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code_template': - '{{ "" if from_state == "disarmed" else "abc" }}', - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - self.hass.start() - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_home(self.hass, 'def') - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_ARMED_HOME == state.state - - common.alarm_disarm(self.hass, 'def') - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_ARMED_HOME == state.state - - common.alarm_disarm(self.hass, 'abc') - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_DISARMED == state.state - - def test_arm_custom_bypass_no_pending(self): - """Test arm custom bypass method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 0, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_custom_bypass(self.hass, CODE) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_CUSTOM_BYPASS == \ - self.hass.states.get(entity_id).state - - def test_arm_custom_bypass_with_pending(self): - """Test arm custom bypass method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_custom_bypass(self.hass, CODE, entity_id) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - state = self.hass.states.get(entity_id) - assert state.attributes['post_pending_state'] == \ - STATE_ALARM_ARMED_CUSTOM_BYPASS - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert state.state == STATE_ALARM_ARMED_CUSTOM_BYPASS - - def test_arm_custom_bypass_with_invalid_code(self): - """Attempt to custom bypass without a valid code.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 1, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_custom_bypass(self.hass, CODE + '2') - self.hass.block_till_done() - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - def test_armed_custom_bypass_with_specific_pending(self): - """Test arm custom bypass method.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'pending_time': 10, - 'armed_custom_bypass': { - 'pending_time': 2 - } - }}) - - entity_id = 'alarm_control_panel.test' - - common.alarm_arm_custom_bypass(self.hass) - self.hass.block_till_done() - - assert STATE_ALARM_PENDING == \ - self.hass.states.get(entity_id).state - - future = dt_util.utcnow() + timedelta(seconds=2) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - assert STATE_ALARM_ARMED_CUSTOM_BYPASS == \ - self.hass.states.get(entity_id).state - - def test_arm_away_after_disabled_disarmed(self): - """Test pending state with and without zero trigger time.""" - assert setup_component( - self.hass, alarm_control_panel.DOMAIN, - {'alarm_control_panel': { - 'platform': 'manual', - 'name': 'test', - 'code': CODE, - 'pending_time': 0, - 'delay_time': 1, - 'armed_away': { - 'pending_time': 1, - }, - 'disarmed': { - 'trigger_time': 0 - }, - 'disarm_after_trigger': False - }}) - - entity_id = 'alarm_control_panel.test' - - assert STATE_ALARM_DISARMED == \ - self.hass.states.get(entity_id).state - - common.alarm_arm_away(self.hass, CODE) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_PENDING == state.state - assert STATE_ALARM_DISARMED == \ state.attributes['pre_pending_state'] - assert STATE_ALARM_ARMED_AWAY == \ + assert STATE_ALARM_TRIGGERED == \ state.attributes['post_pending_state'] - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() + future += timedelta(seconds=1) + with patch(('homeassistant.components.alarm_control_panel.manual.' + 'dt_util.utcnow'), return_value=future): + async_fire_time_changed(hass, future) + await hass.async_block_till_done() - state = self.hass.states.get(entity_id) - assert STATE_ALARM_PENDING == state.state - assert STATE_ALARM_DISARMED == \ - state.attributes['pre_pending_state'] - assert STATE_ALARM_ARMED_AWAY == \ - state.attributes['post_pending_state'] - - future = dt_util.utcnow() + timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_ARMED_AWAY == state.state - - common.alarm_trigger(self.hass, entity_id=entity_id) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_PENDING == state.state - assert STATE_ALARM_ARMED_AWAY == \ - state.attributes['pre_pending_state'] - assert STATE_ALARM_TRIGGERED == \ - state.attributes['post_pending_state'] - - future += timedelta(seconds=1) - with patch(('homeassistant.components.alarm_control_panel.manual.' - 'dt_util.utcnow'), return_value=future): - fire_time_changed(self.hass, future) - self.hass.block_till_done() - - state = self.hass.states.get(entity_id) - assert STATE_ALARM_TRIGGERED == state.state + state = hass.states.get(entity_id) + assert STATE_ALARM_TRIGGERED == state.state async def test_restore_armed_state(hass):