JavaScript API - JpEncausse/SARAH-Documentation GitHub Wiki
The official documentation has been moved to http://wiki.sarah.encausse.net/
.
.
.
.
.
.
.
.
SARAH is a bridge between all server side features. This singleton provides function wrapping HTTP client request. And advanced feature for plugins.
Note: as SARAH uses a NodeJS you can call the NodeJS API into your JavaScript files.
Plugins Functions
List of available functions to control plugins life cycle.
| NodeJS | Description |
|---|---|
| SARAH.run() | Run script with given data |
| SARAH.call() | Like run without rule dispatch |
| SARAH.last() | Run latest script again (v2.8) |
| SARAH.exists() | Check if module/phantom exists (v2.8) |
| SARAH.remote() | Run client remote commande (play, pause, …) |
To run a plugin like an HTTP request:
// Run eedomus plugin with some parameters
SARAH.run('eedomus', { 'periphId' : id , 'periphValue' : value });
// Call eedomus plugin without forwarding result to Rule Engine
SARAH.call('eedomus', { 'periphId' : LUMENS}, function(options){ /* do next stuff */ });
# HTTP Functions
List of available function sending an HTTP Request to Client. Request are sent using SARAH.remote()
See also: Client HTTP Server
| NodeJS | Request | Description |
|---|---|---|
| SARAH.answer() | Call SARAH.speak() with predefined answers | |
| SARAH.speak() | tts=...&sync=... | Trigger Text to Speech (can be sync or async) |
| SARAH.shutUp() | notts=... | Stop speaking |
| SARAH.play() | play=...&sync=... | File.mp3 to play |
| SARAH.pause() | pause=... | File.mp3 to stop |
| SARAH.keyText() | keyText=... | Text to type |
| SARAH.runApp() | run=...&runp=... | Application path to run and parameters |
| SARAH.activate() | activate=... | Application to put foreground |
| SARAH.face() | face=... | start/stop face recognition |
| SARAH.gesture() | gesture=... | start/stop gesture recognition |
| below the requests only | ||
| picture=... | Take a picture, store it and return in response (only main Sensor) | |
| height=... | Return user height based on it's forearm (value tts to speech) | |
| keyUp=... | Key to press | |
| keyDown=... | Key to press | |
| keyPress=... | Key to press | |
| keyMod=... | Key modifier | |
| status=... | returns "speaking" if SARAH is currently speaking | |
| recognize=... | Perform speech recognition on given audio path or upload | |
| listen=... | Start / Stop listening | |
| context=... | Activate context grammar |
JSDocs
SARAH.exists(module)
Parameters
- {String} module : check if a module/phantom is available
Return
If the module is available the function will return true, or false if it's not available.
Comments
From SARAH v2.8.
Example: if you have the plugin "freebox" you can test SARAH.exists("freebox").
SARAH.answer()
Parameters
- No parameter
Comments
The function will randomly take one sentence from the custom.prop. You can change the default sentences via the web interface of SARAH: in the "A propos" widget, just click on the "Config." button. Each answers must be seperated with a pipe (|).
The default answers are Oui|Je m'en occupe|Voilà|C'est fait. So when you call SARAH.answer() the program will say "Oui", or "Voilà", or "Je m'en occupe". The answer is randomly chosen.
SARAH.speak(sentence, [callback])
Parameters
- {String} Sentence : this is the sentence that SARAH will say
- {Function} [callback] : (optional) this is a callback function that will be called when the sentence has been said
Comments
The call is synchronous if you don't use a second parameter. Examples:
SARAH.speak("Hello");
SARAH.speak("world");
SARAH.speak("I'm Sarah");
Then it will send 3 HTTP requests and only 1 will be said by SARAH. It's because the TTS requests are ignored when SARAH is currently speaking.
From SARAH V3.0 it's possible to change this behavior with cascading calls (=asynchronous):
SARAH.speak("Hello", function(){
SARAH.speak("world", function(){
SARAH.speak("I'm Sarah", function(){
// ...
})
})
})
It's still possible to use SARAH.shutUp() at any time to stop SARAH for speaking.
Note - you can check the status of SARAH in sending the request http://127.0.0.1:8888/?status=true : if it returns speaking then it means SARAH is current speaking, otherwise it returns nothing.
SARAH.play(file/url, [callback])
Parameters
- {String} file : relative path to a MP3 or WAV file (e.g.
media/song.mp3), or a web URL (e.g.http://www.site.com/file.mp3) - {Function} [callback] : (optional) this is a callback function that will be called when the audio has been played
Comments
This function will play a sound file. The sounds can be parallelized. However there is a timeout after 8 minutes (from SARAH v3.1, or 2 minutes for SARAH < v3.1) that will automatically stop the playing.
Regarding the WAV file, it must be a 88 kb/s encoded file (the 64 kb/s won't work).
SARAH.pause(file)
Parameters
- {String} file : relative path to a MP3 or WAV file (e.g.
media/song.mp3), or a web URL (e.g.http://www.site.com/file.mp3)
Comments
This function will stop/pause a sound that is currently playing.
The file parameter must be the same used for SARAH.play().
SARAH.runApp({run, [runp]})
Parameters
- {Object} the options
- {String} run : the path to the program to execute
- {String} [runp] : use this one to pass some parameters to the program
Comments
This function call the C# function Process.Start(processName, param). Windows' rule: never use space or custom chars in path.
If you want to launch/run an executable program on client side:
// Lauching XBMC
SARAH.runApp('E:\\XBMC12\\XBMC.exe');
// Lauching Spotify with a song
SARAH.runApp('C:\\Program Files (x86)\\Spotify\\spotify.exe', '"spotify:track:6ilfuI7O1vUfKf4TQ9fJRb"');
If you want to launch/run an executable program on server side:
exports.action = function(data, callback, config, SARAH) {
// see http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
var exec = require('child_process').exec;
// note: below we use double quotes inside (") the simple quotes (')
// because we have some blank spaces in the path
// for a relative path to SARAH you can use %CD%
// example: var process = '%CD%\\\\plugins\\\\myplugin\\\\bin\\\\xbmc.bat';
var process = '"C:\\\\Program Files (x86)\\\\XBMC\\\\XBMC.exe"';
var child = exec(process, function (error, stdout, stderr) {
if (error !== null) console.log('exec error: ' + error);
});
callback({'tts': "Je lance XBMC."});
}
Advanced features
SARAH also provides advanced features throught it's API to handle Context, Profile, Events, ...
Context
Plugins can share contextual data for other plugins using SARAH.context. For instance the XBMC plugin store data in SARAH.context.xbmc.
If you want to use it with your plugin, then make sure to use the syntax: SARAH.context.yourPluginName (yourPluginName is the name of the folder used by your plugin) to avoid any conflicts.
Because the data are only stored in memory (it means they are deleted after a restart of SARAH) you can use the below function to setup your context:
exports.init = function(SARAH) {
SARAH.context.myPluginName = {"someVariable": "someValue"}
}
Profile
Client's send and up to date profile of currents users in the context:
SARAH.context.profile =
[
{ Timestamp: "2013-11-10T14:00:11.1205204+01:00",
Name: "Jean_Philippe", Pitch: 153.28974723815918,
x: 0, y: 0, z: 0,
Mood: 0, Height: 0
},
{ Timestamp: "2013-10-18T22:29:21.843015+02:00",
Name: "Aurelie", Pitch: 0,
x: 0, y: 0, z: 0,
Mood: 0, Height: 0
}
]
Event
A plugin can comunicate with other plugin using EventEmiter API. Plugins should listen to event in their init() function.
On a side must listen to events (like XBMC):
exports.init = function(SARAH){
SARAH.listen('xbmc', function(data){
// your code here
});
}
On the other side XBMC will do:
SARAH.trigger('xbmc', { key : value, x : 1, y : 2 });
Note: An other way to do this without code is to use RuleEngine IF xbmc THEN DO YourPlugin. XBMC must still put convenient data in callback({}).
AskMe
A plugin can ask a question to user then be called back using following function:
SARAH.askme(tts, grammar, timeout, callback);
| Argument | Description |
|---|---|
| tts | The text to speech |
| grammar | key/value grammar choice |
| timeout | timeout (if > 0 ask twice) |
| callback | function to call with answer |
- A dynamic grammar is set on client side
- The grammar is exclusif (a context is set)
- After the given timeout, the question is ask again
- If there is no answer after
timeout x 2or 8s the callback is called withfalse - AskMe call are stacked and buffered !
Example: Plugin 1
SARAH.askme("What is your favorite color", {
"My color is bleu" : 'blue',
"My favorite color is blue no red" : 'red'
}, 10000, function(answer, end){ // the selected answer or false
SARAH.speak('You said: ' + answer, function(){
end(); // MUST be called when job done
});
});
Concurrent Plugin 2
If Plugin 2 ask something at the same time, it will stack and wait.
SARAH.askme("What is your favorite sound", {
"I feel good" : 'feelggod',
"Highway to hell" : 'ACDC'
}, 10000, function(answer, end){
SARAH.call('xbmc', { 'song' : answer }, function(options){ end(); }); // Again a callback to wait
});
Chromeless
A plugin can display a webpage, on server side using Chromeless browser using folowing function:
SARAH.chromeless(url, o, w, h, x, y)
| Argument | Description |
|---|---|
| url | URL to display |
| o | Browser's opacity |
| w | Browser's width |
| h | Browser's height |
| x | Browser's x |
| y | Browser's y |
Example
SARAH.chromeless('http://www.google.com', 80);

see also : Plugin's third party page