Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Averager plugin: possibility to enable/disable by property and events #294

Merged
merged 2 commits into from
Apr 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@

import java.util.LinkedList;

import eu.asterics.mw.model.runtime.*;
import org.apache.commons.math3.stat.StatUtils;

import eu.asterics.mw.data.ConversionUtils;
import eu.asterics.mw.model.runtime.AbstractRuntimeComponentInstance;
import eu.asterics.mw.model.runtime.IRuntimeInputPort;
import eu.asterics.mw.model.runtime.IRuntimeOutputPort;
import eu.asterics.mw.model.runtime.impl.DefaultRuntimeInputPort;
import eu.asterics.mw.model.runtime.impl.DefaultRuntimeOutputPort;

Expand All @@ -57,13 +55,15 @@ public class AveragerInstance extends AbstractRuntimeComponentInstance {
private IRuntimeOutputPort opOutput = new OutputPort1();

private int propBufferSize = DEFAULT_BUFFER_SIZE;
private boolean propEnabled = true;
private int propMode = 0;
private int propAutoReenableTime = 0;

private final LinkedList<Double> buffer = new LinkedList<Double>();
private long lastUpdate = 0;
private double accu = 0;

private double sum = 0;
private long disableTime = 0;

/**
* The class constructor.
Expand Down Expand Up @@ -104,6 +104,37 @@ public IRuntimeOutputPort getOutputPort(String portID) {
}
}

/**
* returns an Event Listener Port.
*
* @param eventPortID
* the name of the port
* @return the EventListener port or null if not found
*/
public IRuntimeEventListenerPort getEventListenerPort(String eventPortID) {
if ("enablePlugin".equalsIgnoreCase(eventPortID)) {
return elpEnablePlugin;
}
if ("disablePlugin".equalsIgnoreCase(eventPortID)) {
return elpDisablePlugin;
}

return null;
}

private final IRuntimeEventListenerPort elpEnablePlugin = new IRuntimeEventListenerPort() {
public void receiveEvent(final String data) {
propEnabled = true;
}
};

private final IRuntimeEventListenerPort elpDisablePlugin = new IRuntimeEventListenerPort() {
public void receiveEvent(final String data) {
propEnabled = false;
disableTime = System.currentTimeMillis();
}
};

/**
* returns the value of the given property.
*
Expand All @@ -113,10 +144,14 @@ public IRuntimeOutputPort getOutputPort(String portID) {
*/
@Override
public Object getRuntimePropertyValue(String propertyName) {
if ("bufferSize".equalsIgnoreCase(propertyName)) {
if ("enabled".equalsIgnoreCase(propertyName)) {
return propEnabled;
} else if ("bufferSize".equalsIgnoreCase(propertyName)) {
return propBufferSize;
} else if ("mode".equalsIgnoreCase(propertyName)) {
return propMode;
} else if ("autoReenableTime".equalsIgnoreCase(propertyName)) {
return propAutoReenableTime;
} else {
return null;
}
Expand All @@ -132,7 +167,11 @@ public Object getRuntimePropertyValue(String propertyName) {
*/
@Override
public synchronized Object setRuntimePropertyValue(String propertyName, Object newValue) {
if ("bufferSize".equalsIgnoreCase(propertyName)) {
if ("enabled".equalsIgnoreCase(propertyName)) {
final Object oldValue = propEnabled;
propEnabled = Boolean.parseBoolean((String) newValue);
return oldValue;
} else if ("bufferSize".equalsIgnoreCase(propertyName)) {
final Object oldValue = propBufferSize;

if (newValue != null) {
Expand Down Expand Up @@ -165,6 +204,10 @@ public synchronized Object setRuntimePropertyValue(String propertyName, Object n
}
}
return oldValue;
} else if ("autoReenableTime".equalsIgnoreCase(propertyName)) {
final Object oldValue = propAutoReenableTime;
propAutoReenableTime = Integer.parseInt(newValue.toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if newValue==null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the property is defined as integer in the bundle descriptor, shouldn't any generic logic ensure that it is actually an integer value when arriving at this point? Otherwise, whats the point of declaring datatypes in the bundleDescriptor?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, although, semantically, "no value" (null) is not the same as 0 or could be interpreted differently. So maybe that's why you can't handle it generically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so I should catch a NumberFormatException there? I've seen plenty plugins, where no FormatExceptions are caught at property parsing. I think any FormatExceptions in this method should be caught by default in a base plugin class, so that the creator of a plugin does not have to care about them, if he doesn't want any specific error handling.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, you are right, the generic code in the DeploymentManager should do a check, if the value is conforming to the datatype specified in the bundle descriptor. If not log exceptions and proceed with datatype-specific default values.

These are the datatypes which could be easiliy checked:
https://github.com/asterics/AsTeRICS/blob/56f59f844f2a1c038ff4807ee208127d2033298b/ARE/middleware/src/main/java/eu/asterics/mw/model/DataType.java

Let's merge this PR and see if there is enough time for a generic solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opened corresponding issue #312

return oldValue;
} else {
return null;
}
Expand All @@ -177,6 +220,12 @@ public synchronized Object setRuntimePropertyValue(String propertyName, Object n
* samples are summed but not divided
*/
private synchronized void process(final double in) {
if (!propEnabled && buffer.size() == propBufferSize) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need the check ... && buffer.size() == propBufferSize

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the idea was somehow to wait until the buffer is full, but it does not make much sense as it is now. I'll remove it.

if (System.currentTimeMillis() - disableTime < propAutoReenableTime || propAutoReenableTime == 0) {
return;
}
propEnabled = true;
}
if (propMode == MODE_AVERAGE) {
buffer.addFirst(in);
sum += in;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,19 @@
<dataType>double</dataType>
</outputPort>
</ports>
<properties>
<events>
<eventListenerPort id="enablePlugin">
<description>enables the functionality of this plugin</description>
</eventListenerPort>
<eventListenerPort id="disablePlugin">
<description>disables the functionality of this plugin</description>
</eventListenerPort>
</events>
<properties>
<property name="enabled"
type="boolean"
value="true"
description="if true, the plugin is enabled, if false the plugin does nothing"/>
<property name="bufferSize"
type="integer"
value="50"
Expand All @@ -28,6 +40,10 @@
value="0"
combobox="average//averager with integer output//accumulate for n milliseconds//median"
description="The averager or accumulator mode"/>
<property name="autoReenableTime"
type="integer"
value="0"
description="time in ms, after the plugin automatically re-enables itself after being disabled. Set to zero to deactivate this functionality (never auto re-enable)."/>
</properties>
</componentType>

Expand Down
11 changes: 11 additions & 0 deletions Documentation/ACS-Help/HTML/Plugins/processors/Averager.htm
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,18 @@ <H2>Output Port Description</H2>
<ul>
<li><STRONG>output [double]:</STRONG> This port provides the current average of the buffered inputs.</li>
</ul>
<H2>Event Listener Description</H2>
<ul>
<li><STRONG>enablePlugin:</STRONG> Enables the functionality of this plugin. </li>
<li>
<STRONG>disablePlugin:</STRONG> Disables the functionality of this plugin. New values aren't accumulated anymore and no output is sent to the output port.
If property autoReenableTime set, the plugin is automatically re-enabled after the time defined by this property.
Generally disabling is delayed until the buffer of values is full, preventing any startup glitches.
</li>
</ul>
<H2>Properties</H2>
<ul>
<li><STRONG>enabled [boolean]:</STRONG> if true (default), the plugin is enabled, if false the plugin does nothing. Generally disabling is delayed until the buffer of values is full, preventing any startup glitches.</li>
<li>
<STRONG>mode [integer]:</STRONG> Denotes the operating mode of the unit, three modes are available:
<ul>
Expand All @@ -31,6 +41,7 @@ <H2>Properties</H2>
</ul>
</li>
<li><STRONG>bufferSize [integer]:</STRONG> Specifies the size of the buffer in the averaging modes or the amount of milliseconds to accumulate in the accumulator mode.</li>
<li><STRONG>autoReenableTime [integer]:</STRONG> Time in ms, after the plugin automatically re-enables itself after being disabled. Set to zero (default) to deactivate this functionality (never auto re-enable).</li>
</ul>
</BODY>
</HTML>
Binary file modified Documentation/ACS-Help/HTML/Plugins/processors/img/Averager.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.