API Call Service returns states changed

This commit is contained in:
Paulus Schoutsen 2014-12-14 00:35:16 -08:00
parent b091e9c31c
commit 5e8673fc4a
7 changed files with 72 additions and 43 deletions

View File

@ -370,13 +370,29 @@ optional body: JSON encoded object that represents event_data
``` ```
**/api/services/&lt;domain>/&lt;service>** - POST<br> **/api/services/&lt;domain>/&lt;service>** - POST<br>
Calls a service within a specific domain.<br> Calls a service within a specific domain. Will return when the service has been executed or 10 seconds has past, whichever comes first.<br>
optional body: JSON encoded object that represents service_data optional body: JSON encoded object that represents service_data
Returns a list of states that have changed since the start of this service call.
```json ```json
{ [
"message": "Service keyboard/volume_up called." {
} "attributes": {
"next_rising": "07:04:15 29-10-2013",
"next_setting": "18:00:31 29-10-2013"
},
"entity_id": "sun.sun",
"last_changed": "23:24:33 28-10-2013",
"state": "below_horizon"
},
{
"attributes": {},
"entity_id": "process.Dropbox",
"last_changed": "23:24:33 28-10-2013",
"state": "on"
}
]
``` ```
**/api/event_forwarding** - POST<br> **/api/event_forwarding** - POST<br>

View File

@ -96,7 +96,7 @@ def setup(hass, config):
# ent_ids is a generator, convert it to a list. # ent_ids is a generator, convert it to a list.
data[ATTR_ENTITY_ID] = list(ent_ids) data[ATTR_ENTITY_ID] = list(ent_ids)
hass.services.call(domain, service.service, data) hass.services.call(domain, service.service, data, True)
hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, handle_turn_service) hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, handle_turn_service)
hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, handle_turn_service) hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, handle_turn_service)

View File

@ -86,7 +86,7 @@ import homeassistant as ha
from homeassistant.const import ( from homeassistant.const import (
SERVER_PORT, URL_API, URL_API_STATES, URL_API_EVENTS, URL_API_SERVICES, SERVER_PORT, URL_API, URL_API_STATES, URL_API_EVENTS, URL_API_SERVICES,
URL_API_EVENT_FORWARD, URL_API_STATES_ENTITY, AUTH_HEADER) URL_API_EVENT_FORWARD, URL_API_STATES_ENTITY, AUTH_HEADER)
from homeassistant.helpers import validate_config from homeassistant.helpers import validate_config, TrackStates
import homeassistant.remote as rem import homeassistant.remote as rem
import homeassistant.util as util import homeassistant.util as util
from . import frontend from . import frontend
@ -484,9 +484,10 @@ class RequestHandler(SimpleHTTPRequestHandler):
domain = path_match.group('domain') domain = path_match.group('domain')
service = path_match.group('service') service = path_match.group('service')
self.server.hass.services.call(domain, service, data, True) with TrackStates(self.server.hass) as changed_states:
self.server.hass.services.call(domain, service, data, True)
self._json_message("Service {}/{} called.".format(domain, service)) self._write_json(changed_states)
# pylint: disable=invalid-name # pylint: disable=invalid-name
def _handle_post_api_event_forward(self, path_match, data): def _handle_post_api_event_forward(self, path_match, data):

View File

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """ """ DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "5c3b2dd8a63197e380e798da8b057b0a" VERSION = "dc16db6d5f4ba9f6dbf9d88f65592184"

File diff suppressed because one or more lines are too long

View File

@ -139,6 +139,12 @@
this.fire('states-updated'); this.fire('states-updated');
}, },
_pushNewStates: function(new_states) {
new_states.map(function(state) {
this._pushNewState(state);
}.bind(this));
},
// call api methods // call api methods
fetchAll: function() { fetchAll: function() {
this.fetchStates(); this.fetchStates();
@ -205,19 +211,14 @@
"GET", "services", null, successServicesUpdated.bind(this), onError); "GET", "services", null, successServicesUpdated.bind(this), onError);
}, },
turn_on: function(entity_id) { turn_on: function(entity_id, options) {
// we call the turn_on method on the domain of the entity_id this.call_service(
// because the call to homeassistant.turn_on does not wait "homeassistant", "turn_on", {entity_id: entity_id}, options);
// till the call is done.
var parts = entity_id.split(".");
this.call_service(parts[0], "turn_on", {entity_id: entity_id});
}, },
turn_off: function(entity_id) { turn_off: function(entity_id, options) {
var parts = entity_id.split("."); this.call_service(
"homeassistant", "turn_off", {entity_id: entity_id}, options);
this.call_service(parts[0], "turn_off", {entity_id: entity_id});
}, },
set_state: function(entity_id, state, attributes) { set_state: function(entity_id, state, attributes) {
@ -236,10 +237,11 @@
payload, successToast.bind(this)); payload, successToast.bind(this));
}, },
call_service: function(domain, service, parameters) { call_service: function(domain, service, parameters, options) {
parameters = parameters || {}; parameters = parameters || {};
options = options || {};
var successToast = function() { var successHandler = function(changed_states) {
if(service == "turn_on" && parameters.entity_id) { if(service == "turn_on" && parameters.entity_id) {
this.showToast("Turned on " + parameters.entity_id + '.'); this.showToast("Turned on " + parameters.entity_id + '.');
} else if(service == "turn_off" && parameters.entity_id) { } else if(service == "turn_off" && parameters.entity_id) {
@ -248,14 +250,21 @@
this.showToast("Service "+domain+"/"+service+" called."); this.showToast("Service "+domain+"/"+service+" called.");
} }
// if we call a service on an entity_id, update the state this._pushNewStates(changed_states);
if(parameters && parameters.entity_id) {
this.fetchStates(); if(options.success) {
options.success();
}
};
var errorHandler = function(error_data) {
if(options.error) {
options.error(error_data);
} }
}; };
this.call_api("POST", "services/" + domain + "/" + service, this.call_api("POST", "services/" + domain + "/" + service,
parameters, successToast.bind(this)); parameters, successHandler.bind(this), errorHandler);
}, },
fire_event: function(eventType, eventData) { fire_event: function(eventType, eventData) {

View File

@ -139,31 +139,34 @@
}, },
stateChanged: function(oldVal, newVal) { stateChanged: function(oldVal, newVal) {
this.stateUnknown = newVal === null;
this.toggleChecked = newVal === "on"; this.toggleChecked = newVal === "on";
}, },
turn_on: function() { turn_on: function() {
// We call stateChanged after a successful call to re-sync the toggle
// with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic.
if(this.cb_turn_on) { if(this.cb_turn_on) {
this.cb_turn_on(this.stateObj.entity_id); this.cb_turn_on(this.stateObj.entity_id, {
success: function() {
// unset state while we wait for an update this.stateChanged(this.stateObj.state, this.stateObj.state);
var delayUnsetSate = function() { }.bind(this)
this.stateObj.state = null; });
};
setTimeout(delayUnsetSate.bind(this), 500);
} }
}, },
turn_off: function() { turn_off: function() {
// We call stateChanged after a successful call to re-sync the toggle
// with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic.
if(this.cb_turn_off) { if(this.cb_turn_off) {
this.cb_turn_off(this.stateObj.entity_id); this.cb_turn_off(this.stateObj.entity_id, {
success: function() {
// unset state while we wait for an update this.stateChanged(this.stateObj.state, this.stateObj.state);
var delayUnsetSate = function() { }.bind(this)
this.stateObj.state = null; });
};
setTimeout(delayUnsetSate.bind(this), 500);
} }
}, },