Builded WebHook for DialogFlow

This commit is contained in:
2018-08-29 00:52:40 +02:00
parent 2c6789c33a
commit 7b21345f89
12 changed files with 285 additions and 57 deletions

View File

@@ -11,9 +11,8 @@
Il nostro progetto nasce per aiutare nella quotidianità persone anziane che non possono essere seguite da assistenti e che quindi possono trarre vantaggio da un sistema automatizzato che interagisca attraverso un assistente vocale in modo da permettere al soggetto di controllare i dispositivi collegati alla Home Station. In caso di stress (rilevato attraverso battito cardiaco), le luci vengono soffuse così da creare un ambiente più rilassante e nel caso in cui la situazione non migliori contatti medico o familiari; inoltre viene consigliata in questo caso musica rilassante che il soggetto può avviare con comando vocale. Inoltre il soggetto viene sollecitato vocalmente in caso di sedentarietà. Si mantiene anche il contatto con persone esterne, medico e familiari, i quali possono controllare le attività del soggetto poiché verranno mantenute statistiche su di esse.
# TODO
- Aggiungere url generato da ngrok sul Webhook di DialogFlow
- Implementare la funzione getCurrentBrightness() nella classe Hue
- Documentazione per capire meglio (Sensor per esempio manca)
- Documentazione per capire meglio
- Main da iniziare e finire
[Jack]: <https://github.com/Berack96>

View File

@@ -12,6 +12,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/out" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="inheritedJdk" />

View File

@@ -15,9 +15,9 @@ repositories {
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
// compile "com.sparkjava:spark-core:2.5.5"
compile "com.google.code.gson:gson:2.8.0"
// compile "org.xerial:sqlite-jdbc:3.15.1"
compile "com.sparkjava:spark-core:2.7.2"
compile "com.google.code.gson:gson:2.8.4"
// compile "org.xerial:sqlite-jdbc:3.21.0.1" //todo remove commenting because "You need to install an appropriate JDBC (Java Database Connectivity) driver to run your Java database programs."
compile 'org.apache.httpcomponents:httpclient:4.5.3'
compile 'com.google.api-client:google-api-client:1.23.0'
compile group: 'com.google.oauth-client', name: 'google-oauth-client-jetty', version: '1.11.0-beta'
@@ -27,18 +27,20 @@ dependencies {
compile files('lib/zway-lib-0.2.9-SNAPSHOT.jar')
compile 'org.apache.commons:commons-lang3:3.4'
compile 'org.eclipse.jetty:jetty-client:9.3.11.v20160721'
compile 'org.eclipse.jetty:jetty-http:9.3.11.v20160721'
compile 'org.eclipse.jetty:jetty-io:9.3.11.v20160721'
compile 'org.eclipse.jetty:jetty-util:9.3.11.v20160721'
compile 'org.eclipse.jetty.websocket:websocket-api:9.3.12.v20160915'
compile 'org.eclipse.jetty.websocket:websocket-client:9.3.12.v20160915'
compile 'org.eclipse.jetty.websocket:websocket-common:9.3.12.v20160915'
compile 'org.eclipse.jetty:jetty-client:9.4.11.v20180605'
compile 'org.eclipse.jetty:jetty-http:9.4.11.v20180605'
compile 'org.eclipse.jetty:jetty-io:9.4.11.v20180605'
compile 'org.eclipse.jetty:jetty-util:9.4.11.v20180605'
compile 'org.eclipse.jetty.websocket:websocket-api:9.4.11.v20180605'
compile 'org.eclipse.jetty.websocket:websocket-client:9.4.11.v20180605'
compile 'org.eclipse.jetty.websocket:websocket-common:9.4.11.v20180605'
compile 'org.slf4j:slf4j-simple:1.7.21'
//DialogFlow
// compile "ai.api:libai:1.6.12"
compile "ai.api:libai:1.6.12"
// compile 'com.google.cloud:google-cloud-dialogflow:0.59.0-alpha' // for the v2 of dialogflow
//for objectMapper
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.5'
implementation 'junit:junit:4.12'
}

View File

@@ -1,9 +0,0 @@
package device;
public class DialogFlow {
public DialogFlow() {
}
}

View File

@@ -0,0 +1,109 @@
package device;
import ai.api.GsonFactory;
import ai.api.model.AIResponse;
import ai.api.model.Fulfillment;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import static spark.Spark.post;
/**
* Classe per creare un Webhook che Dialog-Flow possa utilizzare per le sue azioni
*/
public class DialogFlowWebHook {
/**
* Un logger per vedere le cose piu' easy
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* Errore che viene mostrato all'utente se l'azione inviata non corrisponde a nessuna di quelle inserite
*/
public static final String ERROR = "Non mi hanno imparato abbastanza per fare questo";
/**
* L'eventuale path successiva all'url dichiarato nel Webhook di Dialog-Flow
*/
public final String path;
/**
* Mappa che contiene tutte le azioni e il loro ID
*/
private final Map<String, Action> actions;
/**
* Crea una classe vuota per un server che risponde lle chiamate di Dialog-Flow.
* La path viene impostata di default a "/"
*/
public DialogFlowWebHook() {
this("/");
}
/**
* Crea una classe vuota per un server che risponde lle chiamate di Dialog-Flow.
* @param path il percorso dopo l'url inidicato nel WebHook di Dialog-Flow
*/
public DialogFlowWebHook(String path) {
this.path = path;
this.actions = new HashMap<>();
}
/**
* Aggiunge un'azione ad una specifica richiesta di Dialog-Flow
* @param actionId il nome dell'azione che viene passata da Dialog-Flow
* @param action l'azione da fare (usare lambda)
*/
public void addOnAction(String actionId, Action action) {
this.actions.put(actionId, action);
}
/**
* Fa partire il server per accettare richieste da Dialog-Flow.
* Ogni richiesta viene esaminata e fatta coincidere con una azione specificata precedentemente.
* Se nessuna azione viene riscontrata, viene inviato un errore, rimuovendo i messaggi
*/
public void startServer() { // todo add param port? Spark.port(num);
Gson gson = GsonFactory.getDefaultFactory().getGson();
post(this.path, (request, response) -> {
Fulfillment output = new Fulfillment();
AIResponse input = gson.fromJson(request.body(), AIResponse.class);
String text = null;
try {
log.info("AZIONE: "+input.getResult().getAction());
Action action = actions.get(input.getResult().getAction());
text = action.doAction();
} catch (NullPointerException e) {
log.info("NESSUNA AZIONE TROVATA");
text = ERROR;
}
if(text != null) {
log.info(text);
output.setDisplayText(text);
output.setSpeech(text);
}
response.type("application/json");
return output;
}, gson::toJson);
}
/**
* Interfaccia usata per fare un'azione per ogni Id di Dialog-Flow
*/
public interface Action {
/**
* Fai l'azione desiderata.
* Se ritorna una stringa allora il testo viene cambiato. Se ritorna null non cambia il testo
* @return Una stringa che verra' usata come messaggio o null se non si vuole
*/
String doAction();
}
}

View File

@@ -6,28 +6,41 @@ import de.fh_zwickau.informatik.sensor.model.devices.Device;
import de.fh_zwickau.informatik.sensor.model.devices.DeviceList;
import support.ZWaySimpleCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Sensore che permette di registrare vari dati dell'ambiente
*/
public class Sensor {
/**
* Logger?
*/
Logger logger = LoggerFactory.getLogger(Sensor.class);
// sample RaZberry IP address
public String ipAddress = "172.30.1.137";
/* todo ma serve il LOGGER?
private Logger logger = LoggerFactory.getLogger(Sensor.class);
*/
// sample username and password
public String username = "admin";
public String password = "raz4reti2";
/**
* IP del sensore a cui ci si vuole agganciare
*/
private static final String IP_ADDRESS = "172.30.1.137";
public IZWayApi zwayApi;
/**
* Porta in cui si ascolta per i sensori
*/
private static final int PORT = 8083;
/**
* Username con cui si entra nel dispositivo
*/
private static final String USERNAME = "admin";
/**
* Password del dispositivo
*/
private final String PASSWORD = "raz4reti2";
/**
* Tutti i devices che esistono nella rete
*/
private DeviceList allZWaveDevices;
/**
* I device che vengono selezionati e filtrati dall'utente (ovvero quelli che verranno usati per prendere i dati)
*/
private DeviceList devices;
/**
@@ -37,9 +50,13 @@ public class Sensor {
this(null);
}
/**
* Si connette ad un sensore che ha il nodeId selezioniato
* @param nodeId nodo che viene selezionato
*/
public Sensor (Integer nodeId) {
// create an instance of the Z-Way library; all the params are mandatory (we are not going to use the remote service/id)
zwayApi = new ZWayApiHttp(ipAddress, 8083, "http", username, password, 0, false, new ZWaySimpleCallback());
IZWayApi zwayApi = new ZWayApiHttp(IP_ADDRESS, PORT, "http", USERNAME, PASSWORD, 0, false, new ZWaySimpleCallback());
// get all the Z-Wave devices
allZWaveDevices = zwayApi.getDevices();
@@ -50,6 +67,10 @@ public class Sensor {
devices = allZWaveDevices;
}
/**
* Cambia i dispositivi selezionati in base al nodeId che viene scelto
* @param nodeId il nodo che viene selezionato
*/
public void useNode(int nodeId) {
devices = new DeviceList();
for (Device devi : allZWaveDevices.getAllDevices())
@@ -57,6 +78,10 @@ public class Sensor {
devices.addDevice(devi);
}
/**
* Legge i valori della luminosita' segnata dai dispositivi e ne ritorna il valore
* @return la luminopsita' segnata dai dispositivi
*/
public int getBrightnessLevel() {
for (Device device : devices.getAllDevices())
if (device.getMetrics().getProbeTitle().equalsIgnoreCase("luminiscence"))
@@ -64,8 +89,13 @@ public class Sensor {
return -99;
}
/**
* Fa in modo di forzare l'aggiornamento dei dispositivi
* @param timeout fa aspettare un tot di tempo prima di provare a forzare e dopo l'aggiornameto
* @throws InterruptedException nel caso che succeda qualcosa
*/
synchronized public void update(int timeout) throws InterruptedException {
//setInitialValues();
wait(timeout);
for (Device device : devices.getAllDevices())
device.update();
wait(timeout);

View File

@@ -7,6 +7,39 @@ import device.*;
*/
public class Main {
public static void main(String[] args) {
DialogFlowWebHook df = new DialogFlowWebHook();
df.addOnAction("LightsON", () -> {return "Luci accese";});
df.addOnAction("LightsOFF", () -> {return "Luci spente";});
df.startServer();
}
/**
* Cose da fare in questa funzione:
* - far partire il database
* - ogni ora aggiornare i dati del cuore. (Runnable che gira da se')
* - alla fine della giornata fare un riepilogo del paziente (Runnable che gira da se')
* (magari ci si calcola quando bisogna risvegliarsi e si mette un wait)
* @param fibit da dove prende i dati
*/
private void startDb(Fitbit fibit) {
/*
try {
Connection conn = DBConnect.getInstance().getConnection();
PreparedStatement st = conn.prepareStatement("");
ResultSet rs = st.executeQuery();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
*/
}
/*
public static void main(String[] args) throws Exception {
Fitbit fitbit = new Fitbit();
Sensor sensor = new Sensor();
@@ -17,7 +50,7 @@ public class Main {
int brightness = sensor.getBrightnessLevel();
// AUTOMATIC
// Inserire ui dati nel DB ogni ora
// Gestione DB in modo che si aggiorni ogni ora
// Gestione luci in modo che la luminosità sia sempre la stessa
// Gestione luci a seconda del battito cardiaco
// Ad una certa ora guarda i passi e se sono pochi dillo
@@ -31,4 +64,5 @@ public class Main {
// Randomly at night heavy metal start
}
}
*/
}

View File

@@ -0,0 +1,39 @@
package support;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* Handle the connection to the SQLite database that stores our tasks.
* @author <a href="mailto:luigi.derussis@uniupo.it">Luigi De Russis</a>
* @version 1.1 (06/05/2018)
*/
public class DBConnect {
// todo add a db where we put daily (or hourly, but only for heart) updates
static private final String DB_LOCATION = "jdbc:sqlite:src/main/resources/tasks.db";
static private DBConnect instance = null;
private DBConnect() {
instance = this;
}
public static DBConnect getInstance() {
return (instance == null ? new DBConnect() : instance);
}
public Connection getConnection() throws SQLException {
try {
/* todo this might work for create the database
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/");
Statement s = Conn.createStatement();
int result = s.executeUpdate("CREATE DATABASE databasename");
st.close();
*/
return DriverManager.getConnection(DB_LOCATION);
} catch (SQLException e) {
throw new SQLException("Cannot get connection to " + DB_LOCATION, e);
}
}
}

View File

@@ -0,0 +1,18 @@
package test;
import device.DialogFlowWebHook;
import org.junit.Test;
public class TestDialogFlow {
@Test
public void test01() {
DialogFlowWebHook webHook = new DialogFlowWebHook();
webHook.addOnAction("LightsON", () -> {return "Luci accese";});
webHook.addOnAction("LightsOFF", () -> {return "Luci spente";});
webHook.startServer();
}
}

View File

@@ -1,17 +1,18 @@
import device.Fitbit;
import org.junit.Test;
public class TestFitbit {
@Test
public void test01() throws Exception {
Fitbit fitBit = new Fitbit();
fitBit.getHoursSleep();
System.out.println("Today's average heart-rate: "+fitBit.getHeartRate());
System.out.println("Today's hours of sleep: "+fitBit.getHoursSleep());
System.out.println("Today's steps: "+fitBit.getSteps());
System.out.println("Fine.");
}
}
package test;
import device.Fitbit;
import org.junit.Test;
public class TestFitbit {
@Test
public void test01() throws Exception {
Fitbit fitBit = new Fitbit();
fitBit.getHoursSleep();
System.out.println("Today's average heart-rate: "+fitBit.getHeartRate());
System.out.println("Today's hours of sleep: "+fitBit.getHoursSleep());
System.out.println("Today's steps: "+fitBit.getSteps());
System.out.println("Fine.");
}
}

View File

@@ -1,3 +1,5 @@
package test;
import device.Hue;
import org.junit.Test;

View File

@@ -1,3 +1,5 @@
package test;
import device.Hue;
import device.Sensor;
import org.junit.Test;