From 472ca9776db7fa0be6535ff0cc59e5c9b8a7bbd4 Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Thu, 2 May 2019 16:33:09 +0200 Subject: [PATCH] Working on Separation of Trees. - Begin to integrate ML adapters, see issue #13 - Create separate tree for openhab - Separate concrete ML models into different grammar files - This partly makes issue #7 obsolete (ML-Model still needs to be renamed) --- .../src/main/jastadd/DecisionTree.jrag | 10 +- .../src/main/jastadd/DecisionTree.relast | 12 +++ eraser-base/src/main/jastadd/Logging.jadd | 2 +- .../src/main/jastadd/MachineLearning.jrag | 62 +++++++++++-- .../src/main/jastadd/MachineLearning.relast | 40 +------- .../src/main/jastadd/ModelStatistics.jrag | 4 +- eraser-base/src/main/jastadd/Navigation.jrag | 33 ++++--- .../src/main/jastadd/NeuralNetwork.jrag | 2 +- .../src/main/jastadd/NeuralNetwork.relast | 20 ++++ eraser-base/src/main/jastadd/Printing.jrag | 14 ++- eraser-base/src/main/jastadd/Util.jrag | 3 +- eraser-base/src/main/jastadd/eraser.parser | 8 +- eraser-base/src/main/jastadd/main.relast | 3 +- eraser-base/src/main/jastadd/openhab.jrag | 5 + eraser-base/src/main/jastadd/openhab.relast | 3 +- .../java/de/tudresden/inf/st/eraser/Main.java | 8 +- .../deserializer/ASTNodeDeserializer.java | 17 +++- .../model/InternalMachineLearningHandler.java | 54 +++++++++++ .../model/InternalMachineLearningResult.java | 21 +++++ .../model}/MachineLearningDecoder.java | 2 +- .../model}/MachineLearningEncoder.java | 2 +- .../jastadd/model}/MachineLearningResult.java | 2 +- .../st/eraser/openhab2/OpenHab2Importer.java | 28 ++---- .../st/eraser/parser/EraserParserHelper.java | 19 ++-- .../inf/st/eraser/util/ParserUtils.java | 7 +- .../inf/st/eraser/util/TestUtils.java | 16 ++-- .../inf/st/eraser/ControllingItemTest.java | 2 +- .../inf/st/eraser/DecisionTreeTest.java | 6 +- .../tudresden/inf/st/eraser/InfluxTest.java | 12 ++- .../de/tudresden/inf/st/eraser/MqttTests.java | 55 +++++------ .../inf/st/eraser/NeuralNetworkTest.java | 2 +- .../inf/st/eraser/OpenHabImporterTest.java | 5 +- .../tudresden/inf/st/eraser/ParserTests.java | 20 ++-- .../de/tudresden/inf/st/eraser/RulesTest.java | 92 +++++++++---------- .../eraser/jastadd_test/core/TestRunner.java | 17 ++-- .../resources/openhabtest/oh1/output.eraser | 2 - .../resources/openhabtest/oh2/output.eraser | 2 - 37 files changed, 373 insertions(+), 239 deletions(-) create mode 100644 eraser-base/src/main/jastadd/DecisionTree.relast create mode 100644 eraser-base/src/main/jastadd/NeuralNetwork.relast create mode 100644 eraser-base/src/main/jastadd/openhab.jrag create mode 100644 eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java create mode 100644 eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java rename {feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api => eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model}/MachineLearningDecoder.java (93%) rename {feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api => eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model}/MachineLearningEncoder.java (96%) rename {feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api => eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model}/MachineLearningResult.java (91%) diff --git a/eraser-base/src/main/jastadd/DecisionTree.jrag b/eraser-base/src/main/jastadd/DecisionTree.jrag index e8d3ae67..f50ca056 100644 --- a/eraser-base/src/main/jastadd/DecisionTree.jrag +++ b/eraser-base/src/main/jastadd/DecisionTree.jrag @@ -4,20 +4,20 @@ aspect DecisionTree { public class DecisionTreeLeaf implements Leaf { } //--- classify --- - syn Leaf DecisionTreeRoot.classify() { + syn DecisionTreeLeaf DecisionTreeRoot.classify() { return getRootRule().classify(); } - syn Leaf DecisionTreeElement.classify(); + syn DecisionTreeLeaf DecisionTreeElement.classify(); - syn Leaf DecisionTreeRule.classify(); + syn DecisionTreeLeaf DecisionTreeRule.classify(); - syn Leaf ItemStateCheckRule.classify() { + syn DecisionTreeLeaf ItemStateCheckRule.classify() { boolean chooseLeft = getItemStateCheck().holds(); return (chooseLeft ? getLeft() : getRight()).classify(); } - syn Leaf DecisionTreeLeaf.classify() = this; + syn DecisionTreeLeaf DecisionTreeLeaf.classify() = this; //--- holds --- syn boolean ItemStateCheck.holds() = holdsFor(getItem()); diff --git a/eraser-base/src/main/jastadd/DecisionTree.relast b/eraser-base/src/main/jastadd/DecisionTree.relast new file mode 100644 index 00000000..17a1e65c --- /dev/null +++ b/eraser-base/src/main/jastadd/DecisionTree.relast @@ -0,0 +1,12 @@ +// ---------------- Decision Tree ------------------------------ +DecisionTreeRoot : InternalMachineLearningModel ::= RootRule:DecisionTreeRule ; +abstract DecisionTreeElement ::= Preference:ItemPreference*; +abstract DecisionTreeRule : DecisionTreeElement ::= Left:DecisionTreeElement Right:DecisionTreeElement <Label:String> ; +ItemStateCheckRule : DecisionTreeRule ::= ItemStateCheck ; + +abstract ItemStateCheck ::= <Comparator:ComparatorType> ; +rel ItemStateCheck.Item -> Item ; + +ItemStateNumberCheck : ItemStateCheck ::= <Value:double> ; +ItemStateStringCheck : ItemStateCheck ::= <Value:String> ; +DecisionTreeLeaf : DecisionTreeElement ::= <ActivityIdentifier:int> <Label:String> ; diff --git a/eraser-base/src/main/jastadd/Logging.jadd b/eraser-base/src/main/jastadd/Logging.jadd index 55c48fc5..dd41bc70 100644 --- a/eraser-base/src/main/jastadd/Logging.jadd +++ b/eraser-base/src/main/jastadd/Logging.jadd @@ -6,7 +6,7 @@ aspect Logging { 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 MachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(MachineLearningModel.class); + private org.apache.logging.log4j.Logger InternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(MachineLearningModel.class); 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); } diff --git a/eraser-base/src/main/jastadd/MachineLearning.jrag b/eraser-base/src/main/jastadd/MachineLearning.jrag index 339cbda9..1a912dbd 100644 --- a/eraser-base/src/main/jastadd/MachineLearning.jrag +++ b/eraser-base/src/main/jastadd/MachineLearning.jrag @@ -11,7 +11,7 @@ aspect MachineLearning { List<ItemPreference> computePreferences(); } - syn Leaf MachineLearningModel.classify(); + syn Leaf InternalMachineLearningModel.classify(); //--- currentActivityName --- syn String Root.currentActivityName() = JavaUtils.ifPresentOrElseReturn( @@ -21,10 +21,20 @@ aspect MachineLearning { ); //--- currentActivity --- - syn java.util.Optional<Activity> Root.currentActivity() = resolveActivity(getMachineLearningRoot().hasActivityRecognition() ? getMachineLearningRoot().getActivityRecognition().classify().getActivityIdentifier() : -1); + syn java.util.Optional<Activity> Root.currentActivity() { + return resolveActivity(getMachineLearningRoot().hasActivityRecognition() ? + extractActivityIdentifier(getMachineLearningRoot().getActivityRecognition().getDecoder().classify().getPreferences()) : + -1); + } + private int Root.extractActivityIdentifier(List<ItemPreference> preferences) { + if (preferences.isEmpty()) { + return -1; + } + return (int) ((ItemPreferenceDouble) preferences.get(0)).getPreferredValue(); + } //--- currentPreferences --- - syn List<ItemPreference> Root.currentPreferences() = getMachineLearningRoot().getPreferenceLearning().classify().computePreferences(); + syn List<ItemPreference> Root.currentPreferences() = getMachineLearningRoot().getPreferenceLearning().getDecoder().classify().getPreferences(); //--- canSetActivity --- syn boolean MachineLearningModel.canSetActivity() = false; @@ -64,7 +74,7 @@ aspect MachineLearning { public void DummyMachineLearningModel.connectItems(List<String> itemNames) { logger.info("Storing items to connect"); for (String itemName : itemNames) { - JavaUtils.ifPresentOrElse(getRoot().resolveItem(itemName), + JavaUtils.ifPresentOrElse(getRoot().getOpenHAB2Model().resolveItem(itemName), this::addItem, () -> logger.warn("Could not resolve item '{}'", itemName)); } @@ -72,10 +82,10 @@ aspect MachineLearning { //--- check --- /** - * Checks the NeuralNetwork for all necessary children. + * Checks the ML model for all necessary children. * @return true, if everything is alright. false otherwise */ - public boolean MachineLearningModel.check() { + public boolean InternalMachineLearningModel.check() { boolean good = true; if (getOutputApplication() == null) { logger.warn("{}: OutputApplication function is null!", mlKind()); @@ -114,4 +124,44 @@ aspect MachineLearning { ); } + //... ExternalMachineLearningModel ... + private MachineLearningEncoder ExternalMachineLearningModel.encoder; + public void ExternalMachineLearningModel.setEncoder(MachineLearningEncoder encoder) { + this.encoder = encoder; + } + private MachineLearningDecoder ExternalMachineLearningModel.decoder; + public void ExternalMachineLearningModel.setDecoder(MachineLearningDecoder decoder) { + this.decoder = decoder; + } +// eq ExternalMachineLearningModel.classify() = null; + public void ExternalMachineLearningModel.connectItems(List<String> itemNames) { } + + //... InternalMachineLearningModel ... + syn InternalMachineLearningHandler InternalMachineLearningModel.handler() { + return new InternalMachineLearningHandler().setModel(this); + } + cache InternalMachineLearningModel.handler(); + + //--- getEncoder --- + public abstract MachineLearningEncoder MachineLearningModel.getEncoder(); + @Override + public MachineLearningEncoder InternalMachineLearningModel.getEncoder() { + return handler(); + } + @Override + public MachineLearningEncoder ExternalMachineLearningModel.getEncoder() { + return this.encoder; + } + + //--- getDecoder --- + public abstract MachineLearningDecoder MachineLearningModel.getDecoder(); + @Override + public MachineLearningDecoder InternalMachineLearningModel.getDecoder() { + return handler(); + } + @Override + public MachineLearningDecoder ExternalMachineLearningModel.getDecoder() { + return this.decoder; + } + } diff --git a/eraser-base/src/main/jastadd/MachineLearning.relast b/eraser-base/src/main/jastadd/MachineLearning.relast index 4f00aa9c..01014656 100644 --- a/eraser-base/src/main/jastadd/MachineLearning.relast +++ b/eraser-base/src/main/jastadd/MachineLearning.relast @@ -13,44 +13,14 @@ rel RecognitionEvent.Activity -> Activity ; ManualChangeEvent : ChangeEvent ; -abstract MachineLearningModel ::= <OutputApplication:DoubleDoubleFunction> ; +abstract MachineLearningModel ::= ; +ExternalMachineLearningModel : MachineLearningModel ; +abstract InternalMachineLearningModel : MachineLearningModel ::= <OutputApplication:DoubleDoubleFunction> ; +rel InternalMachineLearningModel.RelevantItem* -> Item ; +rel InternalMachineLearningModel.TargetItem* -> Item ; abstract ItemPreference ::= ; rel ItemPreference.Item -> Item ; ItemPreferenceColor : ItemPreference ::= <PreferredHSB:TupleHSB> ; ItemPreferenceDouble : ItemPreference ::= <PreferredValue:double> ; - -// ---------------- Decision Tree ------------------------------ -DecisionTreeRoot : MachineLearningModel ::= RootRule:DecisionTreeRule ; -abstract DecisionTreeElement ::= Preference:ItemPreference*; -abstract DecisionTreeRule : DecisionTreeElement ::= Left:DecisionTreeElement Right:DecisionTreeElement <Label:String> ; -ItemStateCheckRule : DecisionTreeRule ::= ItemStateCheck ; - -abstract ItemStateCheck ::= <Comparator:ComparatorType> ; -rel ItemStateCheck.Item -> Item ; - -ItemStateNumberCheck : ItemStateCheck ::= <Value:double> ; -ItemStateStringCheck : ItemStateCheck ::= <Value:String> ; -DecisionTreeLeaf : DecisionTreeElement ::= <ActivityIdentifier:int> <Label:String> ; - -// ---------------- Neural Network ------------------------------ -NeuralNetworkRoot : MachineLearningModel ::= InputNeuron* HiddenNeuron* OutputLayer ; - -OutputLayer ::= OutputNeuron* <Combinator:DoubleArrayDoubleFunction> ; -rel OutputLayer.AffectedItem -> Item ; - -abstract Neuron ::= Output:NeuronConnection* ; - -NeuronConnection ::= <Weight:double> ; -rel NeuronConnection.Neuron <-> Neuron.Input* ; - -InputNeuron : Neuron ; -rel InputNeuron.Item -> Item ; - -HiddenNeuron : Neuron ::= <ActivationFormula:DoubleArrayDoubleFunction> ; -BiasNeuron : HiddenNeuron ; -OutputNeuron : HiddenNeuron ::= <Label:String> ; - -DummyMachineLearningModel : MachineLearningModel ::= Current:DecisionTreeLeaf ; -rel DummyMachineLearningModel.Item* -> Item ; diff --git a/eraser-base/src/main/jastadd/ModelStatistics.jrag b/eraser-base/src/main/jastadd/ModelStatistics.jrag index 293fcd92..443635f1 100644 --- a/eraser-base/src/main/jastadd/ModelStatistics.jrag +++ b/eraser-base/src/main/jastadd/ModelStatistics.jrag @@ -1,7 +1,7 @@ aspect ModelStatistics { //--- numChannels --- - syn int Root.numChannels() { + syn int OpenHAB2Model.numChannels() { int sum = 0; for (Thing thing : getThingList()) { sum += thing.getNumChannel(); @@ -10,7 +10,7 @@ aspect ModelStatistics { } //--- description --- - syn String Root.description() = "[" + syn String OpenHAB2Model.description() = "[" + this.getNumThingType() + " thing type(s), " + this.getNumChannelType() + " channel type(s), " + this.numChannels() + " channel(s), " diff --git a/eraser-base/src/main/jastadd/Navigation.jrag b/eraser-base/src/main/jastadd/Navigation.jrag index 9aadd37e..69592c1b 100644 --- a/eraser-base/src/main/jastadd/Navigation.jrag +++ b/eraser-base/src/main/jastadd/Navigation.jrag @@ -1,36 +1,36 @@ aspect Navigation { - syn Comparator<ModelElement> Root.modelElementComparator() { + syn Comparator<ModelElement> OpenHAB2Model.modelElementComparator() { return (e1, e2) -> (e1.getID().compareTo(e2.getID())); } //--- items --- - syn java.util.List<Item> Root.items() { + syn java.util.List<Item> OpenHAB2Model.items() { java.util.List<Item> result = new java.util.ArrayList<>(); addItems(result, getGroupList()); return result; } - private void Root.addItems(java.util.List<Item> result, JastAddList<Group> groups) { + private void OpenHAB2Model.addItems(java.util.List<Item> result, JastAddList<Group> groups) { groups.forEach(group -> group.getItemList().forEach(item -> result.add(item))); } //--- parameters --- - syn java.util.Set<Parameter> Root.parameters() { + syn java.util.Set<Parameter> OpenHAB2Model.parameters() { java.util.Set<Parameter> result = new java.util.TreeSet<>(modelElementComparator()); getThingTypeList().forEach(tt -> tt.getParameterList().forEach(parameter -> result.add(parameter))); return result; } //--- channels --- - syn java.util.Set<Channel> Root.channels() { + syn java.util.Set<Channel> OpenHAB2Model.channels() { java.util.Set<Channel> result = new java.util.TreeSet<>(modelElementComparator()); getThingList().forEach(thing -> thing.getChannelList().forEach(channel -> result.add(channel))); return result; } //--- resolveThingType --- - syn java.util.Optional<ThingType> Root.resolveThingType(String thingTypeId) { + syn java.util.Optional<ThingType> OpenHAB2Model.resolveThingType(String thingTypeId) { for (ThingType thingType : this.getThingTypeList()) { if (thingType.getID().equals(thingTypeId)) { return java.util.Optional.of(thingType); @@ -40,7 +40,7 @@ aspect Navigation { } //--- resolveChannel --- - syn java.util.Optional<Channel> Root.resolveChannel(String channelId) { + syn java.util.Optional<Channel> OpenHAB2Model.resolveChannel(String channelId) { for (Thing thing : this.getThingList()) { for (Channel channel : thing.getChannelList()) { if (channel.getID().equals(channelId)) { @@ -52,7 +52,7 @@ aspect Navigation { } //--- resolveChannelType --- - syn java.util.Optional<ChannelType> Root.resolveChannelType(String channelTypeId) { + syn java.util.Optional<ChannelType> OpenHAB2Model.resolveChannelType(String channelTypeId) { for (ChannelType channelType : this.getChannelTypeList()) { if (channelType.getID().equals(channelTypeId)) { return java.util.Optional.of(channelType); @@ -62,7 +62,10 @@ aspect Navigation { } //--- resolveItem --- - syn java.util.Optional<Item> Root.resolveItem(String itemId) { + syn java.util.Optional<Item> OpenHAB2Model.resolveItem(String itemId) { + if ("activity".equals(itemId)) { + return Optional.of(getActivityItem()); + } for (Item item : items()) { if (item.getID().equals(itemId)) { return java.util.Optional.of(item); @@ -72,7 +75,7 @@ aspect Navigation { } //--- resolveGroup --- - syn java.util.Optional<Group> Root.resolveGroup(String groupId) { + syn java.util.Optional<Group> OpenHAB2Model.resolveGroup(String groupId) { for (Group group : this.getGroupList()) { if (group.getID().equals(groupId)) { return java.util.Optional.of(group); @@ -87,7 +90,7 @@ aspect Navigation { } //--- resolveItemCategory --- - syn java.util.Optional<ItemCategory> Root.resolveItemCategory(String categoryName) { + syn java.util.Optional<ItemCategory> OpenHAB2Model.resolveItemCategory(String categoryName) { for (ItemCategory category : getItemCategoryList()) { if (category.getName().equals(categoryName)) { return java.util.Optional.of(category); @@ -136,15 +139,11 @@ aspect Navigation { //--- getRoot --- inh Root ASTNode.getRoot(); - eq Root.getChannelCategory().getRoot() = this; + eq Root.getOpenHAB2Model().getRoot() = this; eq Root.getMqttRoot().getRoot() = this; eq Root.getInfluxRoot().getRoot() = this; eq Root.getMachineLearningRoot().getRoot() = this; - eq Root.getThing().getRoot() = this; - eq Root.getGroup().getRoot() = this; - eq Root.getThingType().getRoot() = this; - eq Root.getChannelType().getRoot() = this; eq Root.getRule().getRoot() = this; - eq Root.getItemCategory().getRoot() = this; eq Root.getUser().getRoot() = this; + eq Root.getLocation().getRoot() = this; } diff --git a/eraser-base/src/main/jastadd/NeuralNetwork.jrag b/eraser-base/src/main/jastadd/NeuralNetwork.jrag index d2953b92..e673b69a 100644 --- a/eraser-base/src/main/jastadd/NeuralNetwork.jrag +++ b/eraser-base/src/main/jastadd/NeuralNetwork.jrag @@ -100,7 +100,7 @@ aspect NeuralNetwork { } String itemName = itemNames.get(i); InputNeuron neuron = getInputNeuron(i); - JavaUtils.ifPresentOrElse(getRoot().resolveItem(itemName), + JavaUtils.ifPresentOrElse(getRoot().getOpenHAB2Model().resolveItem(itemName), neuron::setItem, () -> logger.warn("Could not resolve item '{}'", itemName)); } diff --git a/eraser-base/src/main/jastadd/NeuralNetwork.relast b/eraser-base/src/main/jastadd/NeuralNetwork.relast new file mode 100644 index 00000000..1214eb19 --- /dev/null +++ b/eraser-base/src/main/jastadd/NeuralNetwork.relast @@ -0,0 +1,20 @@ +// ---------------- Neural Network ------------------------------ +NeuralNetworkRoot : InternalMachineLearningModel ::= InputNeuron* HiddenNeuron* OutputLayer ; + +OutputLayer ::= OutputNeuron* <Combinator:DoubleArrayDoubleFunction> ; +rel OutputLayer.AffectedItem -> Item ; + +abstract Neuron ::= Output:NeuronConnection* ; + +NeuronConnection ::= <Weight:double> ; +rel NeuronConnection.Neuron <-> Neuron.Input* ; + +InputNeuron : Neuron ; +rel InputNeuron.Item -> Item ; + +HiddenNeuron : Neuron ::= <ActivationFormula:DoubleArrayDoubleFunction> ; +BiasNeuron : HiddenNeuron ; +OutputNeuron : HiddenNeuron ::= <Label:String> ; + +DummyMachineLearningModel : InternalMachineLearningModel ::= Current:DecisionTreeLeaf ; +rel DummyMachineLearningModel.Item* -> Item ; diff --git a/eraser-base/src/main/jastadd/Printing.jrag b/eraser-base/src/main/jastadd/Printing.jrag index 3bfa5280..3007db52 100644 --- a/eraser-base/src/main/jastadd/Printing.jrag +++ b/eraser-base/src/main/jastadd/Printing.jrag @@ -3,8 +3,17 @@ aspect Printing { String ASTNode.safeID(ModelElement elem) { return elem == null ? "NULL" : elem.getID(); } -//Root ::= Thing* Item* Group* ThingType* ChannelType* MqttRoot ; syn String Root.prettyPrint() { + StringBuilder sb = new StringBuilder(); + sb.append(getOpenHAB2Model().prettyPrint()); + sb.append(getMqttRoot().prettyPrint()); + sb.append(getInfluxRoot().prettyPrint()); + sb.append(getMachineLearningRoot().prettyPrint()); + return sb.toString(); + } + +//--- OpenHAB2Model.prettyPrint() --- + syn String OpenHAB2Model.prettyPrint() { StringBuilder sb = new StringBuilder(); for (Thing t : getThingList()) { sb.append(t.prettyPrint()); @@ -27,9 +36,6 @@ aspect Printing { for (Channel c : channels()) { sb.append(c.prettyPrint()); } - sb.append(getMqttRoot().prettyPrint()); - sb.append(getInfluxRoot().prettyPrint()); - sb.append(getMachineLearningRoot().prettyPrint()); return sb.toString(); } diff --git a/eraser-base/src/main/jastadd/Util.jrag b/eraser-base/src/main/jastadd/Util.jrag index 3876239d..282a4441 100644 --- a/eraser-base/src/main/jastadd/Util.jrag +++ b/eraser-base/src/main/jastadd/Util.jrag @@ -27,8 +27,9 @@ aspect Util { public static Root Root.createEmptyRoot() { Root model = new Root(); + model.setOpenHAB2Model(new OpenHAB2Model()); model.setMqttRoot(new MqttRoot()); - model.setInfluxRoot(new InfluxRoot()); + model.setInfluxRoot(InfluxRoot.createDefault()); model.setMachineLearningRoot(new MachineLearningRoot()); return model; } diff --git a/eraser-base/src/main/jastadd/eraser.parser b/eraser-base/src/main/jastadd/eraser.parser index dbd6457e..acd54d7c 100644 --- a/eraser-base/src/main/jastadd/eraser.parser +++ b/eraser-base/src/main/jastadd/eraser.parser @@ -25,12 +25,12 @@ import java.util.HashMap; %goal goal; Root goal = - thing.t goal.r {: insertZero(r.getThingList(), t); return r; :} + thing.t goal.r {: insertZero(r.getOpenHAB2Model().getThingList(), t); return r; :} | item.i goal.r {: return r; :} - | group.g goal.r {: insertZero(r.getGroupList(), g); return r; :} - | thing_type.tt goal.r {: insertZero(r.getThingTypeList(), tt); return r; :} + | group.g goal.r {: insertZero(r.getOpenHAB2Model().getGroupList(), g); return r; :} + | thing_type.tt goal.r {: insertZero(r.getOpenHAB2Model().getThingTypeList(), tt); return r; :} | parameter goal.r {: return r; :} - | channel_type.ct goal.r {: insertZero(r.getChannelTypeList(), ct); return r; :} + | channel_type.ct goal.r {: insertZero(r.getOpenHAB2Model().getChannelTypeList(), ct); return r; :} | channel.c goal.r {: return r; :} | mqtt_root.mr goal.r {: r.setMqttRoot(mr); return r; :} | influx_root.ir goal.r {: r.setInfluxRoot(ir); return r; :} diff --git a/eraser-base/src/main/jastadd/main.relast b/eraser-base/src/main/jastadd/main.relast index 45dd621a..066ffbbc 100644 --- a/eraser-base/src/main/jastadd/main.relast +++ b/eraser-base/src/main/jastadd/main.relast @@ -1,6 +1,5 @@ // ---------------- Main ------------------------------ -Root ::= Thing* Group* ThingType* ChannelType* ChannelCategory* ItemCategory* User* MqttRoot InfluxRoot - MachineLearningRoot Rule* Location* ; +Root ::= OpenHAB2Model User* MqttRoot InfluxRoot MachineLearningRoot Rule* Location* ; // ---------------- Users ------------------------------ User : LabelledModelElement ; diff --git a/eraser-base/src/main/jastadd/openhab.jrag b/eraser-base/src/main/jastadd/openhab.jrag new file mode 100644 index 00000000..6d30e4b3 --- /dev/null +++ b/eraser-base/src/main/jastadd/openhab.jrag @@ -0,0 +1,5 @@ +aspect OpenHAB2 { + syn ActivityItem OpenHAB2Model.getActivityItem() { + return new ActivityItem(); + } +} diff --git a/eraser-base/src/main/jastadd/openhab.relast b/eraser-base/src/main/jastadd/openhab.relast index 6f5b378e..a5cde155 100644 --- a/eraser-base/src/main/jastadd/openhab.relast +++ b/eraser-base/src/main/jastadd/openhab.relast @@ -1,4 +1,6 @@ // ---------------- openHAB ------------------------------ +OpenHAB2Model ::= Thing* Group* ThingType* ChannelType* ChannelCategory* ItemCategory* /ActivityItem:Item/ ; + abstract ModelElement ::= <ID:String> ; abstract LabelledModelElement : ModelElement ::= <Label:String> ; abstract DescribableModelElement : LabelledModelElement ::= <Description:String> ; @@ -53,4 +55,3 @@ abstract GroupAggregationFunction ; SimpleGroupAggregationFunction : GroupAggregationFunction ::= <FunctionName:SimpleGroupAggregationFunctionName> ; ParameterizedGroupAggregationFunction : GroupAggregationFunction ::= <FunctionName:ParameterizedGroupAggregationFunctionName> <Param1:String> <Param2:String> ; - diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/Main.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/Main.java index 9b98f688..40b84e5a 100644 --- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/Main.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/Main.java @@ -16,7 +16,7 @@ import java.io.*; * Main entry point for testing eraser. * @author rschoene - Initial contribution */ -@SuppressWarnings({"unused", "WeakerAccess", "RedundantThrows"}) +@SuppressWarnings({"unused", "RedundantThrows"}) public class Main { public static void main(String[] args) throws IOException, Parser.Exception { @@ -70,7 +70,7 @@ public class Main { private static void testPrinterWith(Root model) { model.flushTreeCache(); - System.out.println("Got model: " + model.description()); + System.out.println("Got model: " + model.getOpenHAB2Model().description()); System.out.println("PrettyPrinted:"); System.out.println(model.prettyPrint()); } @@ -79,7 +79,7 @@ public class Main { Root model; // model = importFromOpenHab(); model = importFromFile(); - System.out.println("Got model: " + model.description()); + System.out.println("Got model: " + model.getOpenHAB2Model().description()); // JsonSerializer.write(model, "openhab2-data.json"); testUpdaterWith(model); } @@ -106,7 +106,7 @@ public class Main { public static Root importFromOpenHab() { OpenHab2Importer importer = new OpenHab2Importer(); - return importer.importFrom("192.168.1.250", 8080); + return importer.importFrom("192.168.1.250", 8080).getRoot(); } public static Root importFromFile() { diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/deserializer/ASTNodeDeserializer.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/deserializer/ASTNodeDeserializer.java index 95f1d470..d349331d 100644 --- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/deserializer/ASTNodeDeserializer.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/deserializer/ASTNodeDeserializer.java @@ -48,12 +48,17 @@ public class ASTNodeDeserializer extends StdDeserializer<ASTNode> { r.put(c.getName(), ((node, model) -> f.apply(model, termValue(node, terminalName)))); } + private void addResolverForOpenHAB2Model(Map<String, ResolveAstNodeForOpenHAB2Model> r, Class<?> c, BiFunction<OpenHAB2Model, String, Optional<? extends ASTNode>> f, String terminalName) { + r.put(c.getName(), ((node, model) -> f.apply(model, termValue(node, terminalName)))); + } + private Map<String, ResolveAstNode> resolvers = new HashMap<>(); + private Map<String, ResolveAstNodeForOpenHAB2Model> resolversForOpenHAB2Model = new HashMap<>(); private void initResolvers() { - addResolver(resolvers, ThingType.class, Root::resolveThingType, "ID"); - addResolver(resolvers, ChannelType.class, Root::resolveChannelType, "ID"); - addResolver(resolvers, Item.class, Root::resolveItem, "ID"); + addResolverForOpenHAB2Model(resolversForOpenHAB2Model, ThingType.class, OpenHAB2Model::resolveThingType, "ID"); + addResolverForOpenHAB2Model(resolversForOpenHAB2Model, ChannelType.class, OpenHAB2Model::resolveChannelType, "ID"); + addResolverForOpenHAB2Model(resolversForOpenHAB2Model, Item.class, OpenHAB2Model::resolveItem, "ID"); addResolver(resolvers, MqttTopic.class, Root::resolveMqttTopic, "IncomingTopic"); } @@ -363,11 +368,15 @@ public class ASTNodeDeserializer extends StdDeserializer<ASTNode> { } } - interface ResolveAstNode { Optional<? extends ASTNode> resolve(JsonNode node, Root model) throws IOException; } + +interface ResolveAstNodeForOpenHAB2Model { + Optional<? extends ASTNode> resolve(JsonNode node, OpenHAB2Model model) throws IOException; +} + class ResolveLater { JsonNode node; diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java new file mode 100644 index 00000000..2c59f46c --- /dev/null +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningHandler.java @@ -0,0 +1,54 @@ +package de.tudresden.inf.st.eraser.jastadd.model; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.time.Instant; +import java.util.List; + +/** + * Adapter for internally held machine learning models. + * + * @author rschoene - Initial contribution + */ +public class InternalMachineLearningHandler implements MachineLearningEncoder, MachineLearningDecoder { + + private static final Logger logger = LogManager.getLogger(InternalMachineLearningHandler.class); + private InternalMachineLearningModel model; + + public InternalMachineLearningHandler setModel(InternalMachineLearningModel model) { + this.model = model; + return this; + } + + @Override + public void newData(Root model, List<Item> changedItems) { + logger.debug("Ignored new data of {}", changedItems); + } + + @Override + public List<Item> getTargets() { + return model.getTargetItems(); + } + + @Override + public List<Item> getRelevantItems() { + return model.getRelevantItems(); + } + + @Override + public void triggerTraining() { + logger.debug("Ignored training trigger."); + } + + @Override + public MachineLearningResult classify() { + List<ItemPreference> preferences = model.classify().computePreferences(); + return new InternalMachineLearningResult(preferences); + } + + @Override + public Instant lastModelUpdate() { + return null; + } +} diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java new file mode 100644 index 00000000..087020b3 --- /dev/null +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/InternalMachineLearningResult.java @@ -0,0 +1,21 @@ +package de.tudresden.inf.st.eraser.jastadd.model; + +import java.util.List; + +/** + * Result of a classification returned by an internally held machine learning model. + * + * @author rschoene - Initial contribution + */ +public class InternalMachineLearningResult implements MachineLearningResult { + private final List<ItemPreference> preferences; + + InternalMachineLearningResult(List<ItemPreference> preferences) { + this.preferences = preferences; + } + + @Override + public List<ItemPreference> getPreferences() { + return this.preferences; + } +} diff --git a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningDecoder.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningDecoder.java similarity index 93% rename from feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningDecoder.java rename to eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningDecoder.java index 2c29aa28..a6e01fb9 100644 --- a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningDecoder.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningDecoder.java @@ -1,4 +1,4 @@ -package de.tudresden.inf.st.eraser.feedbackloop.api; +package de.tudresden.inf.st.eraser.jastadd.model; import java.time.Instant; diff --git a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningEncoder.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningEncoder.java similarity index 96% rename from feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningEncoder.java rename to eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningEncoder.java index dff85f27..8cf4d78f 100644 --- a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningEncoder.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningEncoder.java @@ -1,4 +1,4 @@ -package de.tudresden.inf.st.eraser.feedbackloop.api; +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; diff --git a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningResult.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningResult.java similarity index 91% rename from feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningResult.java rename to eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningResult.java index d57ccc81..eebd16d3 100644 --- a/feedbackloop.api/src/main/java/de/tudresden/inf/st/eraser/feedbackloop/api/MachineLearningResult.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/jastadd/model/MachineLearningResult.java @@ -1,4 +1,4 @@ -package de.tudresden.inf.st.eraser.feedbackloop.api; +package de.tudresden.inf.st.eraser.jastadd.model; import de.tudresden.inf.st.eraser.jastadd.model.ItemPreference; diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/openhab2/OpenHab2Importer.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/openhab2/OpenHab2Importer.java index 19f0dff8..4e1742c7 100644 --- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/openhab2/OpenHab2Importer.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/openhab2/OpenHab2Importer.java @@ -42,7 +42,7 @@ public class OpenHab2Importer { nonDefaultChannelCategories = new HashSet<>(); } - public Root importFrom(String host, int port) { + public OpenHAB2Model importFrom(String host, int port) { /* Plan: - requesting: thing-types, channel-types, things, items, links @@ -58,7 +58,8 @@ public class OpenHab2Importer { mapper.registerModule(module); try { - Root model = Root.createEmptyRoot(); + Root root = Root.createEmptyRoot(); + OpenHAB2Model model = root.getOpenHAB2Model(); ThingTypeData[] thingTypeList = mapper.readValue(makeURL(thingTypesUrl, hostAndPort), ThingTypeData[].class); logger.info("Read a total of {} thing type(s).", thingTypeList.length); update(model, thingTypeList); @@ -84,17 +85,6 @@ public class OpenHab2Importer { ThingTypeData data = mapper.readValue(makeURL(thingTypeDetailUrl, hostAndPort, thingType.getID()), ThingTypeData.class); update(thingType, data); } - - // create empty MQTT root - MqttRoot mqttRoot = new MqttRoot(); - mqttRoot.setHostByName(host); - model.setMqttRoot(mqttRoot); - - // create empty Influx root - InfluxRoot influxRoot = InfluxRoot.createDefault(); - influxRoot.setHostByName(host); - model.setInfluxRoot(influxRoot); - return model; } catch (IOException e) { logger.catching(e); @@ -110,7 +100,7 @@ public class OpenHab2Importer { return URI.create(String.format(formatUrlString, hostAndPort, id)).toURL(); } - private void update(Root model, ThingTypeData[] thingTypeList) { + private void update(OpenHAB2Model model, ThingTypeData[] thingTypeList) { for (ThingTypeData thingTypeData : thingTypeList) { ThingType thingType = new ThingType(); thingType.setID(thingTypeData.UID); @@ -120,7 +110,7 @@ public class OpenHab2Importer { } } - private void update(Root model, ChannelTypeData[] channelTypeList) { + private void update(OpenHAB2Model model, ChannelTypeData[] channelTypeList) { for (ChannelTypeData channelTypeData : channelTypeList) { ChannelType channelType = new ChannelType(); channelType.setID(channelTypeData.UID); @@ -173,7 +163,7 @@ public class OpenHab2Importer { } } - private void update(Root model, ThingData[] thingList) { + private void update(OpenHAB2Model model, ThingData[] thingList) { for (ThingData thingData : thingList) { Thing thing = new Thing(); thing.setID(thingData.UID); @@ -192,7 +182,7 @@ public class OpenHab2Importer { } } - private void update(Root model, AbstractItemData[] itemList) { + private void update(OpenHAB2Model model, AbstractItemData[] itemList) { List<Tuple<Group, GroupItemData>> groupsWithMembers = new ArrayList<>(); List<Tuple<Group, GroupItemData>> groupsInGroups = new ArrayList<>(); List<Tuple<Item, AbstractItemData>> itemsInGroups = new ArrayList<>(); @@ -309,7 +299,7 @@ public class OpenHab2Importer { } } - private void update(Root model, LinkData[] linkList) { + private void update(OpenHAB2Model model, LinkData[] linkList) { for (LinkData linkData : linkList) { ifPresent(model.resolveChannel(linkData.channelUID), "Channel", linkData, channel -> ifPresent(model.resolveItem(linkData.itemName), "Item", linkData, channel::addLinkedItem)); @@ -351,7 +341,7 @@ public class OpenHab2Importer { } } - public Root importFrom(URL baseUrl) { + public OpenHAB2Model importFrom(URL baseUrl) { return importFrom(baseUrl.getHost(), baseUrl.getPort() == -1 ? baseUrl.getDefaultPort() : baseUrl.getPort()); } diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/parser/EraserParserHelper.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/parser/EraserParserHelper.java index ea392f2a..8c92ddc1 100644 --- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/parser/EraserParserHelper.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/parser/EraserParserHelper.java @@ -115,13 +115,13 @@ public class EraserParserHelper { sortedDanglingItems.add(item); } } - ParserUtils.createUnknownGroup(this.root, sortedDanglingItems); + ParserUtils.createUnknownGroup(this.root.getOpenHAB2Model(), sortedDanglingItems); } } private void createChannelCategories() { channelCategoryMap.values().stream().sorted(Comparator.comparing(this::ident)).forEach( - cc -> root.addChannelCategory(cc)); + cc -> root.getOpenHAB2Model().addChannelCategory(cc)); channelCategoryMap.clear(); } @@ -129,7 +129,7 @@ public class EraserParserHelper { Map<String, ItemCategory> newCategories = new HashMap<>(); missingItemCategoryMap.forEach((item, category) -> item.setCategory(newCategories.computeIfAbsent(category, ItemCategory::new))); - newCategories.values().forEach(root::addItemCategory); + newCategories.values().forEach(node -> root.getOpenHAB2Model().addItemCategory(node)); } private void checkUnusedElements() { @@ -417,34 +417,31 @@ public class EraserParserHelper { //--- Root --- public Root createRoot() { - this.root = new Root(); - this.root.setMqttRoot(new MqttRoot()); - this.root.setInfluxRoot(InfluxRoot.createDefault()); - this.root.setMachineLearningRoot(new MachineLearningRoot()); + this.root = Root.createEmptyRoot(); return this.root; } public Root createRoot(Thing t) { Root result = createRoot(); - result.addThing(t); + result.getOpenHAB2Model().addThing(t); return result; } public Root createRoot(Group g) { Root result = createRoot(); - result.addGroup(g); + result.getOpenHAB2Model().addGroup(g); return result; } public Root createRoot(ThingType tt) { Root result = createRoot(); - result.addThingType(tt); + result.getOpenHAB2Model().addThingType(tt); return result; } public Root createRoot(ChannelType ct) { Root result = createRoot(); - result.addChannelType(ct); + result.getOpenHAB2Model().addChannelType(ct); return result; } diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/ParserUtils.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/ParserUtils.java index 61504717..40da66ff 100644 --- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/ParserUtils.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/ParserUtils.java @@ -3,10 +3,7 @@ package de.tudresden.inf.st.eraser.util; import beaver.Parser; import beaver.Scanner; import beaver.Symbol; -import de.tudresden.inf.st.eraser.jastadd.model.Group; -import de.tudresden.inf.st.eraser.jastadd.model.Item; -import de.tudresden.inf.st.eraser.jastadd.model.MqttTopic; -import de.tudresden.inf.st.eraser.jastadd.model.Root; +import de.tudresden.inf.st.eraser.jastadd.model.*; import de.tudresden.inf.st.eraser.jastadd.parser.EraserParser; import de.tudresden.inf.st.eraser.jastadd.scanner.EraserScanner; import org.apache.logging.log4j.LogManager; @@ -172,7 +169,7 @@ public class ParserUtils { * @param model The model to operate on * @param danglingItems A list of items to add to the new group */ - public static void createUnknownGroup(Root model, Collection<Item> danglingItems) { + public static void createUnknownGroup(OpenHAB2Model model, Collection<Item> danglingItems) { Group unknownGroup = new Group(); unknownGroup.setID("Unknown"); model.addGroup(unknownGroup); diff --git a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/TestUtils.java b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/TestUtils.java index f31ffd14..5f07ec7c 100644 --- a/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/TestUtils.java +++ b/eraser-base/src/main/java/de/tudresden/inf/st/eraser/util/TestUtils.java @@ -10,9 +10,9 @@ import de.tudresden.inf.st.eraser.jastadd.model.*; public class TestUtils { public static class ModelAndItem { - public Root model; + public OpenHAB2Model model; public NumberItem item; - static ModelAndItem of(Root model, NumberItem item) { + static ModelAndItem of(OpenHAB2Model model, NumberItem item) { ModelAndItem result = new ModelAndItem(); result.model = model; result.item = item; @@ -25,21 +25,21 @@ public class TestUtils { } public static ModelAndItem createModelAndItem(double initialValue, boolean useUpdatingItem) { - Root model = Root.createEmptyRoot(); + Root root = Root.createEmptyRoot(); Group g = new Group(); - model.addGroup(g); + root.getOpenHAB2Model().addGroup(g); g.setID("group1"); NumberItem item = addItemTo(g, initialValue, useUpdatingItem); - return ModelAndItem.of(model, item); + return ModelAndItem.of(root.getOpenHAB2Model(), item); } - public static NumberItem addItemTo(Root model, double initialValue) { + public static NumberItem addItemTo(OpenHAB2Model model, double initialValue) { return addItemTo(model, initialValue, false); } - public static NumberItem addItemTo(Root model, double initialValue, boolean useUpdatingItem) { + public static NumberItem addItemTo(OpenHAB2Model model, double initialValue, boolean useUpdatingItem) { return addItemTo(getDefaultGroup(model), initialValue, useUpdatingItem); } @@ -56,7 +56,7 @@ public class TestUtils { return item; } - public static Group getDefaultGroup(Root model) { + public static Group getDefaultGroup(OpenHAB2Model model) { // use first found group return model.getGroup(0); } diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java index 612bda86..edc98e72 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java @@ -58,7 +58,7 @@ public class ControllingItemTest { @Test public void testManyToOneColor() { ModelAndItem mai = TestUtils.createModelAndItem(0); - Root model = mai.model; + OpenHAB2Model model = mai.model; NumberItem numberItem = mai.item; Group g = TestUtils.getDefaultGroup(model); diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java index 89fbacb6..fa93e069 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/DecisionTreeTest.java @@ -17,7 +17,7 @@ public class DecisionTreeTest { TestUtils.ModelAndItem mai = TestUtils.createModelAndItem(4); DecisionTreeRoot dtroot = new DecisionTreeRoot(); - mai.model.getMachineLearningRoot().setActivityRecognition(dtroot); + mai.model.getRoot().getMachineLearningRoot().setActivityRecognition(dtroot); DecisionTreeLeaf isLessThanFour = newLeaf("less than four"); DecisionTreeLeaf isFourOrGreater = newLeaf("four or greater"); ItemStateNumberCheck check = new ItemStateNumberCheck(ComparatorType.LessThan, 4f); @@ -44,7 +44,7 @@ public class DecisionTreeTest { TestUtils.ModelAndItem mai = TestUtils.createModelAndItem(20); DecisionTreeRoot dtroot = new DecisionTreeRoot(); - mai.model.getMachineLearningRoot().setActivityRecognition(dtroot); + mai.model.getRoot().getMachineLearningRoot().setActivityRecognition(dtroot); DecisionTreeLeaf isLessThan25 = newLeaf("less than 25"); DecisionTreeLeaf is25OrGreater = newLeaf("25 or greater"); @@ -130,7 +130,7 @@ public class DecisionTreeTest { TestUtils.ModelAndItem mai = TestUtils.createModelAndItem(0); DecisionTreeRoot dtroot = new DecisionTreeRoot(); - mai.model.getMachineLearningRoot().setActivityRecognition(dtroot); + mai.model.getRoot().getMachineLearningRoot().setActivityRecognition(dtroot); DecisionTreeLeaf left = newLeaf("left"); DecisionTreeLeaf right = newLeaf("right"); ItemStateNumberCheck check = new ItemStateNumberCheck(comparatorType, expected); diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java index 5fd3a3ac..4f8005be 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/InfluxTest.java @@ -95,7 +95,7 @@ public class InfluxTest { @Test public void justAdapter() { - InfluxAdapter influxAdapter = mai.model.getInfluxRoot().influxAdapter(); + InfluxAdapter influxAdapter = getInfluxRoot().influxAdapter(); Assume.assumeTrue("Adapter not connected", influxAdapter.isConnected()); influxAdapter.deleteDatabase(); @@ -151,12 +151,16 @@ public class InfluxTest { influxRoot.setDbName(InfluxTest.class.getSimpleName()); influxRoot.setHostByName("vm2098.zih.tu-dresden.de"); } - mai.model.setInfluxRoot(influxRoot); + mai.model.getRoot().setInfluxRoot(influxRoot); Assume.assumeTrue(influxRoot.influxAdapter().isConnected()); influxRoot.influxAdapter().deleteDatabase(); return mai; } + private InfluxRoot getInfluxRoot() { + return mai.model.getRoot().getInfluxRoot(); + } + private List<DoubleStatePoint> query(ItemWithDoubleState... allItems) { if (useStub) { return points; @@ -172,13 +176,13 @@ public class InfluxTest { @Before public void setNewModel() { mai = createModel(); - mai.model.getInfluxRoot().influxAdapter().disableAsyncQuery(); + getInfluxRoot().influxAdapter().disableAsyncQuery(); } @After public void closeInfluxAdapter() throws Exception { if (mai != null && mai.model != null) { - mai.model.getInfluxRoot().influxAdapter().close(); + getInfluxRoot().influxAdapter().close(); } } diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java index 237a71b4..331a9d8d 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/MqttTests.java @@ -48,21 +48,21 @@ public class MqttTests { @Test public void resolve1() { - RootItemAndTwoTopics rootAB = createAB(); - MqttRoot sut = rootAB.model.getMqttRoot(); + ModelItemAndTwoTopics modelAB = createAB(); + MqttRoot sut = modelAB.model.getRoot().getMqttRoot(); // incoming mqtt topic might be "inc/a/" or "inc/a/b" Assert.assertTrue(sut.resolveTopic("inc/a").isPresent()); - Assert.assertEquals("Could not resolve a.", rootAB.firstTopic, sut.resolveTopic("inc/a").get()); + Assert.assertEquals("Could not resolve a.", modelAB.firstTopic, sut.resolveTopic("inc/a").get()); Assert.assertTrue(sut.resolveTopic("inc/a/b").isPresent()); - Assert.assertEquals("Could not resolve a/b.", rootAB.secondTopic, sut.resolveTopic("inc/a/b").get()); + Assert.assertEquals("Could not resolve a/b.", modelAB.secondTopic, sut.resolveTopic("inc/a/b").get()); } @Test public void brokerConnected() throws Exception { - RootItemAndTwoTopics rootAB = createAB(); - MqttRoot sut = rootAB.model.getMqttRoot(); + ModelItemAndTwoTopics modelAB = createAB(); + MqttRoot sut = modelAB.model.getRoot().getMqttRoot(); // MqttRoot mqttRoot = new MqttRoot(); // mqttRoot.setHostByName("localhost"); // MQTTSender sender = new MQTTSenderImpl().setHost(mqttRoot.getHost()); @@ -76,11 +76,11 @@ public class MqttTests { public void itemUpdateSend1() throws Exception { String expectedTopic = outgoingPrefix + "/" + firstPart + "/" + secondPart; - RootItemAndTwoTopics rootAB = createAB(); - assertSenderConnected(rootAB.model); + ModelItemAndTwoTopics modelAB = createAB(); + assertSenderConnected(modelAB); - NumberItem sut = rootAB.item; - sut.setTopic(rootAB.secondTopic); + NumberItem sut = modelAB.item; + sut.setTopic(modelAB.secondTopic); createMqttReceiver(expectedTopic); @@ -102,20 +102,20 @@ public class MqttTests { String expectedTopic1 = outgoingPrefix + "/" + firstPart + "/" + secondPart; String expectedTopic2 = outgoingPrefix + "/" + alternativeFirstPart + "/" + secondPart; - RootItemAndTwoTopics rootAB = createAB(); - assertSenderConnected(rootAB.model); + ModelItemAndTwoTopics modelAB = createAB(); + assertSenderConnected(modelAB); - NumberItem item1 = rootAB.item; - item1.setTopic(rootAB.secondTopic); + NumberItem item1 = modelAB.item; + item1.setTopic(modelAB.secondTopic); MqttTopic alternative = new MqttTopic(); alternative.setPart(alternativeFirstPart); MqttTopic alternativeB = new MqttTopic(); alternativeB.setPart(secondPart); alternative.addSubTopic(alternativeB); - rootAB.model.getMqttRoot().addTopic(alternative); + modelAB.model.getRoot().getMqttRoot().addTopic(alternative); - NumberItem item2 = TestUtils.addItemTo(rootAB.model, 0); + NumberItem item2 = TestUtils.addItemTo(modelAB.model, 0); item2.setTopic(alternativeB); createMqttReceiver(expectedTopic1, expectedTopic2); @@ -141,16 +141,17 @@ public class MqttTests { Assert.assertThat(messages, hasItem(Double.toString(thirdState))); } - private void assertSenderConnected(Root model) { + private void assertSenderConnected(ModelItemAndTwoTopics modelAB) { + MqttRoot mqttRoot = modelAB.model.getRoot().getMqttRoot(); mqttBroker.waitingFor(Wait.forHealthcheck()); - if (!model.getMqttRoot().getMqttSender().isConnected()) { + if (!mqttRoot.getMqttSender().isConnected()) { try { Thread.sleep(1000); } catch (InterruptedException e) { logger.catching(e); } } - Assert.assertTrue("Broker is not connected", model.getMqttRoot().getMqttSender().isConnected()); + Assert.assertTrue("Broker is not connected", mqttRoot.getMqttSender().isConnected()); } private void createMqttReceiver(String... expectedTopics) throws IOException { @@ -171,9 +172,9 @@ public class MqttTests { receiver.waitUntilReady(2, TimeUnit.SECONDS); } - private RootItemAndTwoTopics createAB() { + private ModelItemAndTwoTopics createAB() { TestUtils.ModelAndItem mai = TestUtils.createModelAndItem(0); - Root model = mai.model; + OpenHAB2Model model = mai.model; MqttRoot mqttRoot = new MqttRoot(); mqttRoot.setIncomingPrefix("inc"); mqttRoot.setOutgoingPrefix(outgoingPrefix); @@ -192,17 +193,17 @@ public class MqttTests { a.addSubTopic(ab); mqttRoot.addTopic(a); mqttRoot.ensureCorrectPrefixes(); - model.setMqttRoot(mqttRoot); - return RootItemAndTwoTopics.of(model, mai.item, a, ab); + model.getRoot().setMqttRoot(mqttRoot); + return ModelItemAndTwoTopics.of(model, mai.item, a, ab); } - static class RootItemAndTwoTopics { - Root model; + static class ModelItemAndTwoTopics { + OpenHAB2Model model; NumberItem item; MqttTopic firstTopic; MqttTopic secondTopic; - static RootItemAndTwoTopics of(Root model, NumberItem item, MqttTopic firstTopic, MqttTopic secondTopic) { - RootItemAndTwoTopics result = new RootItemAndTwoTopics(); + static ModelItemAndTwoTopics of(OpenHAB2Model model, NumberItem item, MqttTopic firstTopic, MqttTopic secondTopic) { + ModelItemAndTwoTopics result = new ModelItemAndTwoTopics(); result.model = model; result.item = item; result.firstTopic = firstTopic; diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java index 5d658500..0eb593fd 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/NeuralNetworkTest.java @@ -24,7 +24,7 @@ public class NeuralNetworkTest { */ NeuralNetworkRoot neuralNetworkRoot = NeuralNetworkRoot.createEmpty(); - mai.model.getMachineLearningRoot().setPreferenceLearning(neuralNetworkRoot); + mai.model.getRoot().getMachineLearningRoot().setPreferenceLearning(neuralNetworkRoot); InputNeuron inputNeuron = new InputNeuron(); inputNeuron.setItem(mai.item); HiddenNeuron hiddenNeuron = new HiddenNeuron(); diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/OpenHabImporterTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/OpenHabImporterTest.java index 37766dac..8c109638 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/OpenHabImporterTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/OpenHabImporterTest.java @@ -1,5 +1,6 @@ package de.tudresden.inf.st.eraser; +import de.tudresden.inf.st.eraser.jastadd.model.OpenHAB2Model; import de.tudresden.inf.st.eraser.jastadd.model.Root; import de.tudresden.inf.st.eraser.jastadd_test.core.*; import de.tudresden.inf.st.eraser.openhab2.OpenHab2Importer; @@ -70,7 +71,7 @@ public class OpenHabImporterTest { // call the modified importer, with the static host name, and an arbitrary chosen port // port will not be used during the test - Root model = importer.importFrom(HOST, 80); + OpenHAB2Model model = importer.importFrom(HOST, 80); if (model == null) { if (expected == Result.PARSE_FAILED) return; @@ -88,7 +89,7 @@ public class OpenHabImporterTest { } } - printAndCompare(config, model); + printAndCompare(config, model.getRoot()); } } diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ParserTests.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ParserTests.java index 02a6d30a..02f2da81 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ParserTests.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ParserTests.java @@ -20,8 +20,8 @@ public class ParserTests { public void testCreateMqttTopicSimple() { ModelAndItem mai = TestUtils.createModelAndItem(1); - Root model = mai.model; - model.setMqttRoot(new MqttRoot()); + Root root = mai.model.getRoot(); + root.setMqttRoot(new MqttRoot()); NumberItem item = mai.item; Assert.assertNull(item.getTopic()); @@ -29,11 +29,11 @@ public class ParserTests { String[] parts = { "one", "two", "three" }; String topicName = String.join("/", parts); - ParserUtils.createMqttTopic(item, topicName, model); + ParserUtils.createMqttTopic(item, topicName, root); Assert.assertNotNull(item.getTopic()); - MqttRoot mqttRoot = model.getMqttRoot(); + MqttRoot mqttRoot = root.getMqttRoot(); Assert.assertEquals("There must be only one topic", 1, mqttRoot.getNumTopic()); Assert.assertEquals("First part is wrong", parts[0], mqttRoot.getTopic(0).getPart()); @@ -56,10 +56,10 @@ public class ParserTests { public void testCreateMqttTopicTwoInterleavedTopics() { ModelAndItem mai = TestUtils.createModelAndItem(1); - Root model = mai.model; - model.setMqttRoot(new MqttRoot()); + Root root = mai.model.getRoot(); + root.setMqttRoot(new MqttRoot()); NumberItem item1 = mai.item; - NumberItem item2 = TestUtils.addItemTo(model, 3); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 3); Assert.assertNull(item1.getTopic()); Assert.assertNull(item2.getTopic()); @@ -69,13 +69,13 @@ public class ParserTests { String topicName1 = String.join("/", parts); String topicName2 = String.join("/", parts[0], otherPart2, parts[2]); - ParserUtils.createMqttTopic(item1, topicName1, model); - ParserUtils.createMqttTopic(item2, topicName2, model); + ParserUtils.createMqttTopic(item1, topicName1, root); + ParserUtils.createMqttTopic(item2, topicName2, root); Assert.assertNotNull(item1.getTopic()); Assert.assertNotNull(item2.getTopic()); - MqttRoot mqttRoot = model.getMqttRoot(); + MqttRoot mqttRoot = root.getMqttRoot(); Assert.assertEquals("There must be only one topic", 1, mqttRoot.getNumTopic()); Assert.assertEquals("First part is wrong", parts[0], mqttRoot.getTopic(0).getPart()); diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/RulesTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/RulesTest.java index 1ec9aaef..2c318278 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/RulesTest.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/RulesTest.java @@ -50,13 +50,13 @@ public class RulesTest { @Test public void testUnconditionalLambdaAction() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; Rule rule = new Rule(); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Counter not initialized correctly"), 0, counter.get(item)); @@ -74,11 +74,11 @@ public class RulesTest { @Test public void testIdempotentActivation() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(4); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; Rule rule = new Rule(); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); rule.activateFor(item); @@ -94,18 +94,18 @@ public class RulesTest { @Test public void testTwoRulesForOneItem() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(4); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; Counters counter1 = new Counters(); Rule ruleA = new Rule(); ruleA.addAction(new LambdaAction(counter1)); - model.addRule(ruleA); + root.addRule(ruleA); Rule ruleB = new Rule(); Counters counter2 = new Counters(); ruleB.addAction(new LambdaAction(counter2)); - model.addRule(ruleB); + root.addRule(ruleB); ruleA.activateFor(item); ruleB.activateFor(item); @@ -129,14 +129,14 @@ public class RulesTest { @Test public void testOneRuleForTwoItems() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(4); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item1 = modelAndItem.item; - NumberItem item2 = TestUtils.addItemTo(model, 4, useUpdatingItem); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); Rule rule = new Rule(); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item1); rule.activateFor(item2); @@ -188,13 +188,13 @@ public class RulesTest { @Test public void testRemoveActivation() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(4); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; Rule rule = new Rule(); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); @@ -212,7 +212,7 @@ public class RulesTest { @Test public void testNumberConditions() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(2); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; Rule rule = new Rule(); @@ -222,7 +222,7 @@ public class RulesTest { rule.addCondition(new ItemStateCheckCondition(check2)); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Counter not initialized correctly"), 0, counter.get(item)); @@ -246,7 +246,7 @@ public class RulesTest { @Test public void testTwoActions() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(2); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; Rule rule = new Rule(); @@ -254,7 +254,7 @@ public class RulesTest { rule.addAction(new LambdaAction(counter1)); Counters counter2 = new Counters(); rule.addAction(new LambdaAction(counter2)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("First counter not initialized correctly"), 0, counter1.get(item)); @@ -272,9 +272,9 @@ public class RulesTest { @Test public void testChainedRules() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(2); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - NumberItem item2 = TestUtils.addItemTo(model, 4, useUpdatingItem); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); Rule ruleA = new Rule(); Counters counter1 = new Counters(); @@ -286,8 +286,8 @@ public class RulesTest { ruleA.addAction(new TriggerRuleAction(ruleB)); - model.addRule(ruleA); - model.addRule(ruleB); + root.addRule(ruleA); + root.addRule(ruleB); ruleA.activateFor(item); ruleB.activateFor(item2); @@ -315,15 +315,15 @@ public class RulesTest { @Test public void testSetStateFromConstantStringAction() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - NumberItem item2 = TestUtils.addItemTo(model, 4, useUpdatingItem); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); Rule rule = new Rule(); rule.addAction(new SetStateFromConstantStringAction(item2, "5")); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Affected item not initialized correctly"), @@ -347,15 +347,15 @@ public class RulesTest { public void testSetStateFromLambdaAction() { ValuedStateProvider provider = new ValuedStateProvider(); TestUtils.ModelAndItem modelAndItem = createModelAndItem(0); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - NumberItem item2 = TestUtils.addItemTo(model, 3, useUpdatingItem); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 3, useUpdatingItem); Rule rule = new Rule(); rule.addAction(new SetStateFromLambdaAction(item2, provider)); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Affected item not initialized correctly"), @@ -389,15 +389,15 @@ public class RulesTest { @Test public void testSetStateFromTriggeringItemAction() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - StringItem item2 = addStringItem(model, "0"); + StringItem item2 = addStringItem(root.getOpenHAB2Model(), "0"); Rule rule = new Rule(); Counters counter = new Counters(); rule.addAction(new SetStateFromTriggeringItemAction(item2)); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Counter not initialized correctly"), 0, counter.get(item)); @@ -419,10 +419,10 @@ public class RulesTest { @Test public void testSetStateFromItemsAction() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - NumberItem item2 = TestUtils.addItemTo(model, 4, useUpdatingItem); - StringItem affectedItem = addStringItem(model, "1"); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); + StringItem affectedItem = addStringItem(root.getOpenHAB2Model(), "1"); Rule rule = new Rule(); SetStateFromItemsAction action = new SetStateFromItemsAction(items -> @@ -435,7 +435,7 @@ public class RulesTest { rule.addAction(action); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Counter not initialized correctly"), 0, counter.get(item)); @@ -467,7 +467,7 @@ public class RulesTest { "12", affectedItem.getState()); // add new item to sum - NumberItem item3 = TestUtils.addItemTo(model, -4, useUpdatingItem); + NumberItem item3 = TestUtils.addItemTo(root.getOpenHAB2Model(), -4, useUpdatingItem); action.addSourceItem(item3); // still 7 + 5 = 12, as rule should not trigger @@ -486,15 +486,15 @@ public class RulesTest { @Test public void testAddDoubleToStateAction() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - NumberItem affectedItem = TestUtils.addItemTo(model, 4, useUpdatingItem); + NumberItem affectedItem = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); Rule rule = new Rule(); rule.addAction(new AddDoubleToStateAction(affectedItem, 2)); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Counter not initialized correctly"), 0, counter.get(item)); @@ -523,15 +523,15 @@ public class RulesTest { @Test public void testMultiplyDoubleToStateAction() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item = modelAndItem.item; - NumberItem affectedItem = TestUtils.addItemTo(model, 4, useUpdatingItem); + NumberItem affectedItem = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); Rule rule = new Rule(); rule.addAction(new MultiplyDoubleToStateAction(affectedItem, 2)); Counters counter = new Counters(); rule.addAction(new LambdaAction(counter)); - model.addRule(rule); + root.addRule(rule); rule.activateFor(item); Assert.assertEquals(m("Counter not initialized correctly"), 0, counter.get(item)); @@ -560,10 +560,10 @@ public class RulesTest { @Test public void testChainAddMultiplyActions() { TestUtils.ModelAndItem modelAndItem = createModelAndItem(3); - Root model = modelAndItem.model; + Root root = modelAndItem.model.getRoot(); NumberItem item1 = modelAndItem.item; - NumberItem item2 = TestUtils.addItemTo(model, 4, useUpdatingItem); - NumberItem affectedItem = TestUtils.addItemTo(model, 5, useUpdatingItem); + NumberItem item2 = TestUtils.addItemTo(root.getOpenHAB2Model(), 4, useUpdatingItem); + NumberItem affectedItem = TestUtils.addItemTo(root.getOpenHAB2Model(), 5, useUpdatingItem); Rule ruleA = new Rule(); ruleA.addAction(new AddDoubleToStateAction(affectedItem, 2)); @@ -577,8 +577,8 @@ public class RulesTest { ruleA.addAction(new TriggerRuleAction(ruleB)); - model.addRule(ruleA); - model.addRule(ruleB); + root.addRule(ruleA); + root.addRule(ruleB); ruleA.activateFor(item1); ruleB.activateFor(item2); @@ -653,7 +653,7 @@ public class RulesTest { return message + " (Using " + name + ")"; } - private StringItem addStringItem(Root model, String initialValue) { + private StringItem addStringItem(OpenHAB2Model model, String initialValue) { StringItem item = new StringItem(); Group group = TestUtils.getDefaultGroup(model); item.setID("item" + group.getNumItem()); diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/jastadd_test/core/TestRunner.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/jastadd_test/core/TestRunner.java index 984fb21d..6978df5c 100644 --- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/jastadd_test/core/TestRunner.java +++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/jastadd_test/core/TestRunner.java @@ -30,6 +30,7 @@ package de.tudresden.inf.st.eraser.jastadd_test.core; import beaver.Parser; +import de.tudresden.inf.st.eraser.jastadd.model.OpenHAB2Model; import de.tudresden.inf.st.eraser.jastadd.model.Root; import de.tudresden.inf.st.eraser.util.ParserUtils; @@ -67,9 +68,9 @@ public class TestRunner { Result expected = config.expected; // Parse input model - Root model; + Root root; try { - model = parseModel(config); + root = parseModel(config); } catch (Parser.Exception e) { if (expected == Result.PARSE_FAILED) return; // otherwise rethrow error @@ -80,7 +81,7 @@ public class TestRunner { fail("Parsing the model should have failed, but was successful!"); } - if (model == null) { + if (root == null) { fail("Parsing the model should have passed, but model was null!"); } @@ -91,15 +92,15 @@ public class TestRunner { return; } - printAndCompare(config, model); + printAndCompare(config, root); } - protected static void printAndCompare(TestConfiguration config, Root model) { + protected static void printAndCompare(TestConfiguration config, Root root) { Result expected = config.expected; // Print model. String output; try { - output = printModel(model, config); + output = printModel(root, config); } catch (Exception e) { if (expected == Result.PRINT_FAILED) return; // otherwise rethrow error @@ -149,8 +150,8 @@ public class TestRunner { return new File(testDir, "jastadd.err.expected"); } - private static String printModel(Root model, TestConfiguration config) { - return model.prettyPrint(); + private static String printModel(Root root, TestConfiguration config) { + return root.prettyPrint(); } /** diff --git a/eraser-base/src/test/resources/openhabtest/oh1/output.eraser b/eraser-base/src/test/resources/openhabtest/oh1/output.eraser index c4228400..1844189c 100644 --- a/eraser-base/src/test/resources/openhabtest/oh1/output.eraser +++ b/eraser-base/src/test/resources/openhabtest/oh1/output.eraser @@ -18,5 +18,3 @@ Color Item: id="wohnzimmer_item" label="Wohnzimmer" state="0,0,0" category="Ligh Color Item: id="iris1_item" label="Iris 1" state="226,100,98" category="Lighting" ; Group: id="all_dimmable_lamps" label="All dimmable lamps" items=["Go1_item"] aggregation="AVG" ; Group: id="Unknown" items=["Rule_Switch", "Color_Manual_Slider", "watch_acceleration_x", "watch_acceleration_y", "watch_acceleration_z", "watch_rotation_x", "watch_rotation_y", "watch_rotation_z", "phone_rotation_x", "phone_rotation_y", "phone_rotation_z", "samsung_brightness", "skywriter_flick_item", "polar_brightness", "moto_360_brightness", "wohnzimmer_item", "iris1_item"] ; -Mqtt: host="localhost" ; -Influx: host="localhost" ; diff --git a/eraser-base/src/test/resources/openhabtest/oh2/output.eraser b/eraser-base/src/test/resources/openhabtest/oh2/output.eraser index 45f5a639..e6354c12 100644 --- a/eraser-base/src/test/resources/openhabtest/oh2/output.eraser +++ b/eraser-base/src/test/resources/openhabtest/oh2/output.eraser @@ -85,5 +85,3 @@ Channel: id="openlicht:samsung-s6:2ca84896:rotation-x" type="openlicht:rotation- Channel: id="openlicht:samsung-s6:2ca84896:rotation-y" type="openlicht:rotation-type" links=["phone_rotation_y"] ; Channel: id="openlicht:samsung-s6:2ca84896:rotation-z" type="openlicht:rotation-type" links=["phone_rotation_z"] ; Channel: id="openlicht:skywriter-hat:e937d4f3:flick" type="openlicht:flick-type" links=["skywriter_flick_item"] ; -Mqtt: host="localhost" ; -Influx: host="localhost" ; -- GitLab