keolis-services
Version:
Keolis services includes Microphone, Location, Voice Activity Detector, Heart rate through web bluetooth API, text to speech, stop watch with our own cloud.
447 lines (364 loc) ⢠14 kB
JavaScript
const KeolisServices = (function (window, _) {
var api_url="https://localhost:44311";
const KeolisServices = {};
KeolisServices.init = function(initData) {
var settings = {
"url": api_url + "/api/TokenAuth/Auth",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json"
},
"data": JSON.stringify({
"apiKey": initData.apiKey,
"apiSecret": initData.apiSecret,
"tenantName": initData.tenantName
}),
};
$.ajax(settings).done(function (response) {
var Token = response.result.accessToken;
var settings2 = {
"url": api_url + "/api/services/app/State/GetUserPreferences?userID="+initData.userId,
"method": "GET",
"timeout": 0,
"headers": {
"Content-Type": "application/json",
"Authorization":"Bearer "+ Token
},"error": function (xhr, ajaxOptions, thrownError) {
alert("error occurred while trying to log you in");
}
}
$.ajax(settings2).done(function (response) {
if(response.result != null){
}
localStorage.setItem("logged_in_user", initData.userId);
//localStorage.setItem("logged_in_tenant",response.result.tenant_id);
localStorage.setItem("user_recurring",response.result.recurring_user);
localStorage.setItem("user_basalBpm",response.result.basal_bpm);
localStorage.setItem("user_userProfile",response.result.user_profile);
});
});
}
//------- global variables
let hrData = new Array(200).fill(10)
let RealtimeHeartRate =0;
var latitude = "";
var longitude = "";
var currentSpeed=0;
var mediaRecorder;
var uncertaintyDetected=0;
var isRecording=false;
var isTalking=false;
var isUploading=false;
var PassiveModeOn=false;
//webkitURL is deprecated but nevertheless
URL = window.URL || window.webkitURL;
var gumStream; //stream from getUserMedia()
var rec; //Recorder.js object
var input; //MediaStreamAudioSourceNode we'll be recording
var IsVoiceActivated =false;
var VoiceActivationTimeout;
// shim for AudioContext when it's not avb.
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext //audio context to help us record
let artyom = new Artyom();
// Or add multiple commands at time
var myGroup = [
{
//smart:true,
indexes:["hi","hey","hello","I hate this song","I love this song","i love this","i hate this"],
action:function(i){ // var i returns the index of the recognized command in the previous array
debugger;
if(i <= 2){
IsVoiceActivated=true;
clearInterval(VoiceActivationTimeout);
//artyom.say("I can hear you now !");
$(".tabToRecord").hide();
startRecording();
VoiceActivationTimeout = setTimeout(() => {
IsVoiceActivated=false;
$(".tabToRecord").show();
//artyom.say("you didn't say anything.");
stopRecording();
}, 7000);
startContinuousArtyom();
}else{
if(IsVoiceActivated){
IsVoiceActivated=false;
$(".tabToRecord").show();
clearInterval(VoiceActivationTimeout);
stopRecording();
}
}
}
}
];
artyom.addCommands(myGroup);
// //passive mode detection
// if (annyang) {
// // Let's define our first command. First the text we expect, and then the function it should call
// var commands = {"hi":startListening,"hello":startListening,"hey":startListening};
// function startListening(){
// IsVoiceActivated=true;
// clearInterval(VoiceActivationTimeout);
// //artyom.say("I can hear you now !");
// $(".tabToRecord").hide();
// startRecording();
// VoiceActivationTimeout = setTimeout(() => {
// IsVoiceActivated=false;
// $(".tabToRecord").show();
// //artyom.say("you didn't say anything.");
// annyang.removeCommands(['i hate this song', 'i love this song']);
// stopRecording();
// }, 20000);
// var commands2 = {"i hate this song":StopListening,"i love this song":StopListening};
// function StopListening(){
// if(IsVoiceActivated){
// IsVoiceActivated=false;
// $(".tabToRecord").show();
// clearInterval(VoiceActivationTimeout);
// annyang.removeCommands(['i hate this song', 'i love this song']);
// stopRecording();
// }
// }
// annyang.addCommands(commands2);
// }
// // Add our commands to annyang
// annyang.addCommands(commands);
// }
KeolisServices.TextToSpeach = (Text) => {
//let artyom = new Artyom();
artyom.say(Text,{
onStart:function(){
KeolisServices.onPlaying();
},
onEnd:function(){
KeolisServices.onStop();
}
});
// artyom=null;
// delete artyom;
}
// This function activates artyom and will listen all that you say forever (requires https conection, otherwise a dialog will request if you allow the use of the microphone)
const startContinuousArtyom = () => {
artyom.fatality();// use this to stop any of
setTimeout(function(){// if you use artyom.fatality , wait 250 ms to initialize again.
artyom.initialize({
lang:"en-GB",// A lot of languages are supported. Read the docs !
continuous:false,// Artyom will listen forever
listen:true, // Start recognizing
debug:true, // Show everything in the console
speed:1, // talk normally
voice: ['Google US English', 'Alex'],
}).then(function(){
console.log("Ready to work !");
$("#Passive_mode").show();
});
},250);
}
KeolisServices.onPlaying = () => {
isTalking=true;
$(".tabToRecord").hide();
$(".audioWrapper .loader").removeClass("idle").removeClass("listening");
isUploading=false;
}
KeolisServices.onStop = () => {
isTalking=false;
$(".tabToRecord").show();
$(".audioWrapper .loader").addClass("idle").removeClass("listening");
if(PassiveModeOn){
navigator.permissions.query(
{ name: 'microphone' }
).then(function(permissionStatus){
$("#Passive_mode").show();
//annyang.start({ autoRestart: false, continuous: true });
startContinuousArtyom();
}
);
}
}
KeolisServices.connect = async (props) => {
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['heart_rate',] }],
//optionalServices: ['battery_service'], // Required to access service later.
acceptAllDevices: false,
})
//battery_service,battery_level
//alert(`%c\nš©š¼āāļø`, 'font-size: 82px;', 'Starting HR...\n\n')
const server = await device.gatt.connect()
const service = await server.getPrimaryService('heart_rate')
const char = await service.getCharacteristic('heart_rate_measurement')
device.addEventListener('gattserverdisconnected', onDisconnected);
char.oncharacteristicvaluechanged = props.onChange
char.startNotifications();
PlayCarl();
return char
}
KeolisServices.printHeartRate = (event) => {
RealtimeHeartRate = event.target.value.getInt8(1)
//check if hearRate triggered the passive mode
const prev = hrData[hrData.length - 1]
hrData[hrData.length] = RealtimeHeartRate
hrData = hrData.slice(-200)
let arrow = ''
if (RealtimeHeartRate !== prev) arrow = RealtimeHeartRate > prev ? 'ā¬' : 'ā¬'
document.getElementById("hr-rate").innerHTML = `<img src="./images/heart.png" width="16"> ${RealtimeHeartRate} ${arrow}`;
}
const onDisconnected = (event) => {
const device = event.target;
console.log(`Device ${device.name} is disconnected.`);
}
const recorder = new MicRecorder({
bitRate: 512
});
KeolisServices.startRecording = () => {
isRecording=true;
recorder.start().then(() => {
$(".tabToRecord").css("opacity","0.3");
console.log("---- recording started");
$(".audioWrapper .loader").removeClass("idle").addClass("listening");
}).catch((e) => {
console.error(e);
});
}
KeolisServices.stopRecording = (sendToCloud=true) => {
isRecording=false;
$(".tabToRecord").css("opacity","1");
recorder.stop().getMp3().then(([buffer, blob]) => {
// console.log(buffer, blob);
$(".audioWrapper .loader").removeClass("listening").addClass("idle");
if(sendToCloud)
SendTheRecordToCloud(blob);
}).catch((e) => {
console.error(e);
});
}
const SendTheRecordToCloud = (blob) => {
isUploading=true;
var form = new FormData();
form.append("Response_Voice_Wav", blob, "input.wav");
form.append("Beats_Per_Minute", RealtimeHeartRate);
form.append("Time_Taken_To_Response", "1");
form.append("Interaction_Session", localStorage.getItem("interaction_session"));
form.append("IsTesting", isTesting);
const payloadArray = [];
var recurringUser = localStorage.getItem("user_recurring");
payloadArray.push({"name":"RecurringUser","value": recurringUser});
payloadArray.push({"name":"spotify_playlist","value": localStorage.getItem("spotify_playlistid")});
payloadArray.push({"name":"spotify_user","value": localStorage.getItem("spotify_userid")});
payloadArray.push({"name":"spotify_top10songs","value": JSON.stringify(localStorage.getItem("spotify_top10songs").split(','))});
payloadArray.push({"name":"spotify_currentPlayingUri","value": getCurrentPlayingSong()});
form.append("JsonPayload",JSON.stringify(payloadArray));
var settings = {
"url": api_url + "/api/Interaction/Interact",
"method": "POST",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form,
"dataType":"json",
"beforeSend":function(){
$(".tabToRecord").hide();
},"error":function(data){
TextToSpeach("I didn't hear that can you repeat");
$(".tabToRecord").show();
}
};
$.ajax(settings).done(function (response) {
if(response.result.stage >= 13){
// Start listening. You can call this here, or attach this call to an event, button, etc.
console.log("---- listening started");
PassiveModeOn=true;
}
if(!response.result.statement){
TextToSpeach("I didn't hear that can you repeat");
$(".tabToRecord").show();
}else{
TextToSpeach(response.result.statement);
}
});
}
const PlayCarl = () => {
var settings = {
"url": api_url + "/api/TokenAuth/Auth",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json"
},
"data": JSON.stringify({
"apiKey": "d07c2100068146ae",
"apiSecret": "a745f8246c87407c",
"tenantName": "keolis"
}),
};
$.ajax(settings).done(function (response) {
var Token = response.result.accessToken;
var settings = {
"url": api_url + "/api/Interaction/SDK_InitializeSession",
"method": "POST",
"timeout": 0,
"headers": {
"Authorization": "Bearer " + Token,
"Content-Type": "application/json"
},
"data": JSON.stringify({
"UserID": localStorage.getItem("logged_in_user")
}),
"beforeSend" : function(){
$("#loading").show();
},
"error": function (xhr, ajaxOptions, thrownError) {
$("#loading").hide();
}
};
$.ajax(settings).done(function (response) {
debugger;
$("#loading").hide();
$(".wrapper").show();
if(response.success){
localStorage.setItem("interaction_session",response.result.id);
TextToSpeach("Hello, My Name Is Carl");
}
});
$(".section1").hide();
$(".section2").show();
});
}
//------------ Background worker.
///------------ Stop Watch ---
//----------------------------
var stopWatchPlaying=false;
var StopWatch_Seconds = 00;
var StopWatch_tens = 00;
var StopWatch_interval;
KeolisServices.StopWatch_Start = () => {
stopWatchPlaying=true;
console.log("---timer started");
clearInterval(StopWatch_interval);
StopWatch_interval = setInterval(startTimer, 10);
}
KeolisServices.StopWatch_Stop = () => {
stopWatchPlaying=false;
console.log("---timer stopped");
clearInterval(StopWatch_interval);
}
KeolisServices.StopWatch_Reset = () => {
stopWatchPlaying=false;
console.log("---timer reset");
clearInterval(StopWatch_interval);
StopWatch_tens = "00";
StopWatch_Seconds = "00";
}
KeolisServices.startTimer = () => {
console.log("---timer ticks :"+StopWatch_Seconds);
StopWatch_tens++;
if (StopWatch_tens > 99) {
StopWatch_Seconds++;
StopWatch_tens = 0;
}
}
return KeolisServices;
// eslint-disable-next-line prettier/prettier
}(window));