Skip to content

Commit

Permalink
Merge branch 'greenhouse-core' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Tale152 committed May 13, 2022
2 parents 8536cd6 + a83dd21 commit e85f3f8
Show file tree
Hide file tree
Showing 15 changed files with 444 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import city.sane.wot.thing.ConsumedThing;
import utility.ThingDescriptorUtility;
import utility.component.Component;
import utility.component.ComponentUtility;
import utility.sample.Sample;
import utility.setting.RangeSetting;

Expand Down Expand Up @@ -95,7 +96,7 @@ void actuate(final Sample outOfRangeSample, final RangeSetting setting) {
* @param turnOffAction the action that needs to be turned off.
*/
private void switchActuatorAction(final String category, final String turnOnAction, final String turnOffAction) {
List<Component> components = ThingDescriptorUtility.getActuatorsByCategory(this.components, category);
List<Component> components = ComponentUtility.getActuatorsByCategory(this.components, category);
for (Component component : components) {
//search for the specific action in the td list for a specific edge
Optional<ConsumedThing> td = ThingDescriptorUtility.getThingDescriptor(this.thingDescriptors, component.getEdgeIp());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import city.sane.wot.thing.ConsumedThing;
import utility.ThingDescriptorUtility;
import utility.component.Component;
import utility.component.ComponentUtility;
import utility.setting.HourSetting;
import utility.setting.Settings;

Expand Down Expand Up @@ -73,7 +74,7 @@ void checkSettings(final String category) {
if (!this.components.isEmpty() && this.settings.isPresent()
&& this.settings.get().getSetting(category).isPresent()) {
HourSetting setting = (HourSetting) this.settings.get().getSetting(category).get();
List<Component> actuators = ThingDescriptorUtility.getActuatorsByCategory(this.components, category);
List<Component> actuators = ComponentUtility.getActuatorsByCategory(this.components, category);
checkTime(setting, actuators);
}
}
Expand Down Expand Up @@ -116,4 +117,5 @@ private void performActuatorAction(final List<Component> actuators, final String
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
*/
public class DiscoverComponentsArtifact extends Artifact {

private final static long TICK_TIME = 100;

private OkHttpClient client;
private List<Component> components;
private List<ConsumedThing> thingDescriptors;
Expand Down Expand Up @@ -67,21 +69,30 @@ private void configWot() {
*/
@OPERATION
void discoverComponents() {
// initialization due to avoid to try to communicate with disconnected components
//initialization due to avoid to try to communicate with disconnected components
this.components = new ArrayList<>();
this.thingDescriptors = new ArrayList<>();
// create cycle for broadcast requests!
// for test purposes
/*
* for (int i = 1; i >= 255; i++){
* System.out.println("http://192.168.189." + i);
* }
*/
getThingDescriptor("http://192.168.246.1"); // this is in the cicle

// at the end of the cicle, update components and thing descriptors
defineObsProperty("components", this.components);
defineObsProperty("thingDescriptors", this.thingDescriptors);
//calling asynchronous operation
execInternalOp("broadcastRequest");
}

/**
* This internal operation is used to run an asynchronous operation,
* which it is usually for a long term operation.
* This internal operation is used to cicle on all the ip adresses
* in order to find all the edges connected to the greenhouse, and
* it requires some time.
*
* Even though it runs asynchronously, it is necessary to call
* await time, which stops the executing operation and makes
* it possible to commit the observable states.
*/
@INTERNAL_OPERATION
void broadcastRequest() {
for (int i = 1; i <= 255; i++) {
getThingDescriptor("http://192.168.246." + i);
await_time(TICK_TIME);
}
}

/**
Expand All @@ -94,11 +105,15 @@ private void getThingDescriptor(final String url) {
Request request = new Request.Builder().url(url).build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println("Successful edge response at url " + url);
JsonObject thingDescriptor = JsonParser.parseString(response.body().string()).getAsJsonObject();
updateComponents(thingDescriptor); // if found, update components
updateComponents(thingDescriptor); //if found, update components
//update components and thing descriptors
defineObsProperty("components", this.components);
defineObsProperty("thingDescriptors", this.thingDescriptors);
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("Impossible to contact edge at url " + url);
}
}

Expand Down
94 changes: 41 additions & 53 deletions greenhouse_core/src/env/sampling/SamplingCoordinatorArtifact.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import cartago.*;
import utility.component.Component;
import utility.component.ComponentUtility;
import utility.sample.Sample;
import utility.sample.SamplesUtility;
import utility.setting.RangeSetting;
import utility.setting.Setting;
import utility.setting.Settings;

/**
Expand Down Expand Up @@ -60,7 +59,7 @@ void setupComponents(final List<Component> components) {
* the settings only if they exist.
*/
@OPERATION
void setupSettings( final Optional<Settings> settings) {
void setupSettings(final Optional<Settings> settings) {
this.settings = settings;
}

Expand All @@ -76,7 +75,7 @@ void setupSettings( final Optional<Settings> settings) {
*/
@OPERATION
void sampleOperation(final String category) {
List<Component> filteredComponents = getComponentsByCategory(category);
List<Component> filteredComponents = ComponentUtility.getComponentsByCategory(this.components, category);
if (!filteredComponents.isEmpty()) {
defineObsProperty("sampling", filteredComponents);
}
Expand All @@ -93,104 +92,93 @@ void sampleOperation(final String category) {
@OPERATION
void updateOperation(final List<Sample> currentSamples) {
if (!currentSamples.isEmpty()) {
Sample avarageSample = SamplesUtility.getAvarageOfSamples(currentSamples);
String category = avarageSample.getCategory();
Sample averageSample = SamplesUtility.getAverageOfSamples(currentSamples);
String category = averageSample.getCategory();
Optional<Sample> lastSample = SamplesUtility.getSampleByCategory(lastSamples, category);
System.out.println("Avarage current Sample: " + avarageSample + "\nLast avarage sample: " + lastSample);
System.out.println("Average current Sample: " + averageSample + "\nLast average sample: " + lastSample);

uploadToPersistence(avarageSample, lastSample);
startActuator(avarageSample, category);
uploadToPersistence(averageSample, lastSample);
startActuator(averageSample, category);

this.lastSamples.add(avarageSample);
this.lastSamples.add(averageSample);
}
}

/**
* Utility method used to check the avarage of the current samples and the last
* Utility method used to check the average of the current samples and the last
* sample retrieved. If their difference is bigger that the specified DELTA,
* then the new avarage sample is going to be uploaded in the persistence
* then the new average sample is going to be uploaded in the persistence
* service.
*
* @param avarageSample the avarage of the current samples retrieved.
* @param averageSample the average of the current samples retrieved.
* @param lastSample the last sample saved.
*/
private void uploadToPersistence(final Sample avarageSample, final Optional<Sample> lastSample){
private void uploadToPersistence(final Sample averageSample, final Optional<Sample> lastSample) {
if (lastSample.isPresent()) {
if (isSampleDifferenceBiggerThanDelta(avarageSample, lastSample)){
defineObsProperty("uploadPersistence", avarageSample);
if (isSampleDifferenceBiggerThanDelta(averageSample, lastSample)) {
defineObsProperty("uploadPersistence", averageSample);
lastSamples.remove(lastSample.get());
}

}
}
}

/**
* Utility method used to check if the difference of the current avarage sample
* Utility method used to check if the difference of the current average sample
* and the last sample is bigger than the DELTA.
*
* @param avarageSample the avarage of the current samples retrieved.
* @param averageSample the average of the current samples retrieved.
* @param lastSample the last sample saved.
* @return true if the difference of the samples is bigger thant the DELTA, false otherwise.
*/
private boolean isSampleDifferenceBiggerThanDelta(final Sample avarageSample, final Optional<Sample> lastSample){
return Math.abs(avarageSample.getValue() - lastSample.get().getValue()) > DELTA;
private boolean isSampleDifferenceBiggerThanDelta(final Sample averageSample, final Optional<Sample> lastSample) {
return Math.abs(averageSample.getValue() - lastSample.get().getValue()) > DELTA;
}

/**
* Utility method used to check the settings to verify if it occurred an
* out of range sample and that it is necessary to perform an action
* from an actuator.
*
* @param avarageSample the avarage of the current samples retrieved.
* @param category the category of the current avarage sample.
* @param averageSample the average of the current samples retrieved.
* @param category the category of the current average sample.
*/
private void startActuator(final Sample avarageSample, final String category){
private void startActuator(final Sample averageSample, final String category) {
if (this.settings.isPresent()) {
// handle only range settings
if (getSettingByCategory(category).isPresent()
&& getSettingByCategory(category).get() instanceof RangeSetting) {
RangeSetting rangeSetting = (RangeSetting) getSettingByCategory(category).get();
if (isSampleOutOfRange(avarageSample, rangeSetting)) {
if (isRangeSettingPresent(category)) {
RangeSetting rangeSetting = (RangeSetting) this.settings.get().getSetting(category).get();
if (isSampleOutOfRange(averageSample, rangeSetting)) {
System.out.println("Create out of range behavior");
defineObsProperty("actuate", category, avarageSample, rangeSetting);
defineObsProperty("actuate", category, averageSample, rangeSetting);
}
}
}
}

/**
* Utility method used check if the current avarage sample is out of the minimum and
* Utility method used check if the current average sample is out of the minimum and
* maximum define by the [[utility.setting.RangeSetting]] of its category.
*
* @param avarageSample the avaragae of the current samples retrieved.
* @param averageSample the average of the current samples retrieved.
* @param rangeSetting the range setting that define the minimum and the maximum
* value of the sample of a specific category.
* @return true if the value of the avarage sample is out of range, false otherwise.
*/
private boolean isSampleOutOfRange(final Sample avarageSample, final RangeSetting rangeSetting){
return avarageSample.getValue() < rangeSetting.getMin() || avarageSample.getValue() > rangeSetting.getMax();
}

/**
* Utility method used to retrieve from a list of components only the components of a specific
* category.
*
* @param category the cateogry of the components that are wanted to be retrieved.
* @return the list of components that have a specific category.
* @return true if the value of the average sample is out of range, false otherwise.
*/
private List<Component> getComponentsByCategory(final String category) {
return this.components.stream().filter(c -> c.getCategory().equals(category)).filter(c -> !c.getProperties().isEmpty()).collect(Collectors.toList());
private boolean isSampleOutOfRange(final Sample averageSample, final RangeSetting rangeSetting) {
return averageSample.getValue() < rangeSetting.getMin() || averageSample.getValue() > rangeSetting.getMax();
}

/**
* Utility method used to retrieve a setting with a specific category
* from an optional list of settings.
* Utility method used to verify if it exists a RangeSetting
* in the current settings list of the specified category.
*
* @param category the category of the settings wanted.
* @return an optional which contains the setting of that category if found.
* @param category the category of the RangeSetting searched.
* @return true if a RangeSetting of the category specified exists,
* false otherwise.
*/
private Optional<Setting> getSettingByCategory(final String category) {
return this.settings.get().getSetting(category);
private boolean isRangeSettingPresent(final String category) {
Settings currentSettings = this.settings.get();
return (currentSettings.getSetting(category).isPresent()
&& currentSettings.getSetting(category).get() instanceof RangeSetting);
}

}
20 changes: 20 additions & 0 deletions greenhouse_core/src/env/utility/Pair.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
package utility;

/**
* Pair is an generic utility class used to contain in
* a single object two values logically connected in some way.
*/
public class Pair<X,Y> {

private final X x;
private final Y y;

/**
* Constructor of Pair.
*
* @param x the first generic value of the Pair.
* @param y the second generic value of the Pair.
*/
public Pair(final X x, final Y y) {
this.x = x;
this.y = y;
}

/**
* A Pair has a generic first element.
*
* @return the first generic value of the Pair.
*/
public X getX() {
return x;
}

/**
* A Pair has a generic second element.
*
* @return the second generic value of the Pair.
*/
public Y getY() {
return y;
}
Expand Down
32 changes: 25 additions & 7 deletions greenhouse_core/src/env/utility/ThingDescriptorUtility.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,36 @@

import city.sane.wot.thing.ConsumedThing;

import utility.component.Component;

/**
* ThingDescriptorUtility is an utility class used to provide
* methods in order to handle easily the thing descriptor.
*/
public class ThingDescriptorUtility {

public static List<Component> getActuatorsByCategory(final List<Component> components, final String category) {
return components.stream().filter(c -> c.getCategory().equals(category))
.filter(c -> !c.getActions().isEmpty()).collect(Collectors.toList());
}

/**
* Utility method used to find in a list of thing descriptors a specific
* thing descriptor by its identifier.
*
* @param thingDescriptors the list of thing descriptors.
* @param id the id of the thing descriptor wanted.
* @return an optional of the thing descriptor with the specified id if found,
* and optional of empty otherwise.
*/
public static Optional<ConsumedThing> getThingDescriptor(final List<ConsumedThing> thingDescriptors, final String id) {
return thingDescriptors.stream().filter(t -> t.getId().equals(id)).findFirst();
}

/**
* Utility method used to get a list of actions and/or properties names from
* the thing descriptor of a specific component, of a specific category.
*
* @param td the thing descriptor that contains the actions or the properties.
* @param category the category of the action or properties wanted.
* @param componentId the id of the component of which the names of properties or
* actions are wanted.
* @return a list of names of the action or the properties of a specific component, based
* on its category.
*/
public static List<String> getNamesByCategory(final JsonObject td, final String category, final String componentId) {
List<String> names = new ArrayList<>();
Set<Map.Entry<String, JsonElement>> entries = td.entrySet();
Expand All @@ -36,4 +53,5 @@ public static List<String> getNamesByCategory(final JsonObject td, final String
}
return names.stream().filter(n -> n.substring(n.lastIndexOf("-") + 1).equals(componentId)).collect(Collectors.toList());
}

}
Loading

0 comments on commit e85f3f8

Please sign in to comment.