Skip to content
Snippets Groups Projects
Commit 310ab641 authored by René Schöne's avatar René Schöne
Browse files

Merge branch 'learner' into 'dev'

Integration of Learner

See merge request !3
parents 4221d160 0d9f3fc2
Branches
No related tags found
No related merge requests found
Showing
with 337 additions and 30 deletions
.gradle/
.idea/
build/dependencyUpdates/
venv/
*/out/
logs/
/build/
logs/
apply plugin: 'application'
dependencies {
compile project(':eraser-base')
compile project(':feedbackloop.learner_backup')
compile project(':datasets')
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.hamcrest/java-hamcrest
// https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core
testCompile group: 'org.hamcrest', name: 'hamcrest-core', version: '1.3'
implementation group: 'com.opencsv', name: 'opencsv', version: '4.1'
// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.0-alpha4'
testCompile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.2'
// https://mvnrepository.com/artifact/org.apache.httpcomponents/fluent-hc
compile group: 'org.apache.httpcomponents', name: 'fluent-hc', version: '4.2.1'
// https://mvnrepository.com/artifact/junit/junit
testCompile group: 'junit', name: 'junit', version: '4.4'
}
run {
mainClassName = 'de.tudresden.inf.st.eraser.benchmark.Main'
standardInput = System.in
if (project.hasProperty("appArgs")) {
args Eval.me(appArgs)
}
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
}
}
package de.tudresden.inf.st.eraser.benchmark;
import com.opencsv.CSVReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.FileReader;
import java.util.Arrays;
public class Benchmark {
//read every 5 s from csv
//activity CSV
/**
* Col 1: smartphone acceleration x
* Col 2: smartphone acceleration y
* Col 3: smartphone acceleration z
* Col 4: smartphone rotation x
* Col 5: smartphone rotation y
* Col 6: smartphone rotation z
* Col 7: watch acceleration x
* Col 8: watch acceleration y
* Col 9: watch acceleration z
* Col 10: watch rotation x
* Col 11: watch rotation y
* Col 12: watch rotation z/*/
//preference CSV
/**
* Col 1: Activity
* Col 2: watch brightness range "bright, medium, dimmer, dark"*/
private String a_csv_file_path;
private String p_csv_file_path;
private static final Logger logger = LogManager.getLogger(Benchmark.class);
private static final String ERASER_ITEM_URI = "http://localhost:4567/model/items/";
//TODO ITEM_NAME HAS TO BE DISCUSSED
private static final String[] ACTIVITY_ITEM_NAME = {
"m_accel_x", "m_accel_y", "m_accel_z", "m_rotation_x",
"m_rotation_y", "m_rotation_z", "w_accel_x", "w_accel_y",
"w_accel_z", "w_rotation_x", "w_rotation_y", "w_rotation_z"};
private static final String[] PREFERENCE_ITEM_NAME = {
"w_brightness"
};
private static boolean flag2 = true;
//csv_type is activity or preference
Benchmark(String a_csv_file_path, String p_csv_file_path) {
this.a_csv_file_path = a_csv_file_path;
this.p_csv_file_path = p_csv_file_path;
}
void start(){
String PREFERENCE_URL = "http://localhost:4567/model/items/iris1_item/state";
String ACTIVITY_URL = "http://localhost:4567/activity/current";
int TIME_PERIOD = 5000;
File a_file;
File p_file;
FileReader a_file_reader;
FileReader p_file_reader;
CSVReader a_csv_reader;
CSVReader p_csv_reader;
String[] a_next_record;
String[] p_next_record;
boolean flag1;
a_file=new File(a_csv_file_path);
p_file= new File(p_csv_file_path);
try {
a_file_reader =new FileReader(a_file);
p_file_reader=new FileReader(p_file);
a_csv_reader = new CSVReader(a_file_reader);
p_csv_reader = new CSVReader(p_file_reader);
while ((((a_next_record = a_csv_reader.readNext())!= null) && flag2)){
try{Thread.sleep(TIME_PERIOD);}catch (InterruptedException e){e.printStackTrace();}
String[] values = Arrays.copyOf(a_next_record,12);
setNewValue(values, ACTIVITY_ITEM_NAME,"activity");
HttpResponse response= Request.Get(ACTIVITY_URL).execute().returnResponse();
String status = response.getStatusLine().toString();
if(status.contains("200")){
flag1 = true;
logger.info("activity should be (read direct from CSV): " + a_next_record[12]);
logger.info(EntityUtils.toString(response.getEntity()));
logger.info("get activity from web server: response 200 ok");
}else{
flag1 = false;
flag2 = false;
logger.info("can not get the activity from the web server");
}
while((((p_next_record = p_csv_reader.readNext()) != null) && flag1)) {
try{Thread.sleep(TIME_PERIOD);}catch (InterruptedException e){e.printStackTrace();}
String[] values1 = Arrays.copyOf(p_next_record,2);
setNewValue(values1, PREFERENCE_ITEM_NAME,"preference");
HttpResponse response1= Request.Get(PREFERENCE_URL).execute().returnResponse();
String status1=response1.getStatusLine().toString();
if(status1.contains("200")){
flag2 = true;
logger.info("get the iris1_item preference from web server: response 200 ok, value is: "+EntityUtils.toString(response1.getEntity()));
}else {flag2 = false;
logger.info("can not get the iris1_item from the web server");}
break;
}
}
}
catch (Exception e){
e.printStackTrace();
}
}
private void setNewValue(String[] values, String[] name, String file_typ){
if(file_typ.equals("activity"))
{
int i = 0;
for(String value : values){
String uri = ERASER_ITEM_URI + name[i] + "/state";
try {
HttpResponse httpResponse = Request.Put(uri)
.bodyString(value, ContentType.TEXT_PLAIN)
.execute().returnResponse();
String status=httpResponse.getStatusLine().toString();
if(status.contains("200")){
logger.info("put activity input name: "+name[i]+", value: "+value+"to web server: response 200 ok");
}else{
logger.info("can not put activity inputs to rest server");
}
}catch (Exception e){
e.printStackTrace();
}
i+=1;
}
}else{
String uri= ERASER_ITEM_URI + "w_brightness" +"/state";
try {
HttpResponse httpResponse = Request.Put(uri)
.bodyString(values[1], ContentType.TEXT_PLAIN)
.execute().returnResponse();
String put_response=httpResponse.getStatusLine().toString();
if (put_response.contains("200")){logger.info("put w_brightness to web server: response 200 ok");}else{
logger.info("can not put w_brightness to rest server");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
\ No newline at end of file
package de.tudresden.inf.st.eraser.benchmark;
public class Main {
public static void main(String[] args) {
String A_CSV_FILE_PATH = "../datasets/backup/activity_data.csv";
String P_CSV_FILE_PATH = "../datasets/backup/preference_data.csv";
Benchmark benchmark=new Benchmark(A_CSV_FILE_PATH,P_CSV_FILE_PATH);
benchmark.start();
}
}
......@@ -118,6 +118,7 @@ task copyRagdoc(type: Copy, dependsOn: cleanRagdoc) {
}
generateAst.dependsOn preprocess
generateAst.inputs.files file("./src/main/jastadd/mainGen.ast"), file("./src/main/jastadd/mainGen.jadd")
//compileJava.dependsOn jastadd
//
//// always run jastadd
......
......@@ -10,12 +10,19 @@ aspect ItemHandling {
public void Item.enableSendState() { sendState = true; }
public final boolean Item.isSendState() { return sendState; }
//--- DateTimeItem.ALTERNATIVE_FORMAT ---
private static final java.time.format.DateTimeFormatter DateTimeItem.ALTERNATIVE_FORMAT = new java.time.format.DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.toFormatter()
.withZone(java.time.ZoneId.of("UTC"));
//--- getStateAsString ---
syn String Item.getStateAsString();
eq ColorItem.getStateAsString() = getState().toString();
eq DateTimeItem.getStateAsString() = getState().toString();
eq ItemWithBooleanState.getStateAsString() = Boolean.toString(getState());
eq SwitchItem.getStateAsString() = getState() ? "ON" : "OFF";
eq ContactItem.getStateAsString() = getState() ? "OPEN" : "CLOSED";
eq ItemWithDoubleState.getStateAsString() = Double.toString(getState());
eq ItemWithStringState.getStateAsString() = getState();
......@@ -50,19 +57,24 @@ aspect ItemHandling {
}
}
public void DateTimeItem.setStateFromString(String value) {
Exception exception = null;
// try normal instant parsing. Format example: 2019-07-22T12:58:08.960Z
try {
this.setState(Instant.parse(value));
} catch (java.time.format.DateTimeParseException e1) {
return;
} catch (java.time.format.DateTimeParseException e) { /* empty */ }
// try openHAB parsing. Format example: 2019-07-22T12:58:08.960+0000
try {
this.setState(ALTERNATIVE_FORMAT.parse(value, Instant::from));
return;
} catch (java.time.format.DateTimeParseException e) { /* empty */ }
// try to read input as number and use that
try {
long time = Long.parseLong(value);
this.setStateFromLong(time);
// exit the method to avoid printing the error message for e1
return;
} catch (NumberFormatException e2) {
logger.catching(e2);
}
logger.catching(e1);
} catch (NumberFormatException e) {
logger.warn("Could not parse date value from {}", value);
}
}
public void ItemWithBooleanState.setStateFromString(String value) {
......@@ -75,6 +87,20 @@ aspect ItemHandling {
default: super.setStateFromString(value);
}
}
public void ContactItem.setStateFromString(String value) {
switch (value) {
case "OPEN": this.setState(true); break;
case "CLOSED": this.setState(false); break;
default: super.setStateFromString(value);
}
}
public void RollerShutterItem.setStateFromString(String value) {
switch (value) {
case "UP": this.setState(0); break;
case "DOWN": this.setState(100); break;
default: super.setStateFromString(value);
}
}
public void ItemWithDoubleState.setStateFromString(String value) {
this.setState(Double.parseDouble(value));
}
......@@ -288,7 +314,7 @@ aspect ItemHandling {
//--- sendState ---
protected void Item.sendState() throws Exception {
for (MachineLearningModel model : getRelevantInMachineLearningModels()) {
model.getEncoder().newData(getRoot(), java.util.Collections.singletonList(this));
model.getEncoder().newData(Collections.singletonList(this));
}
}
......
aspect Logging {
// Base
protected org.apache.logging.log4j.Logger Item.logger = org.apache.logging.log4j.LogManager.getLogger(Item.class);
protected org.apache.logging.log4j.Logger ItemPreference.logger = org.apache.logging.log4j.LogManager.getLogger(ItemPreference.class);
protected org.apache.logging.log4j.Logger Neuron.logger = org.apache.logging.log4j.LogManager.getLogger(Neuron.class);
// MachineLearning
private org.apache.logging.log4j.Logger DummyMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(DummyMachineLearningModel.class);
private org.apache.logging.log4j.Logger Rule.logger = org.apache.logging.log4j.LogManager.getLogger(Rule.class);
private org.apache.logging.log4j.Logger MqttRoot.logger = org.apache.logging.log4j.LogManager.getLogger(MqttRoot.class);
private org.apache.logging.log4j.Logger InternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(MachineLearningModel.class);
private org.apache.logging.log4j.Logger InternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(InternalMachineLearningModel.class);
private org.apache.logging.log4j.Logger ExternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(ExternalMachineLearningModel.class);
// NeuralNetwork
private org.apache.logging.log4j.Logger NeuralNetworkRoot.logger = org.apache.logging.log4j.LogManager.getLogger(NeuralNetworkRoot.class);
private org.apache.logging.log4j.Logger OutputLayer.logger = org.apache.logging.log4j.LogManager.getLogger(OutputLayer.class);
protected org.apache.logging.log4j.Logger Neuron.logger = org.apache.logging.log4j.LogManager.getLogger(Neuron.class);
// Rules
private org.apache.logging.log4j.Logger Rule.logger = org.apache.logging.log4j.LogManager.getLogger(Rule.class);
// MQTT
private org.apache.logging.log4j.Logger MqttRoot.logger = org.apache.logging.log4j.LogManager.getLogger(MqttRoot.class);
}
......@@ -112,7 +112,8 @@ aspect MachineLearning {
@Override
public boolean ExternalMachineLearningModel.check() {
throw new UnsupportedOperationException("check not available for external ML models (yet)!");
logger.warn("check not available for external ML models (yet)!");
return true;
}
//--- mlKind ---
......@@ -160,7 +161,33 @@ aspect MachineLearning {
return this.decoder;
}
// refine Item.stateUpdated
}
aspect ChangeEvents {
private static final java.util.concurrent.atomic.AtomicInteger ChangeEvent.idCounter = new java.util.concurrent.atomic.AtomicInteger(0);
//--- createRecognitionEvent ---
public static RecognitionEvent RecognitionEvent.createRecognitionEvent(MachineLearningModel modelOfRecognition) {
RecognitionEvent result = new RecognitionEvent();
result.initChangeEvent();
for (Item relevantItem : modelOfRecognition.getRelevantItems()) {
result.addChangedItem(ChangedItem.newFromItem(relevantItem));
}
return result;
}
//--- newFromItem ---
public static ChangedItem ChangedItem.newFromItem(Item source) {
ChangedItem result = new ChangedItem();
result.setItem(source);
result.setNewStateAsString(source.getStateAsString());
return result;
}
//--- initChangeEvent ---
protected void ChangeEvent.initChangeEvent() {
this.setCreated(Instant.now());
this.setIdentifier(idCounter.incrementAndGet());
}
}
......@@ -3,7 +3,7 @@ MachineLearningRoot ::= [ActivityRecognition:MachineLearningModel] [PreferenceLe
Activity ::= <Identifier:int> <Label:String> ;
abstract ChangeEvent ::= <Identifier:int> <Timestamp:long> ChangedItem* ;
abstract ChangeEvent ::= <Identifier:int> <Created:Instant> ChangedItem* ;
ChangedItem ::= <NewStateAsString:String> ;
rel ChangedItem.Item -> Item ;
......
......@@ -207,4 +207,29 @@ aspect Printing {
.build();
}
// Expressions
syn String ParenthesizedNumberExpression.prettyPrint() = "(" + getOperand().prettyPrint() + ")";
syn String NumberLiteralExpression.prettyPrint() = Double.toString(getValue());
syn String AddExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " + " + getRightOperand().prettyPrint() + ")";
syn String SubExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " - " + getRightOperand().prettyPrint() + ")";
syn String MultExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " * " + getRightOperand().prettyPrint() + ")";
syn String DivExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " / " + getRightOperand().prettyPrint() + ")";
syn String PowerExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " ^ " + getRightOperand().prettyPrint() + ")";
syn String ParenthesizedLogicalExpression.prettyPrint() = "(" + getOperand().prettyPrint() + ")";
syn String NotExpression.prettyPrint() = "!" + getOperand().prettyPrint();
syn String ComparingExpression.prettyPrint() {
switch (getComparator()) {
case NotEquals: return "(" + getLeftOperand().prettyPrint() + " != " + getRightOperand().prettyPrint() + ")";
case Equals: return "(" + getLeftOperand().prettyPrint() + " == " + getRightOperand().prettyPrint() + ")";
case LessThan: return "(" + getLeftOperand().prettyPrint() + " < " + getRightOperand().prettyPrint() + ")";
case GreaterThan: return "(" + getLeftOperand().prettyPrint() + " > " + getRightOperand().prettyPrint() + ")";
case LessOrEqualThan: return "(" + getLeftOperand().prettyPrint() + " <= " + getRightOperand().prettyPrint() + ")";
case GreaterOrEqualThan: return "(" + getLeftOperand().prettyPrint() + " >= " + getRightOperand().prettyPrint() + ")";
default: throw new IllegalArgumentException("Unknown compartor type: " + getComparator());
}
}
syn String AndExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " & " + getRightOperand().prettyPrint() + ")";
syn String OrExpression.prettyPrint() = "(" + getLeftOperand().prettyPrint() + " | " + getRightOperand().prettyPrint() + ")";
syn String Designator.prettyPrint() = getItem().getID();
}
......@@ -6,6 +6,7 @@ aspect Util {
// }
public void MqttRoot.setHostByName(String hostName) {
setHost(ExternalHost.of(hostName, DEFAULT_PORT));
flushCache();
}
public void InfluxRoot.setHostByName(String hostName) {
......
......@@ -106,7 +106,7 @@ Comment = "//" [^\n\r]+
"<=" { return sym(Terminals.LE); }
"==" { return sym(Terminals.EQ); }
"!=" { return sym(Terminals.NE); }
"=>" { return sym(Terminals.GE); }
">=" { return sym(Terminals.GE); }
">" { return sym(Terminals.GT); }
"+" { return sym(Terminals.PLUS); }
"*" { return sym(Terminals.MULT); }
......
......@@ -74,4 +74,14 @@ aspect MQTT {
getMqttRoot().getMqttSender().publish(getOutgoingTopic(), message);
}
refine OpenHAB2 public void OpenHAB2Model.addNewItem(Item item) {
refined(item);
// update mqtt-topic to new mqtt-root
JavaUtils.ifPresentOrElse(
getRoot().getMqttRoot().resolveTopicSuffix(item.getTopic().getTopicString()),
topic -> item.setTopic(topic),
() -> de.tudresden.inf.st.eraser.util.ParserUtils.createMqttTopic(item, item.getTopic().getTopicString(), getRoot())
);
}
}
......@@ -2,4 +2,12 @@ aspect OpenHAB2 {
syn ActivityItem OpenHAB2Model.getActivityItem() {
return new ActivityItem();
}
public void OpenHAB2Model.addNewItem(Item item) {
JavaUtils.ifPresentOrElse(
resolveGroup(de.tudresden.inf.st.eraser.util.ParserUtils.UNKNOWN_GROUP_NAME),
group -> group.addItem(item),
() -> de.tudresden.inf.st.eraser.util.ParserUtils.createUnknownGroup(this, Collections.singletonList(item)));
}
}
......@@ -40,7 +40,7 @@ ImageItem : ItemWithStringState ;
LocationItem : ItemWithStringState ;
NumberItem : ItemWithDoubleState ;
PlayerItem : ItemWithStringState ;
RollerShutterItem : ItemWithBooleanState ;
RollerShutterItem : ItemWithDoubleState ;
StringItem : ItemWithStringState ;
SwitchItem : ItemWithBooleanState ;
DefaultItem : ItemWithStringState ;
......
......@@ -22,7 +22,12 @@ public class InternalMachineLearningHandler implements MachineLearningEncoder, M
}
@Override
public void newData(Root model, List<Item> changedItems) {
public void setKnowledgeBaseRoot(Root root) {
// ignored
}
@Override
public void newData(List<Item> changedItems) {
logger.debug("Ignored new data of {}", changedItems);
}
......
......@@ -9,7 +9,7 @@ import java.time.Instant;
* @author rschoene - Initial contribution
*/
@SuppressWarnings("unused")
public interface MachineLearningDecoder {
public interface MachineLearningDecoder extends MachineLearningSetRoot {
/**
* Execute the machine learning model and returns the classification result.
......
package de.tudresden.inf.st.eraser.jastadd.model;
import de.tudresden.inf.st.eraser.jastadd.model.Item;
import de.tudresden.inf.st.eraser.jastadd.model.Root;
import java.util.List;
/**
......@@ -13,14 +10,13 @@ import java.util.List;
* @author rschoene - Initial contribution
*/
@SuppressWarnings("unused")
public interface MachineLearningEncoder {
public interface MachineLearningEncoder extends MachineLearningSetRoot {
/**
* Update when new data is available.
* @param model The underlying model
* @param changedItems A list of items whose state has changed
*/
void newData(Root model, List<Item> changedItems);
void newData(List<Item> changedItems);
// to be discussed, in which form this is specified
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment