Google plus sing-in API

Maintenant que je connais les bases de Flask je peux continuer mon test de l’API Google Plus.

La documentation la plus a jour est disponible ICI : https://developers.google.com/+/ et je vous conseil aussi de jeter un œil au tutorial disponible ICI : http://www.googleplusdaily.com/2013/03/add-google-sign-in-in-6-easy-steps.html

J’ai réalisé un site web minimaliste en utilisant Jquery Mobile et Flask. Le site offre la possibilité de se logger avec son compte Google grâce a la méthode de sign in de Google plus.

Création du client ID

Pour pouvoir utiliser les services de google il faut déclarer notre projet dans la console disponible a l’adresse suivante :

https://console.developers.google.com/project

Il faut ensuite créer un nouveau projet (ou utiliser un de vos projets existants). Il faut ensuite activer l API Google + pour ce projet en cliquant sur API.

GoogleApiOn

Il faut enfin créer une clé d’identification pour utiliser l’API. Pour cela on clique sur le sous menu “credentials” situe en dessous du menu API.

GoogleApiCle

 Site web

Le site est très simple et repose sur l’utilisation de Flask (voir mon article précédant). L’utilisation de l’API google est assez bien documente (voir liens au début de l’article) et je ne vais pas répéter toutes les étapes.

L’ensemble du code est disponible sur bitbucket ICI :
https://bitbucket.org/charly37/googlesign/overview

Il suffit de remplacer le client ID présent dans le code par celui crée dans l’étape précédente :

class="g-signin"
data-callback="signinCallback"
data-clientid="67694002414-idd640ukscsntd4nmn80gg66i6sirup1.apps.googleusercontent.com"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/plus.login">

Le résultat :

GoogleSignInApiLogin

A la fin du logging le site affichera le nom de l’utilisateur :

GoogleApiResult

Voila 😉

 

Reconnaissance vocale

Création d’une application android pour le système de domotique qui sera capable de reconnaitre la parole pour actionner certaines actions. Le but est de remplacer “Tasker + auto voice” par une application fait maison et plus plus adapte au système.

on utilise l API google et c est google qui fait tout le boulot de décodage de la parole (et plutôt bien) :

public void speak(View view) {
 Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// Specify the calling package to identify your application
 intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
// Given an hint to the recognizer about what the user is going to say
 //There are two form of language model available
 //1.LANGUAGE_MODEL_WEB_SEARCH : For short phrases
 //2.LANGUAGE_MODEL_FREE_FORM  : If not sure about the words or phrases and its domain.
 intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
// Specify how many results you want to receive. The results will be sorted where the first result is the one with higher confidence.
 int noOfMatches = 4;
 intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, noOfMatches);
 //Start the Voice recognizer activity for the result.
 startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
 }

et on attend la réponse de l’activité :

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 if (requestCode == VOICE_RECOGNITION_REQUEST_CODE)
//If Voice recognition is successful then it returns RESULT_OK
 if(resultCode == RESULT_OK) {
ArrayList<java.lang.String> textMatchList = data
 .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
if (!textMatchList.isEmpty()) {
 mlvTextMatches
 .setAdapter(new ArrayAdapter<java.lang.String>(this,
 android.R.layout.simple_list_item_1,
 textMatchList));
 sendMsgToServer(textMatchList);
}

ensuite avec les résultats (plusieurs phrases correspondant a ce que google a décoder) on appel une fonction “sendMsgToServer” qui va envoyer ses phrases aux serveur python qui gère tout la centrale domotique.

public void sendMsgToServer(ArrayList<java.lang.String> aStrings){
String url = "http://192.168.0.6/Sender/XbeeWrapper.php?iCmdType=CMD_SPEAK&iCmdStrings=";
 String aCmd = combine(aStrings,"_");
 url = url + aCmd;
 url = url.replace(' ','-');
 url = Normalizer.normalize(url, Normalizer.Form.NFD);
 url = url.replaceAll("[^\\p{ASCII}]", "");
 grabURL(url);
 }

Attention : pour faire cela on utilise une autre classe qui dérive de classe asynch car dans android toutes les opérations longues doivent être faites ailleurs que dans le thread principale.

private class GrabURL extends AsyncTask<String, Void, Void> {

je vais pas détailler ici pkoi et comment car il existe une multitude de référence sur le sujet sur internet. Bref le serveur python reçoit les phrases et parcours tous les objets du réseaux domotique pour savoir auquel est destine la commande :

def TranslateVocalAction(self,Sentences, Devices):
 logging.warning("Translate : " + str(Sentences))
 #Weight, Device ID, CommandID
 aBestDeviceMatch=(0,0,0)
 for aOneObj in Devices.registeredDevices:
 (aWeight,aCmdId)=aOneObj.getDeviceWeightSpeech(Sentences)
 logging.warning ("DeviceId : " + str(aOneObj.id) + " has weight : " + str(aWeight))
 if(aWeight > aBestDeviceMatch[0]):
 aBestDeviceMatch=(aWeight,aOneObj.id,aCmdId)
 logging.warning("Device is : " + str(aBestDeviceMatch))
 self.SendMessage( str(aBestDeviceMatch[2]),"VoiceAction",Devices)
 return (Devices.getDevice(aBestDeviceMatch[1]).description,aBestDeviceMatch[2])

Pour cela il parcours la description et les commandes possible de tous les objets qui se présentes sous la forme :

VoletSalon = InterupteurMultiStable()
 VoletSalon.id =5
 VoletSalon.description="volets salon"
 VoletSalon.InPossibleCmd ={ "10" : "off fermer ferme","9" : "on ouvre ouvrir","25" : "stop arreter arrete"}
 VoletSalon.InActionsCommands={ "9" : "self.turnOn(9)","10" : "self.turnOff(10)","25" : "self.turnOff(10)"}
 self.registeredDevices.append(VoletSalon)
LumiereSalonHalogene = InterupteurBiStable()
 LumiereSalonHalogene.id =6
 LumiereSalonHalogene.description="lumiere halogene salon"
 LumiereSalonHalogene.InPossibleCmd ={ "13" : "off eteint eteindre","14" : "on allume allumer"}
 LumiereSalonHalogene.InActionsCommands={ "13" : "self.turnOff(13)","14" : "self.turnOn(14)"}
 self.registeredDevices.append(LumiereSalonHalogene)
....

et donne un poids pour chaque objet en fonction de sa description et de ses possibles commandes. Le poids dépend du nombre de mots commun entre les strings et les mots présent dans la phrase (pondéré par leur longueur)

Ensuite il exécute la commande qui a le poids le plus grand. C’est assez facile en fin de compte. En parallèle le serveur python renvoi la commande exécuté et l’objet associe :

return (Devices.getDevice(aBestDeviceMatch[1]).description,aBestDeviceMatch[2])

Ces infos sont ensuite affiches sur la UI du telephonne portable pour que l utilisateur puisse vérifier :

protected void onPostExecute(Void unused) {
 Dialog.dismiss();
 if (Error != null) {
 Toast.makeText(VoiceRecognitionActivity.this, Error, Toast.LENGTH_LONG).show();
 } else {
 Toast.makeText(VoiceRecognitionActivity.this, "Source: " + Content, Toast.LENGTH_LONG).show();
 }
 }

Je ne détaille pas bcp plus car tous le code est tjs visible au même endroit sur le dépôt central de mon projet domotique et assez court pour être compris facilement.

Je ferais une vidéo du système en action ASAP.