Fix and last TODO
- Various fix in code - Fitbit now support steps by minutes - Added data retrieving from WebHook - Added checkSteps
This commit is contained in:
@@ -102,11 +102,17 @@ public class DialogFlowWebHook {
|
|||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
LOG.error("NESSUNA AZIONE TROVATA: "+ inputAction);
|
LOG.error("NESSUNA AZIONE TROVATA: "+ inputAction);
|
||||||
text = ERROR;
|
text = ERROR;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Qualcosa e' andato storto: " + e.getMessage());
|
||||||
|
text = ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(text == null)
|
if(text == null)
|
||||||
text = input.getResult().getFulfillment().getSpeech();
|
text = input.getResult().getFulfillment().getSpeech();
|
||||||
|
|
||||||
|
for(String param: inputParam.keySet())
|
||||||
|
text = text.replace("@"+param, inputParam.get(param).getAsString());
|
||||||
|
|
||||||
LOG.info("RISPOSTA: " + text);
|
LOG.info("RISPOSTA: " + text);
|
||||||
output.setDisplayText(text);
|
output.setDisplayText(text);
|
||||||
output.setSpeech(text);
|
output.setSpeech(text);
|
||||||
@@ -135,7 +141,8 @@ public class DialogFlowWebHook {
|
|||||||
*
|
*
|
||||||
* @param params una mappa contenente tutti i parametri impostati da dialogflow
|
* @param params una mappa contenente tutti i parametri impostati da dialogflow
|
||||||
* @return Una stringa che verra' usata come messaggio o null se non si vuole
|
* @return Una stringa che verra' usata come messaggio o null se non si vuole
|
||||||
|
* @throws Exception una qualunque eccezione che si vuole lanciare
|
||||||
*/
|
*/
|
||||||
String doAction(Map<String, JsonElement> params);
|
String doAction(Map<String, JsonElement> params) throws Exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package device;
|
package device;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import device.fitbitdata.HeartRate;
|
import device.fitbitdata.HeartRate;
|
||||||
import device.fitbitdata.Sleep;
|
import device.fitbitdata.Sleep;
|
||||||
import device.fitbitdata.Steps;
|
import device.fitbitdata.Steps;
|
||||||
@@ -13,6 +7,12 @@ import oauth.AuthFitbit;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe che permette di ricevere i dati di un particolare account FitBit
|
* Classe che permette di ricevere i dati di un particolare account FitBit
|
||||||
*/
|
*/
|
||||||
@@ -83,19 +83,39 @@ public class Fitbit {
|
|||||||
* Ricevi i passi che l'utente ha effettuato nell'ultimo giorno
|
* Ricevi i passi che l'utente ha effettuato nell'ultimo giorno
|
||||||
*
|
*
|
||||||
* @return un intero rappresentante i passi effettuati
|
* @return un intero rappresentante i passi effettuati
|
||||||
* @throws IOException nel caso la richiesta non vada a buon fine
|
|
||||||
*/
|
*/
|
||||||
public synchronized int getSteps() {
|
public synchronized int getSteps() {
|
||||||
steps = update(Steps.class, steps, "1" + USER + "activities/steps/date/today/1w.json");
|
steps = update(Steps.class, steps, "1" + USER + "activities/steps/date/today/1d/1min.json");
|
||||||
return steps.getSteps();
|
return steps.getSteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ricevi i passi che l'utente ha effettuato negli ultimi minuti richiesti
|
||||||
|
*
|
||||||
|
* @param lastMinutes gli ultimi minuti che si vogliono vedere (positivi e !=0 se no ritorno -1)
|
||||||
|
* @return un intero rappresentante i passi effettuati
|
||||||
|
*/
|
||||||
|
public synchronized int getSteps(int lastMinutes) {
|
||||||
|
if(lastMinutes<=0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
steps = update(Steps.class, steps, "1" + USER + "activities/steps/date/today/1d/1min.json");
|
||||||
|
|
||||||
|
List<Map<String, Object>> list = steps.getStepsData();
|
||||||
|
final int now = list.size()-1;
|
||||||
|
|
||||||
|
int totalSteps = 0;
|
||||||
|
for(int i=0; i<lastMinutes; i++)
|
||||||
|
totalSteps += (int)list.get(now-i).get("value");
|
||||||
|
|
||||||
|
return totalSteps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ricevi il battito cardiaco dell'utente<br>
|
* Ricevi il battito cardiaco dell'utente<br>
|
||||||
* Il risultato e' una media del battito che l'utente ha avuto negli ultimi 15 minuti
|
* Il risultato e' una media del battito che l'utente ha avuto negli ultimi 15 minuti
|
||||||
*
|
*
|
||||||
* @return un intero rappresentante la media del battito cardiaco degli ultimi 15 minuti
|
* @return un intero rappresentante la media del battito cardiaco degli ultimi 15 minuti
|
||||||
* @throws IOException nel caso la richiesta non vada a buon fine
|
|
||||||
*/
|
*/
|
||||||
public synchronized double getHeartRate() { return getHeartRate(15); }
|
public synchronized double getHeartRate() { return getHeartRate(15); }
|
||||||
|
|
||||||
@@ -105,7 +125,6 @@ public class Fitbit {
|
|||||||
*
|
*
|
||||||
* @param lastMinutes fino a quanti minuti bisogna tenere conto (positivi e !=0 se no ritorno -1)
|
* @param lastMinutes fino a quanti minuti bisogna tenere conto (positivi e !=0 se no ritorno -1)
|
||||||
* @return un intero rappresentante la media del battito cardiaco degli ultimi minuti specificati
|
* @return un intero rappresentante la media del battito cardiaco degli ultimi minuti specificati
|
||||||
* @throws IOException nel caso la richiesta non vada a buon fine
|
|
||||||
*/
|
*/
|
||||||
public synchronized double getHeartRate(int lastMinutes) {
|
public synchronized double getHeartRate(int lastMinutes) {
|
||||||
if(lastMinutes<=0)
|
if(lastMinutes<=0)
|
||||||
@@ -127,7 +146,6 @@ public class Fitbit {
|
|||||||
* Ricevi le ore di sonno che l'utente ha fatto nell'ultimo giorno
|
* Ricevi le ore di sonno che l'utente ha fatto nell'ultimo giorno
|
||||||
*
|
*
|
||||||
* @return un intero rappresentante le ore passate a dormire
|
* @return un intero rappresentante le ore passate a dormire
|
||||||
* @throws IOException nel caso la richiesta non vada a buon fine
|
|
||||||
*/
|
*/
|
||||||
public synchronized long getHoursSleep() {
|
public synchronized long getHoursSleep() {
|
||||||
sleep = update(Sleep.class, sleep,"1.2" + USER + "sleep/date/today.json");
|
sleep = update(Sleep.class, sleep,"1.2" + USER + "sleep/date/today.json");
|
||||||
@@ -141,7 +159,6 @@ public class Fitbit {
|
|||||||
* - la durata del sonno<br>
|
* - la durata del sonno<br>
|
||||||
* - la data di fine<br>
|
* - la data di fine<br>
|
||||||
* @return una lista contenente ogni volta che l'utente ha dormito
|
* @return una lista contenente ogni volta che l'utente ha dormito
|
||||||
* @throws IOException
|
|
||||||
*/
|
*/
|
||||||
public synchronized List<Sleep.SleepData> getDetailedSleep() {
|
public synchronized List<Sleep.SleepData> getDetailedSleep() {
|
||||||
sleep = update(Sleep.class, sleep,"1.2" + USER + "sleep/date/today.json");
|
sleep = update(Sleep.class, sleep,"1.2" + USER + "sleep/date/today.json");
|
||||||
@@ -169,16 +186,17 @@ public class Fitbit {
|
|||||||
return variable;
|
return variable;
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// do nothing and update
|
// do nothing and update
|
||||||
} finally {
|
|
||||||
LOG.info("Updating " + varClass.getSimpleName() + " form " + BASIC_URL + url);
|
|
||||||
try {
|
|
||||||
variable = auth.run(BASIC_URL + url, varClass);
|
|
||||||
latestRequest.put(varClass, System.currentTimeMillis());
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.error("Non sono riuscito a prender i dati aggiornati: " + e.getMessage());
|
|
||||||
}
|
|
||||||
return variable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG.info("Updating " + varClass.getSimpleName() + " form " + BASIC_URL + url);
|
||||||
|
try {
|
||||||
|
variable = auth.run(BASIC_URL + url, varClass);
|
||||||
|
latestRequest.put(varClass, System.currentTimeMillis());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Non sono riuscito a prender i dati aggiornati: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public class Hue {
|
|||||||
if(allLights.isEmpty())
|
if(allLights.isEmpty())
|
||||||
throw new NullPointerException("Non e' stato possibile connettersi alle luci");
|
throw new NullPointerException("Non e' stato possibile connettersi alle luci");
|
||||||
|
|
||||||
|
// TODO GIOVEDI impostare una luminosita' e un colore di default
|
||||||
double bri = 0;
|
double bri = 0;
|
||||||
double hue = 0;
|
double hue = 0;
|
||||||
for (String name: allLights.keySet()) {
|
for (String name: allLights.keySet()) {
|
||||||
@@ -147,7 +148,7 @@ public class Hue {
|
|||||||
else if (num>100)
|
else if (num>100)
|
||||||
num=100;
|
num=100;
|
||||||
|
|
||||||
setState("bri", (int) (num*MAX_BRIGHTNESS)/100 );
|
setState("bri", (int) (num*MAX_BRIGHTNESS)/100, true);
|
||||||
brightness.set(num);
|
brightness.set(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,23 +197,13 @@ public class Hue {
|
|||||||
public void changeColor(String colorName) {
|
public void changeColor(String colorName) {
|
||||||
for (String regex: COLORS.keySet())
|
for (String regex: COLORS.keySet())
|
||||||
if(colorName.matches("(?i)" + regex))
|
if(colorName.matches("(?i)" + regex))
|
||||||
setState("xy", COLORS.get(regex));
|
setState("xy", COLORS.get(regex), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifica il colore delle luci in modo da fare un bel effetto arcobaleno continuo
|
* Modifica il colore delle luci in modo da fare un bel effetto arcobaleno continuo
|
||||||
*/
|
*/
|
||||||
public void colorLoop() { setState("effect", "colorloop"); }
|
public void colorLoop() { setState("effect", "colorloop", false); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Invia una richiesta a tutte le luci hue con l'attributo selezionato ed il suo valore<br>
|
|
||||||
* Con esso invia anche una transition:20 in modo che sia piu fluido il cambiamento
|
|
||||||
* @param attribute l'attributo che si vuole cambiare
|
|
||||||
* @param value il valore da inserire
|
|
||||||
*/
|
|
||||||
public void setState(String attribute, Object value){
|
|
||||||
setState(attribute, value, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invia una richiesta a tutte le luci hue con l'attributo selezionato ed il suo valore<br>
|
* Invia una richiesta a tutte le luci hue con l'attributo selezionato ed il suo valore<br>
|
||||||
@@ -221,7 +212,7 @@ public class Hue {
|
|||||||
* @param value il valore da inserire
|
* @param value il valore da inserire
|
||||||
* @param transition se includere la transizione o meno
|
* @param transition se includere la transizione o meno
|
||||||
*/
|
*/
|
||||||
public void setState(String attribute, Object value, boolean transition){
|
private void setState(String attribute, Object value, boolean transition){
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put(attribute, value);
|
map.put(attribute, value);
|
||||||
if(transition)
|
if(transition)
|
||||||
@@ -233,7 +224,7 @@ public class Hue {
|
|||||||
* Invia una richiesta a tutte le luci hue con gli attributi selezionati ed il loro valore
|
* Invia una richiesta a tutte le luci hue con gli attributi selezionati ed il loro valore
|
||||||
* @param attributes una mappa di attributi -> valori
|
* @param attributes una mappa di attributi -> valori
|
||||||
*/
|
*/
|
||||||
public synchronized void setState(Map<String, Object> attributes) {
|
private synchronized void setState(Map<String, Object> attributes) {
|
||||||
String body = GsonFactory.getDefaultFactory().getGson().toJson(attributes);
|
String body = GsonFactory.getDefaultFactory().getGson().toJson(attributes);
|
||||||
LOG.info("Setting: " + body);
|
LOG.info("Setting: " + body);
|
||||||
for (String light : allLights.keySet()) {
|
for (String light : allLights.keySet()) {
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
package device.fitbitdata;
|
package device.fitbitdata;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class Steps extends FitbitData {
|
public class Steps extends FitbitData {
|
||||||
|
|
||||||
private int steps = 0;
|
private int steps;
|
||||||
|
private List<Map<String, Object>> stepsData;
|
||||||
|
|
||||||
@JsonProperty("activities-steps")
|
@JsonProperty("activities-steps")
|
||||||
public void setSteps(Map<String, String>[] array) {
|
private void setSteps(Map<String, String>[] array) {
|
||||||
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
|
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
String strDate = sdfDate.format(now);
|
String strDate = sdfDate.format(now);
|
||||||
@@ -23,6 +26,12 @@ public class Steps extends FitbitData {
|
|||||||
steps = Integer.parseInt(map.get("value"));
|
steps = Integer.parseInt(map.get("value"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty("activities-steps-intraday")
|
||||||
|
private void setDetailedSteps(Map<String, Object> map) {
|
||||||
|
stepsData = new ArrayList<>((List<Map<String, Object>>) map.get("dataset"));
|
||||||
|
}
|
||||||
|
|
||||||
public void setSteps(int steps) { this.steps = steps; }
|
public void setSteps(int steps) { this.steps = steps; }
|
||||||
public int getSteps() { return steps; }
|
public int getSteps() { return steps; }
|
||||||
|
public List<Map<String, Object>> getStepsData() { return stepsData; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public class SeniorAssistant {
|
|||||||
* @param args i possibili argomenti da passare al programma
|
* @param args i possibili argomenti da passare al programma
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
//TODO magari aggiungere un arg con la path per la musica in modo che si possa ampliare in futuro
|
||||||
VariousThreads threads = new VariousThreads(); // this should be the first action of the main
|
VariousThreads threads = new VariousThreads(); // this should be the first action of the main
|
||||||
Map<String, String> arguments = getArgsMap(args);
|
Map<String, String> arguments = getArgsMap(args);
|
||||||
|
|
||||||
@@ -65,22 +66,24 @@ public class SeniorAssistant {
|
|||||||
LOG.warn(e.getMessage());
|
LOG.warn(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lo dichiaro qui, cosi' anche se non ci si puo' collegare al fitbit si puo comunque comandare le luci
|
||||||
|
Fitbit fitbit=null;
|
||||||
try {
|
try {
|
||||||
LOG.info("Connessione al Fitbit, ignorare eventuale errore per setPermissionsToOwnerOnly...");
|
LOG.info("Connessione al Fitbit, ignorare eventuale errore per setPermissionsToOwnerOnly...");
|
||||||
Fitbit fitbit = new Fitbit();
|
fitbit = new Fitbit();
|
||||||
|
|
||||||
LOG.info("Connessione al database...");
|
LOG.info("Connessione al database...");
|
||||||
Database database = remoteDbUser == null ? new LocalDB() : new RemoteDB(remoteDbUser);
|
Database database = remoteDbUser == null ? new LocalDB() : new RemoteDB(remoteDbUser);
|
||||||
|
|
||||||
threads.startInsertData(database, fitbit);
|
threads.startInsertData(database, fitbit);
|
||||||
threads.startHueControlledByHeartBeat(lights, fitbit, database);
|
threads.startHueControlledByHeartBeat(lights, fitbit, database);
|
||||||
threads.startCheckSteps(fitbit);
|
threads.startCheckSteps(database);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.warn("Non e' stato possibile collegarsi al fitbit");
|
LOG.warn("Non e' stato possibile collegarsi al fitbit");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
threads.startWebhook(lights);
|
threads.startWebhook(lights, fitbit);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error(e.getMessage());
|
LOG.error(e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -88,19 +91,19 @@ public class SeniorAssistant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO AUTOMATIC: {D}
|
AUTOMATIC:
|
||||||
|
|
||||||
XXX Gestione DB in modo che si aggiorni ogni ora
|
XXX Gestione DB in modo che si aggiorni ogni ora
|
||||||
XXX Gestione luci in modo che la luminosità sia sempre la stessa
|
XXX Gestione luci in modo che la luminosità sia sempre la stessa
|
||||||
XXX Gestione luci a seconda del battito cardiaco
|
XXX Gestione luci a seconda del battito cardiaco
|
||||||
/D/ Ogni X ore/minuti guarda i passi e se sono pochi dillo
|
XXX Ogni X ore/minuti guarda i passi e se sono pochi dillo
|
||||||
XXX Se i battiti sono troppo bassi/alti avvisare il tizio
|
XXX Se i battiti sono troppo bassi/alti avvisare il tizio
|
||||||
|
|
||||||
TODO USER-INTERACTION {A}
|
USER-INTERACTION:
|
||||||
|
|
||||||
/A/ Dati del sonno/battito/passi che l'utente puo' richiedere
|
XXX Dati del sonno/battito/passi che l'utente puo' richiedere
|
||||||
XXX Gestione luci secondo le esigenze dell'utente ( settare Dialogflow e server + risolvere bug )
|
XXX Gestione luci secondo le esigenze dell'utente ( settare Dialogflow e server + risolvere bug )
|
||||||
XXX Gestione musica tramite comando vocale //TODO mettere a posto dialogflow e inserire qualche canzone
|
XXX Gestione musica tramite comando vocale //TODO inserire qualche canzone
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import device.Fitbit;
|
|||||||
import device.Hue;
|
import device.Hue;
|
||||||
import device.Sensor;
|
import device.Sensor;
|
||||||
import device.fitbitdata.HeartRate;
|
import device.fitbitdata.HeartRate;
|
||||||
|
import device.fitbitdata.Steps;
|
||||||
import support.audio.Audio;
|
import support.audio.Audio;
|
||||||
import support.audio.AudioFile;
|
import support.audio.AudioFile;
|
||||||
import support.audio.Musich;
|
import support.audio.Musich;
|
||||||
@@ -15,6 +16,9 @@ import java.util.Calendar;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe che contiene tutti i thread che servono al programma per funzionare
|
||||||
|
*/
|
||||||
public class VariousThreads {
|
public class VariousThreads {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,16 +45,15 @@ public class VariousThreads {
|
|||||||
* Costruttore
|
* Costruttore
|
||||||
*/
|
*/
|
||||||
public VariousThreads() {
|
public VariousThreads() {
|
||||||
// audio = new AudioFile();
|
// audio = new AudioFile(); se si vuole solamente questo e non YT
|
||||||
audio = System.getProperty("os.name").startsWith("Windows")? new Musich():new AudioFile();
|
audio = System.getProperty("os.name").startsWith("Windows")? new Musich():new AudioFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO aggingere il fitbit per la richiesta dei dati
|
|
||||||
/**
|
/**
|
||||||
* Fa partire il server Webhook per DialogFlow e continua l'esecuzione
|
* Fa partire il server Webhook per DialogFlow e continua l'esecuzione
|
||||||
* @param lights le luci che deve controllare
|
* @param lights le luci che deve controllare
|
||||||
*/
|
*/
|
||||||
public void startWebhook(final Hue lights) {
|
public void startWebhook(final Hue lights, final Fitbit fitbit) {
|
||||||
DialogFlowWebHook df = new DialogFlowWebHook();
|
DialogFlowWebHook df = new DialogFlowWebHook();
|
||||||
|
|
||||||
df.addOnAction("LightsON", (params) -> { lights.turnOn(); cooldown.set(COOLDOWN_IN_MINUTES); return null; });
|
df.addOnAction("LightsON", (params) -> { lights.turnOn(); cooldown.set(COOLDOWN_IN_MINUTES); return null; });
|
||||||
@@ -87,8 +90,23 @@ public class VariousThreads {
|
|||||||
});
|
});
|
||||||
df.addOnAction("StopMusic", (params) -> { audio.stop(); return null; });
|
df.addOnAction("StopMusic", (params) -> { audio.stop(); return null; });
|
||||||
|
|
||||||
//TODO aggiungere una azione che faccia in modo di richiedere dei dati in particolare
|
// TODO GIOVEDI aggiungere un orario magari? se no va bene cosi
|
||||||
//TODO aggiungere una azione su DialogFlow che riconosca di impostare una playlist (Rilassante, Antica...)
|
df.addOnAction("ReqHearthbeat", (params) -> {
|
||||||
|
double rate = fitbit.getHeartRate(60);
|
||||||
|
return "Il battito medio dell'ultima ora e' di "+rate;
|
||||||
|
});
|
||||||
|
df.addOnAction("ReqSteps", (params) -> {
|
||||||
|
int steps = fitbit.getSteps();
|
||||||
|
return "I passi fatti oggi sono "+steps;
|
||||||
|
});
|
||||||
|
df.addOnAction("ReqDistance", (params) -> {
|
||||||
|
double steps = fitbit.getSteps();
|
||||||
|
return String.format("Oggi hai percorso circa %.2f kilometri", steps/2000);
|
||||||
|
});
|
||||||
|
df.addOnAction("ReqSleep", (params) -> {
|
||||||
|
long sleep = fitbit.getHoursSleep();
|
||||||
|
return String.format("Oggi hai dormito per %.2f ore", (double)sleep/3600000);
|
||||||
|
});
|
||||||
|
|
||||||
df.startServer();
|
df.startServer();
|
||||||
SeniorAssistant.LOG.info("Webhook partito");
|
SeniorAssistant.LOG.info("Webhook partito");
|
||||||
@@ -134,7 +152,7 @@ public class VariousThreads {
|
|||||||
calculateBrightFactor(
|
calculateBrightFactor(
|
||||||
calendar.get(Calendar.HOUR_OF_DAY),
|
calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
calendar.get(Calendar.MINUTE),
|
calendar.get(Calendar.MINUTE),
|
||||||
sensor.getBrightnessLevel()/10,
|
sensor.getBrightnessLevel(),
|
||||||
minBrightness
|
minBrightness
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -156,6 +174,7 @@ public class VariousThreads {
|
|||||||
public void startHueControlledByHeartBeat(final Hue lights, final Fitbit fitbit, final Database database) {
|
public void startHueControlledByHeartBeat(final Hue lights, final Fitbit fitbit, final Database database) {
|
||||||
final int minutes = 30;
|
final int minutes = 30;
|
||||||
final int delta = 15;
|
final int delta = 15;
|
||||||
|
final Audio audio = new AudioFile();
|
||||||
Thread thread = getThreadStartingEach(new Runnable() {
|
Thread thread = getThreadStartingEach(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public synchronized void run() {
|
public synchronized void run() {
|
||||||
@@ -177,15 +196,16 @@ public class VariousThreads {
|
|||||||
}
|
}
|
||||||
average = count!=0? sum/count:0;
|
average = count!=0? sum/count:0;
|
||||||
|
|
||||||
//TODO impostare azioni anche di {E}
|
//TODO avvisare con una voce registrata? far partire musica rilassante?
|
||||||
double rateNow = fitbit.getHeartRate(minutes);
|
double rateNow = fitbit.getHeartRate(minutes);
|
||||||
if ((rateNow-average) >= delta )
|
if (Math.abs(rateNow-average) > delta ) {
|
||||||
lights.decreaseBrightness();
|
lights.decreaseBrightness();
|
||||||
//avvisare con una voce registrata?
|
audio.play("Tullio.wav");
|
||||||
else if ((rateNow-average) <= -delta)
|
}
|
||||||
//alzare le luci?
|
else if (Math.abs(rateNow-average) < delta) {
|
||||||
//avvisare con una voce registrata?
|
lights.increaseBrightness();
|
||||||
;
|
audio.play("Tullio.wav");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, minutes, "lights-with-heartbeat");
|
}, minutes, "lights-with-heartbeat");
|
||||||
|
|
||||||
@@ -193,17 +213,49 @@ public class VariousThreads {
|
|||||||
SeniorAssistant.LOG.info("Thread per il controllo delle luci tramite il battito cardiaco partito");
|
SeniorAssistant.LOG.info("Thread per il controllo delle luci tramite il battito cardiaco partito");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Ad una certa ora guarda i passi e se sono pochi dillo
|
|
||||||
/**
|
/**
|
||||||
* Controlla che ad una certa ora si siano fatti abbastanza passi, ed in caso contrario avvisa tramite un messaggio vocale.<br>
|
* Controlla che ad una certa ora si siano fatti abbastanza passi, ed in caso contrario avvisa tramite un messaggio vocale.<br>
|
||||||
* E' possibile trasformarlo in controlla ogni X se si sono fatti dei movimenti o meno.
|
* E' possibile trasformarlo in controlla ogni X se si sono fatti dei movimenti o meno.
|
||||||
* @param fitbit da dove vediamo se si sono fatti abbastanza passi
|
* @param database da dove vediamo se si sono fatti abbastanza passi
|
||||||
*/
|
*/
|
||||||
public void startCheckSteps(final Fitbit fitbit) {
|
public void startCheckSteps(final Database database) {
|
||||||
// trovare un orario (magari inserirlo tramite arg)
|
final int minute = 24 * 60; // ogni ventiquattro ore circa
|
||||||
// a quell'ora controllare i passi fatti durante la giornata
|
final int norm = 4500;
|
||||||
// se pochi mandare un avviso tramite dialogFlow(?)
|
final int delta = 1500; // average steps for 60 year old -> 3.500-5.500 or so they say
|
||||||
// (secondo me si puo' evitare)
|
final Audio audio = new AudioFile();
|
||||||
|
|
||||||
|
// ma la domanda e': ad una certa ora o ad ogni X ore?
|
||||||
|
// AD UNA DETERMINATA ORA
|
||||||
|
Thread thread = getThreadStartingAt(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public synchronized void run() {
|
||||||
|
List<Steps> list = database.getStepDataOfLast(1);
|
||||||
|
|
||||||
|
double sum=0;
|
||||||
|
int size = list.size();
|
||||||
|
for(Steps steps: list)
|
||||||
|
sum += steps.getSteps();
|
||||||
|
final long average = size!=0? (long)(sum/size):0;
|
||||||
|
|
||||||
|
/* Con normale dettata dal tizio e average e' il primo risultato della lista
|
||||||
|
List<Steps> list = database.getStepDataOfLast(15);
|
||||||
|
|
||||||
|
//for
|
||||||
|
|
||||||
|
final long norm = size!=0? (long)(sum/size):0;
|
||||||
|
final long average = size!=0? list.get(0).getSteps():0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
//TODO avvisare con una voce registrata?
|
||||||
|
if (Math.abs(norm-average) > delta )
|
||||||
|
audio.play("Tullio.wav");
|
||||||
|
else if (Math.abs(norm-average) < delta)
|
||||||
|
audio.play("Tullio.wav");
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 20, "checking-steps");
|
||||||
|
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -235,6 +287,42 @@ public class VariousThreads {
|
|||||||
return maxIntensity-sensorBright;
|
return maxIntensity-sensorBright;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restuisce un thread che se fatto partire, esegue il runnable in un sub-thread alll'ora indicata ogni giorno<br>
|
||||||
|
* Il sotto thread lanciato avra' lo stesso nome, ma con un trattino e la data di lancio a seguito<br>
|
||||||
|
* Se il thread viene interrotto non fa piu' partire il runnable e si ferma
|
||||||
|
* @param runnable il runnable da lanciare
|
||||||
|
* @param hour l'ora a cui far partire il thread, se negativa o maggiore di 23 ritorna null
|
||||||
|
* @param threadName il nome da dare al thread
|
||||||
|
*/
|
||||||
|
public static Thread getThreadStartingAt(final Runnable runnable, final int hour, String threadName) {
|
||||||
|
if(hour<0 || hour>23)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public synchronized void run() {
|
||||||
|
boolean notInterrupted = true;
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
double hourCalculated = calendar.get(Calendar.HOUR_OF_DAY)+((double)calendar.get(Calendar.MINUTE)/60);
|
||||||
|
double hourToWait = hour-hourCalculated;
|
||||||
|
if(hourToWait<0)
|
||||||
|
hourToWait += 24;
|
||||||
|
|
||||||
|
wait((long)(hourToWait * 60 * MILLISEC_IN_MINUTE));
|
||||||
|
Thread thread = new Thread(runnable, threadName + "-" + new Timestamp(System.currentTimeMillis()));
|
||||||
|
thread.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
notInterrupted = false;
|
||||||
|
}
|
||||||
|
} while (notInterrupted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restuisce un thread che se fatto partire, esegue il runnable in un sub-thread ogni X minuti<br>
|
* Restuisce un thread che se fatto partire, esegue il runnable in un sub-thread ogni X minuti<br>
|
||||||
* Il sotto thread lanciato avra' lo stesso nome, ma con un trattino e la data di lancio a seguito<br>
|
* Il sotto thread lanciato avra' lo stesso nome, ma con un trattino e la data di lancio a seguito<br>
|
||||||
@@ -243,7 +331,7 @@ public class VariousThreads {
|
|||||||
* @param minutes i minuti da aspettare, se negativi o 0 ritorna null
|
* @param minutes i minuti da aspettare, se negativi o 0 ritorna null
|
||||||
* @param threadName il nome da dare al thread
|
* @param threadName il nome da dare al thread
|
||||||
*/
|
*/
|
||||||
public static Thread getThreadStartingEach(final Runnable runnable, int minutes, String threadName) {
|
public static Thread getThreadStartingEach(final Runnable runnable, final int minutes, String threadName) {
|
||||||
if(minutes<1)
|
if(minutes<1)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class AuthFitbit {
|
|||||||
/**
|
/**
|
||||||
* Un logger per rendere le cose semplici in caso di casini
|
* Un logger per rendere le cose semplici in caso di casini
|
||||||
*/
|
*/
|
||||||
private static final Logger LOG = LoggerFactory.getLogger("Fitbit Response");
|
private static final Logger LOG = LoggerFactory.getLogger("Fitbit Auth");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Un mapper per trasformare i json in mappe.
|
* Un mapper per trasformare i json in mappe.
|
||||||
@@ -132,7 +132,7 @@ public class AuthFitbit {
|
|||||||
|
|
||||||
String content = response.parseAsString();
|
String content = response.parseAsString();
|
||||||
response.disconnect();
|
response.disconnect();
|
||||||
LOG.info("Recived: " + content);
|
LOG.debug("Recived: " + content);
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ public class AuthFitbit {
|
|||||||
*/
|
*/
|
||||||
public <O> O run(String url, Class<O> returnClass) throws IOException {
|
public <O> O run(String url, Class<O> returnClass) throws IOException {
|
||||||
O ret = MAPPER.readValue(this.run(url), returnClass);
|
O ret = MAPPER.readValue(this.run(url), returnClass);
|
||||||
LOG.info("Saved in class: " + JSON_FACTORY.toString(ret));
|
LOG.debug("Saved in class: " + JSON_FACTORY.toString(ret));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class AudioFile implements Audio {
|
|||||||
/**
|
/**
|
||||||
* L'ultimo audio fatto partire
|
* L'ultimo audio fatto partire
|
||||||
*/
|
*/
|
||||||
private AudioStream lastIn = null;
|
private static AudioStream lastIn = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serve per crearsi una mapp di tutte le canzoni
|
* Serve per crearsi una mapp di tutte le canzoni
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ package support.database;
|
|||||||
import device.Fitbit;
|
import device.Fitbit;
|
||||||
import device.fitbitdata.HeartRate;
|
import device.fitbitdata.HeartRate;
|
||||||
import device.fitbitdata.Sleep;
|
import device.fitbitdata.Sleep;
|
||||||
|
import device.fitbitdata.Steps;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static main.VariousThreads.MILLISEC_IN_MINUTE;
|
import static main.VariousThreads.*;
|
||||||
import static main.VariousThreads.getThreadStartingEach;
|
|
||||||
|
|
||||||
public interface Database {
|
public interface Database {
|
||||||
|
|
||||||
@@ -53,6 +53,13 @@ public interface Database {
|
|||||||
*/
|
*/
|
||||||
List<HeartRate> getHeartDataOfLast(int days);
|
List<HeartRate> getHeartDataOfLast(int days);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Riceve i dati dei passi dal giorno selezionato fino ad oggi
|
||||||
|
* @param days quanti giorni devono esser considerati
|
||||||
|
* @return una lista dei passifatti negli ultimi X giorni (ordinati da oggi al giorno X)
|
||||||
|
*/
|
||||||
|
List<Steps> getStepDataOfLast(int days);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prendi il Thread che automaticamente gestisce l'inserimento dei dati orari (per ora solo il battito cardiaco)<br>
|
* Prendi il Thread che automaticamente gestisce l'inserimento dei dati orari (per ora solo il battito cardiaco)<br>
|
||||||
* Se per caso c'e' un fallimento riprova ad inserire i dati ogni x minuti, indicati dal terzo parametro<br>
|
* Se per caso c'e' un fallimento riprova ad inserire i dati ogni x minuti, indicati dal terzo parametro<br>
|
||||||
@@ -65,19 +72,20 @@ public interface Database {
|
|||||||
Runnable runnable = new Runnable() {
|
Runnable runnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public synchronized void run() {
|
public synchronized void run() {
|
||||||
LOG.info("Aggiornamento orario iniziato");
|
|
||||||
try {
|
try {
|
||||||
boolean retry;
|
boolean retry;
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
double heartRate = 30;//fitbit.getHeartRate(60);
|
double heartRate = fitbit.getHeartRate(60);
|
||||||
|
int steps = fitbit.getSteps(1);
|
||||||
do {
|
do {
|
||||||
retry = !database.updateHeart(now, heartRate);
|
retry = !database.updateHeart(now, heartRate);
|
||||||
LOG.info("Aggiornamento " + (!retry ? "riuscito" : "fallito, riprovo fra " + retryMinutes + " minuti"));
|
retry = retry && !database.updateSteps(now, steps);
|
||||||
|
LOG.info("Aggiornamento orario " + (!retry ? "riuscito" : "fallito, riprovo fra " + retryMinutes + " minuti"));
|
||||||
if (retry)
|
if (retry)
|
||||||
wait(retryMinutes * MILLISEC_IN_MINUTE);
|
wait(retryMinutes * MILLISEC_IN_MINUTE);
|
||||||
} while(retry);
|
} while(retry);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.warn("Aggiornamento interrotto");
|
LOG.warn("Aggiornamento orario interrotto");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -86,7 +94,7 @@ public interface Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prendi il Thread che automaticamente gestisce l'inserimento dei dati giornalieri<br>
|
* Prendi il Thread che automaticamente gestisce l'inserimento dei dati giornalieri, esso fara' i tentativi alle 23<br>
|
||||||
* Se per caso c'e' un fallimento riprova ad inserire i dati ogni x minuti, indicati dal terzo parametro<br>
|
* Se per caso c'e' un fallimento riprova ad inserire i dati ogni x minuti, indicati dal terzo parametro<br>
|
||||||
* @param database il database in cui inserirlo
|
* @param database il database in cui inserirlo
|
||||||
* @param fitbit la classe che contiene i dati aggiornati
|
* @param fitbit la classe che contiene i dati aggiornati
|
||||||
@@ -97,27 +105,23 @@ public interface Database {
|
|||||||
Runnable runnable = new Runnable() {
|
Runnable runnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public synchronized void run() {
|
public synchronized void run() {
|
||||||
LOG.info("Aggiornamento giornaliero iniziato");
|
|
||||||
try {
|
try {
|
||||||
boolean retry;
|
|
||||||
long steps = fitbit.getSteps();
|
|
||||||
List<Sleep.SleepData> sleepDatas = fitbit.getDetailedSleep();
|
List<Sleep.SleepData> sleepDatas = fitbit.getDetailedSleep();
|
||||||
long now = System.currentTimeMillis();
|
boolean retry = !sleepDatas.isEmpty();
|
||||||
do {
|
do {
|
||||||
retry = !database.updateSteps(now, steps);
|
|
||||||
for (Sleep.SleepData data : sleepDatas)
|
for (Sleep.SleepData data : sleepDatas)
|
||||||
retry = retry && !database.updateSleep(data.start_date, data.duration);
|
retry = retry && !database.updateSleep(data.start_date, data.duration);
|
||||||
|
|
||||||
LOG.info("Aggiornamento " + (!retry ? "riuscito" : "fallito, riprovo fra " + retryMinutes + " minuti"));
|
LOG.info("Aggiornamento giornaliero" + (!retry ? "riuscito" : "fallito, riprovo fra " + retryMinutes + " minuti"));
|
||||||
if (retry)
|
if (retry)
|
||||||
wait(retryMinutes * MILLISEC_IN_MINUTE);
|
wait(retryMinutes * MILLISEC_IN_MINUTE);
|
||||||
} while (retry);
|
} while (retry);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.warn("Aggiornamento interrotto");
|
LOG.warn("Aggiornamento giornaliero interrotto");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return getThreadStartingEach(runnable, 24*60, "update-daily-data");
|
return getThreadStartingAt(runnable, 23, "update-daily-data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package support.database;
|
package support.database;
|
||||||
|
|
||||||
import device.fitbitdata.HeartRate;
|
import device.fitbitdata.HeartRate;
|
||||||
|
import device.fitbitdata.Steps;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -112,6 +113,29 @@ public class LocalDB implements Database {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Steps> getStepDataOfLast(int days) {
|
||||||
|
try {
|
||||||
|
int dayToSubtract = 15;
|
||||||
|
long time = System.currentTimeMillis() - (dayToSubtract * 24 * 60 * 1000);
|
||||||
|
|
||||||
|
ResultSet result = conn.createStatement().executeQuery("SELECT * FROM steps WHERE day>='" + new Timestamp(time) + "'");
|
||||||
|
List<Steps> list = new LinkedList<>();
|
||||||
|
|
||||||
|
while(result.next()) {
|
||||||
|
Steps steps = new Steps();
|
||||||
|
steps.setSteps(result.getInt("rate"));
|
||||||
|
steps.setDate(result.getDate("day").getTime());
|
||||||
|
|
||||||
|
list.add(steps);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean query(String sql) {
|
private boolean query(String sql) {
|
||||||
try {
|
try {
|
||||||
conn.createStatement().execute(sql);
|
conn.createStatement().execute(sql);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package support.database;
|
|||||||
import ai.api.GsonFactory;
|
import ai.api.GsonFactory;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import device.fitbitdata.HeartRate;
|
import device.fitbitdata.HeartRate;
|
||||||
|
import device.fitbitdata.Steps;
|
||||||
import support.Rest;
|
import support.Rest;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
@@ -73,13 +74,7 @@ public class RemoteDB implements Database {
|
|||||||
@Override
|
@Override
|
||||||
public List<HeartRate> getHeartDataOfLast(int days) {
|
public List<HeartRate> getHeartDataOfLast(int days) {
|
||||||
try {
|
try {
|
||||||
Calendar ago = Calendar.getInstance();
|
String url = base_url+"heartbeat/"+username+"/last/"+(days*24);
|
||||||
ago.setTimeInMillis(System.currentTimeMillis());
|
|
||||||
ago.add(Calendar.DATE, -days);
|
|
||||||
|
|
||||||
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
|
||||||
|
|
||||||
String url = base_url+"heartbeat/"+username+"/"+format.format(ago.getTime())+"/today/";
|
|
||||||
Map<String, List<Map<String, Object>>> map = (Map<String, List<Map<String, Object>>>) Rest.get(url);
|
Map<String, List<Map<String, Object>>> map = (Map<String, List<Map<String, Object>>>) Rest.get(url);
|
||||||
|
|
||||||
List<HeartRate> list = new ArrayList<>(map.get("list").size());
|
List<HeartRate> list = new ArrayList<>(map.get("list").size());
|
||||||
@@ -97,6 +92,27 @@ public class RemoteDB implements Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Steps> getStepDataOfLast(int days) {
|
||||||
|
try {
|
||||||
|
String url = base_url+"step/"+username+"/last/"+(days*24);
|
||||||
|
Map<String, List<Map<String, Object>>> map = (Map<String, List<Map<String, Object>>>) Rest.get(url);
|
||||||
|
|
||||||
|
List<Steps> list = new ArrayList<>(map.get("list").size());
|
||||||
|
for(Map<String, Object> data: map.get("list")) {
|
||||||
|
Steps steps = new Steps();
|
||||||
|
steps.setSteps((int)data.get("value"));
|
||||||
|
steps.setDate(STD_FORMAT.parse((String)data.get("time")).getTime());
|
||||||
|
|
||||||
|
list.add(steps);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
LOG.error(e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serve ad inviare una richiesta PUT per aggiornare i dati
|
* Serve ad inviare una richiesta PUT per aggiornare i dati
|
||||||
* @param type il tipo di dato che deve esser aggiornato
|
* @param type il tipo di dato che deve esser aggiornato
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package test;
|
|||||||
|
|
||||||
import device.Fitbit;
|
import device.Fitbit;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import support.Rest;
|
||||||
|
|
||||||
public class TestFitbit {
|
public class TestFitbit {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test01() throws Exception {
|
public void test01() throws Exception {
|
||||||
Fitbit fitBit = new Fitbit();
|
Fitbit fitBit = new Fitbit();
|
||||||
@@ -14,5 +15,13 @@ public class TestFitbit {
|
|||||||
System.out.println("Today's hours of sleep: "+fitBit.getHoursSleep());
|
System.out.println("Today's hours of sleep: "+fitBit.getHoursSleep());
|
||||||
System.out.println("Today's steps: "+fitBit.getSteps());
|
System.out.println("Today's steps: "+fitBit.getSteps());
|
||||||
System.out.println("Fine.");
|
System.out.println("Fine.");
|
||||||
|
|
||||||
|
Rest.get("https://api.fitbit.com/1/user/-/activities/steps/date/today/1d.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test02() throws Exception {
|
||||||
|
Fitbit fitbit = new Fitbit();
|
||||||
|
System.out.println(fitbit.getSteps(60));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package test;
|
package test;
|
||||||
|
|
||||||
import ai.api.GsonFactory;
|
|
||||||
import device.Hue;
|
import device.Hue;
|
||||||
import main.VariousThreads;
|
import main.VariousThreads;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -51,12 +50,10 @@ public class TestLights {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
synchronized public void testColor() throws InterruptedException {
|
synchronized public void testColor() throws InterruptedException {
|
||||||
// change colors
|
String[] colors = {"rosso", "giallo", "verde", "blu", "bianco", "azzurro", "arancio"};
|
||||||
for (int i=0; i<=360; i++) {
|
|
||||||
double radian = (0.0174533*i);
|
for (String color : colors) {
|
||||||
double x = Math.cos(radian);
|
lights.changeColor(color);
|
||||||
double y = Math.sin(radian);
|
|
||||||
lights.setState("xy", GsonFactory.getDefaultFactory().getGson().toJson(new Double[]{x, y}));
|
|
||||||
this.wait(TIMEOUT);
|
this.wait(TIMEOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,18 @@ public class TestMusich {
|
|||||||
audio.stop();
|
audio.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
AudioFile audio = new AudioFile();
|
||||||
|
AudioFile audio2 = new AudioFile();
|
||||||
|
audio.play("Tullio.wav");
|
||||||
|
waitAndPrint(3);
|
||||||
|
audio2.play("Tullio.wav");
|
||||||
|
waitAndPrint(10);
|
||||||
|
audio.stop();
|
||||||
|
audio2.stop();
|
||||||
|
}
|
||||||
|
|
||||||
public void waitAndPrint(Integer seconds) {
|
public void waitAndPrint(Integer seconds) {
|
||||||
if(seconds != null) synchronized (seconds) {
|
if(seconds != null) synchronized (seconds) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user