Pierre-Gilles Leymarie
17 Septembre 2019
Orléans Tech
Un assistant intelligent open-source pour la maison connectée
🌐 Contrôle à distance
🔐 Chiffré de bout en bout
💳 9.99€/mois pour toute la famille
const { NlpManager } = require('node-nlp');
const manager = new NlpManager({ languages: ['fr'] });
// turn on
manager.addDocument('fr', 'Allume la lumière', 'light.turnon');
manager.addDocument('fr', 'Je veux plus de lumière', 'light.turnon');
manager.addDocument('fr', 'Il fait sombre', 'light.turnon');
// turn off
manager.addDocument('fr', 'Eteins la lumière', 'light.turnoff');
// Train also the NLG
manager.addAnswer('fr', 'light.turnon', 'Lumière allumée !');
manager.addAnswer('fr', 'light.turnoff', 'Lumière éteinte !');
// Train and save the model.
(async() => {
await manager.train();
manager.save();
const response = await manager.process('fr', 'Allume lumière');
console.log(response); // light.turnon
})();
{ utterance: 'Allume lumière',
locale: 'fr',
languageGuessed: false,
localeIso2: 'fr',
language: 'French',
domain: 'default',
classifications:
[ { label: 'light.turnon', value: 1 },
{ label: 'light.turnoff', value: 0 } ],
intent: 'light.turnon',
score: 1,
entities: [],
sentiment:
{ score: 0,
comparative: 0,
vote: 'neutral',
numWords: 2,
numHits: 0,
type: 'pattern',
language: 'fr' },
srcAnswer: 'Lumière allumée !',
answer: 'Lumière allumée !' }
const manager = new NlpManager({ languages: ['fr'] });
const fromEntity = manager.addTrimEntity('room');
fromEntity.addAfterLastCondition('fr', 'du');
manager.slotManager.addSlot('light.turnon', 'room', true, {
fr: 'Quelle pièce dois-je allumer ?'
});
manager.addDocument(
'fr',
'Allume la lumière du %room%',
'light.turnon'
);
await manager.train();
const result = await manager.process('fr', 'Allume la lumière', {});
console.log(result);
{
"utterance": "Allume la lumière",
"locale": "fr",
"languageGuessed": false,
"localeIso2": "fr",
"language": "French",
"domain": "default",
"classifications": [
{
"label": "light.turnon",
"value": 1
}
],
"intent": "light.turnon",
"score": 1,
"entities": [],
"sentiment": {
"score": 0,
"comparative": 0,
"vote": "neutral",
"numWords": 3,
"numHits": 0,
"type": "pattern",
"language": "fr"
},
"slotFill": {
"localeIso2": "fr",
"intent": "light.turnon",
"entities": [],
"currentSlot": "room"
},
"srcAnswer": "Quelle pièce dois-je allumer ?",
"answer": "Quelle pièce dois-je allumer ?"
}
{
"start": 13,
"end": 18,
"len": 6,
"accuracy": 0.95,
"sourceText": "demain",
"utteranceText": "demain",
"entity": "date",
"resolution": {
"type": "date",
"timex": "2019-09-17",
"strValue": "2019-09-17",
"date": "2019-09-17T00:00:00.000Z"
}
},
{
"start": 22,
"end": 23,
"len": 2,
"accuracy": 0.95,
"sourceText": "8h",
"utteranceText": "8h",
"entity": "time",
"resolution": {
"values": [
{
"timex": "T08",
"type": "time",
"value": "08:00:00"
},
{
"timex": "T20",
"type": "time",
"value": "20:00:00"
}
]
}
}
"Demain"
"8h"
{
"score": -0.45,
"comparative": -0.1125,
"vote": "negative",
"numWords": 4,
"numHits": 2,
"type": "pattern",
"language": "fr"
}
Accès à distance, chiffré de bout en bout
const key = await window.crypto.subtle.generateKey({
name: 'RSA-OAEP',
modulusLength: 2048, // can be 1024, 2048, or 4096
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: 'SHA-256'},
},
false, // key is extractable?
['encrypt', 'decrypt']
);
// returns a keypair object
console.log(key);
console.log(key.publicKey);
console.log(key.privateKey);
const data = 'Je suis Iron Man';
const encrypted = await window.crypto.subtle.encrypt({
name: 'RSA-OAEP',
},
publicKey, // public key of the recipient
str2ab(data) //ArrayBuffer of data you want to encrypt
);
console.log(encrypted);
const decrypted = await window.crypto.subtle.decrypt({
name: 'RSA-OAEP',
},
privateKey, //Private key of the recipient
encrypted // ArrayBuffer of the data
);
// Affiche "Je suis Iron Man"
console.log(ab2str(decrypted));
const WebCrypto = require('node-webcrypto-ossl');
Il y a un Polyfill !
gladysassistant.com
Twitter: @pierregillesl, @gladysassistant