Allow removing a state via API + remote StateMachine
parent
ada2fb4ec0
commit
06de73ff80
|
@ -63,6 +63,9 @@ def setup(hass, config):
|
|||
hass.http.register_path(
|
||||
'PUT', re.compile(r'/api/states/(?P<entity_id>[a-zA-Z\._0-9]+)'),
|
||||
_handle_post_state_entity)
|
||||
hass.http.register_path(
|
||||
'DELETE', re.compile(r'/api/states/(?P<entity_id>[a-zA-Z\._0-9]+)'),
|
||||
_handle_delete_state_entity)
|
||||
|
||||
# /events
|
||||
hass.http.register_path('GET', URL_API_EVENTS, _handle_get_api_events)
|
||||
|
@ -240,6 +243,22 @@ def _handle_post_state_entity(handler, path_match, data):
|
|||
location=URL_API_STATES_ENTITY.format(entity_id))
|
||||
|
||||
|
||||
def _handle_delete_state_entity(handler, path_match, data):
|
||||
"""Handle request to delete an entity from state machine.
|
||||
|
||||
This handles the following paths:
|
||||
/api/states/<entity_id>
|
||||
"""
|
||||
entity_id = path_match.group('entity_id')
|
||||
|
||||
if handler.server.hass.states.remove(entity_id):
|
||||
handler.write_json_message(
|
||||
"Entity not found", HTTP_NOT_FOUND)
|
||||
else:
|
||||
handler.write_json_message(
|
||||
"Entity removed", HTTP_OK)
|
||||
|
||||
|
||||
def _handle_get_api_events(handler, path_match, data):
|
||||
""" Handles getting overview of event listeners. """
|
||||
handler.write_json(_events_json(handler.server.hass))
|
||||
|
@ -258,6 +277,7 @@ def _handle_api_post_events_event(handler, path_match, event_data):
|
|||
if event_data is not None and not isinstance(event_data, dict):
|
||||
handler.write_json_message(
|
||||
"event_data should be an object", HTTP_UNPROCESSABLE_ENTITY)
|
||||
return
|
||||
|
||||
event_origin = ha.EventOrigin.remote
|
||||
|
||||
|
|
|
@ -247,6 +247,13 @@ class StateMachine(ha.StateMachine):
|
|||
|
||||
bus.listen(ha.EVENT_STATE_CHANGED, self._state_changed_listener)
|
||||
|
||||
def remove(self, entity_id):
|
||||
"""Remove the state of an entity.
|
||||
|
||||
Returns boolean to indicate if an entity was removed.
|
||||
"""
|
||||
return remove_state(self._api, entity_id)
|
||||
|
||||
def set(self, entity_id, new_state, attributes=None):
|
||||
""" Calls set_state on remote API . """
|
||||
set_state(self._api, entity_id, new_state, attributes)
|
||||
|
@ -258,7 +265,10 @@ class StateMachine(ha.StateMachine):
|
|||
|
||||
def _state_changed_listener(self, event):
|
||||
""" Listens for state changed events and applies them. """
|
||||
self._states[event.data['entity_id']] = event.data['new_state']
|
||||
if event.data['new_state'] is None:
|
||||
self._states.pop(event.data['entity_id'], None)
|
||||
else:
|
||||
self._states[event.data['entity_id']] = event.data['new_state']
|
||||
|
||||
|
||||
class JSONEncoder(json.JSONEncoder):
|
||||
|
@ -415,6 +425,26 @@ def get_states(api):
|
|||
return []
|
||||
|
||||
|
||||
def remove_state(api, entity_id):
|
||||
"""Call API to remove state for entity_id.
|
||||
|
||||
Returns True if entity is gone (removed/never existed).
|
||||
"""
|
||||
try:
|
||||
req = api(METHOD_DELETE, URL_API_STATES_ENTITY.format(entity_id))
|
||||
|
||||
if req.status_code in (200, 404):
|
||||
return True
|
||||
|
||||
_LOGGER.error("Error removing state: %d - %s",
|
||||
req.status_code, req.text)
|
||||
return False
|
||||
except HomeAssistantError:
|
||||
_LOGGER.exception("Error removing state")
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def set_state(api, entity_id, new_state, attributes=None):
|
||||
"""
|
||||
Tells API to update state for entity_id.
|
||||
|
|
|
@ -135,9 +135,17 @@ class TestRemoteMethods(unittest.TestCase):
|
|||
self.assertEqual(hass.states.all(), remote.get_states(master_api))
|
||||
self.assertEqual([], remote.get_states(broken_api))
|
||||
|
||||
def test_remove_state(self):
|
||||
""" Test Python API set_state. """
|
||||
hass.states.set('test.remove_state', 'set_test')
|
||||
|
||||
self.assertIn('test.remove_state', hass.states.entity_ids())
|
||||
remote.remove_state(master_api, 'test.remove_state')
|
||||
self.assertNotIn('test.remove_state', hass.states.entity_ids())
|
||||
|
||||
def test_set_state(self):
|
||||
""" Test Python API set_state. """
|
||||
hass.states.set('test.test', 'set_test')
|
||||
remote.set_state(master_api, 'test.test', 'set_test')
|
||||
|
||||
state = hass.states.get('test.test')
|
||||
|
||||
|
@ -225,6 +233,29 @@ class TestRemoteClasses(unittest.TestCase):
|
|||
self.assertEqual("remote.statemachine test",
|
||||
slave.states.get("remote.test").state)
|
||||
|
||||
def test_statemachine_remove_from_master(self):
|
||||
hass.states.set("remote.master_remove", "remove me!")
|
||||
hass.pool.block_till_done()
|
||||
|
||||
self.assertIn('remote.master_remove', slave.states.entity_ids())
|
||||
|
||||
hass.states.remove("remote.master_remove")
|
||||
hass.pool.block_till_done()
|
||||
|
||||
self.assertNotIn('remote.master_remove', slave.states.entity_ids())
|
||||
|
||||
def test_statemachine_remove_from_slave(self):
|
||||
hass.states.set("remote.slave_remove", "remove me!")
|
||||
hass.pool.block_till_done()
|
||||
|
||||
self.assertIn('remote.slave_remove', slave.states.entity_ids())
|
||||
|
||||
self.assertTrue(slave.states.remove("remote.slave_remove"))
|
||||
slave.pool.block_till_done()
|
||||
hass.pool.block_till_done()
|
||||
|
||||
self.assertNotIn('remote.slave_remove', slave.states.entity_ids())
|
||||
|
||||
def test_eventbus_fire(self):
|
||||
""" Test if events fired from the eventbus get fired. """
|
||||
test_value = []
|
||||
|
|
Loading…
Reference in New Issue