Now possible to set multiple states through one API call.

This commit is contained in:
Paulus Schoutsen 2013-10-05 12:28:18 -07:00
parent 645513b6ae
commit 5c5fe5051b
3 changed files with 60 additions and 10 deletions

View File

@ -35,7 +35,10 @@ The following API commands are currently supported:
parameter: category - string
parameter: new_state - string
Changes category 'category' to 'new_state'
It is possible to sent multiple values for category and new_state.
If the number of values for category and new_state do not match only
combinations where both values are supplied will be set.
/api/event/fire - POST
parameter: api_password - string
parameter: event_name - string

View File

@ -14,6 +14,9 @@ The api supports the following actions:
parameter: category - string
parameter: new_state - string
Changes category 'category' to 'new_state'
It is possible to sent multiple values for category and new_state.
If the number of values for category and new_state do not match only
combinations where both values are supplied will be set.
/api/event/fire - POST
parameter: event_name - string
@ -30,7 +33,7 @@ from urlparse import urlparse, parse_qs
import requests
from . import EVENT_START, EVENT_SHUTDOWN, Event, CategoryDoesNotExistException
from . import EVENT_START, EVENT_SHUTDOWN, Event
SERVER_PORT = 8123
@ -173,15 +176,18 @@ class RequestHandler(BaseHTTPRequestHandler):
# Action to change the state
if action == "state/change":
if self._verify_api_password(given_api_password, use_json):
category, new_state = post_data['category'][0], post_data['new_state'][0]
try:
self.server.statemachine.set_state(category, new_state)
changed = []
self._message(use_json, "State of {} changed to {}.".format(category, new_state))
for category, new_state in zip(post_data['category'], post_data['new_state']):
self.server.statemachine.set_state(category, new_state)
changed.append("{}={}".format(category, new_state))
except CategoryDoesNotExistException:
self._message(use_json, "Category does not exist.", MESSAGE_STATUS_ERROR)
self._message(use_json, "States changed: {}".format( ", ".join(changed) ) )
except KeyError:
# If category or new_state don't exist in post data
self._message(use_json, "Invalid state received.", MESSAGE_STATUS_ERROR)
# Action to fire an event
elif action == "event/fire":
@ -196,7 +202,11 @@ class RequestHandler(BaseHTTPRequestHandler):
except ValueError:
# If JSON decode error
self._message(use_json, "Invalid event received.", MESSAGE_STATUS_ERROR)
self._message(use_json, "Invalid event received (1).", MESSAGE_STATUS_ERROR)
except KeyError:
# If "event_name" not in post_data
self._message(use_json, "Invalid event received (2).", MESSAGE_STATUS_ERROR)
else:
self.send_response(404)

View File

@ -90,15 +90,32 @@ class TestHTTPInterface(HomeAssistantTestCase):
def test_api_state_change(self):
""" Test if the API allows us to change a state. """
""" Test if we can change the state of a category that exists. """
self.statemachine.set_state("test", "not_to_be_set_state")
requests.post("{}/api/state/change".format(HTTP_BASE_URL), data={"category":"test",
"new_state":"debug_state_change2",
"api_password":API_PASSWORD})
self.assertEqual(self.statemachine.get_state("test").state, "debug_state_change2")
def test_api_multiple_state_change(self):
""" Test if we can change multiple states in 1 request. """
self.statemachine.set_state("test", "not_to_be_set_state")
self.statemachine.set_state("test2", "not_to_be_set_state")
requests.post("{}/api/state/change".format(HTTP_BASE_URL), data={"category": ["test", "test2"],
"new_state": ["test_state_1", "test_state_2"],
"api_password":API_PASSWORD})
self.assertEqual(self.statemachine.get_state("test").state, "test_state_1")
self.assertEqual(self.statemachine.get_state("test2").state, "test_state_2")
def test_api_state_change_of_non_existing_category(self):
""" Test if the API allows us to change a state of a non existing category. """
req = requests.post("{}/api/state/change".format(HTTP_BASE_URL), data={"category":"test_category_that_does_not_exist",
"new_state":"debug_state_change",
"api_password":API_PASSWORD})
@ -148,6 +165,26 @@ class TestHTTPInterface(HomeAssistantTestCase):
self.assertEqual(len(test_value), 1)
def test_api_fire_event_with_no_params(self):
""" Test how the API respsonds when we specify no event attributes. """
test_value = []
def listener(event):
""" Helper method that will verify that our event got called and
that test if our data came through. """
if "test" in event.data:
test_value.append(1)
self.eventbus.listen("test_event_with_data", listener)
requests.post("{}/api/event/fire".format(HTTP_BASE_URL), data={"api_password":API_PASSWORD})
# Allow the event to take place
time.sleep(1)
self.assertEqual(len(test_value), 0)
def test_api_fire_event_with_invalid_json(self):
""" Test if the API allows us to fire an event. """
test_value = []