Implementation of Event based triggering. issue 51

This commit is contained in:
Ziver Koc 2017-03-10 16:59:07 +01:00
parent a020ec6668
commit 9af96a7cb2
10 changed files with 144 additions and 20 deletions

View file

@ -103,7 +103,6 @@
<javac srcdir="${testDir}" destdir="${buildTestDir}" debug="yes" debugLevel="lines,vars,source" fork="yes">
<classpath refid="classpath.test" />
<include name="**/*.java" />
<exclude name="se/hal/test/JarvisSyntersizerTest.java" />
</javac>
<copy todir="${buildTestDir}">
<fileset dir="${testDir}"

View file

@ -52,7 +52,7 @@
<tr><td>
<div class="panel panel-default drop-shadow {{#.evaluate()}}panel-success{{/.evaluate()}}">
<div class="panel-heading" style="padding: 2px 15px;">
<small>{{.getClass().getName()}}</small>
<small>{{.getObjectClass()}}</small>
<form method="POST">
<input type="hidden" name="action" value="remove_trigger">
<input type="hidden" name="trigger-id" value="{{.getId()}}">
@ -95,7 +95,7 @@
<tr><td>
<div class="panel panel-default drop-shadow">
<div class="panel-heading" style="padding: 2px 15px;">
<small>{{.getClass().getName()}}</small>
<small>{{.getObjectClass()}}</small>
<form method="POST">
<input type="hidden" name="action" value="remove_action">
<input type="hidden" name="action-id" value="{{.getId()}}">

View file

@ -161,6 +161,9 @@ public class ControllerManager implements HalSensorReportListener,
sensor.setDeviceConfig(sensorConfig);
}
sensor.setDeviceData(sensorData);
// call listeners
for(HalDeviceReportListener<Sensor> listener : sensor.getReportListeners())
listener.receivedReport(sensor);
}catch (SQLException e){
logger.log(Level.WARNING, "Unable to store sensor report", e);
@ -284,6 +287,9 @@ public class ControllerManager implements HalSensorReportListener,
event.setDeviceConfig(eventConfig);
}
event.setDeviceData(eventData);
// call listeners
for(HalDeviceReportListener<Event> listener : event.getReportListeners())
listener.receivedReport(event);
}catch (SQLException e){
logger.log(Level.WARNING, "Unable to store event report", e);

View file

@ -18,9 +18,9 @@ import java.util.logging.Logger;
public class SendEventAction implements HalAction {
private static final Logger logger = LogUtil.getLogger();
@Configurator.Configurable(order = 1, value = "Event Device ID")
@Configurator.Configurable("Event Device ID")
private int eventId;
@Configurator.Configurable(order = 1, value = "Data to Send")
@Configurator.Configurable("Data to Send")
private double data;

View file

@ -0,0 +1,14 @@
package se.hal.intf;
import se.hal.struct.AbstractDevice;
/**
* A listener interface that will be called when the
* Event or Sensor that it is registered to receives a report
*
* @param <T> is the device type
*/
public interface HalDeviceReportListener<T extends AbstractDevice> {
void receivedReport(T device);
}

View file

@ -20,6 +20,7 @@
{"se.hal.intf.HalTrigger": "se.hal.trigger.DateTimeTrigger"},
{"se.hal.intf.HalTrigger": "se.hal.trigger.EventTrigger"},
{"se.hal.intf.HalTrigger": "se.hal.trigger.TimerTrigger"},
{"se.hal.intf.HalAction": "se.hal.action.SendEventAction"}
]

View file

@ -2,6 +2,7 @@ package se.hal.struct;
import se.hal.ControllerManager;
import se.hal.HalContext;
import se.hal.intf.HalDeviceReportListener;
import zutil.db.DBConnection;
import zutil.db.bean.DBBean;
import zutil.log.LogUtil;
@ -10,13 +11,19 @@ import zutil.parser.json.JSONWriter;
import zutil.ui.Configurator;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by Ziver on 2016-01-15.
* Contains logic and data common to devices (Events and Sensors)
*
* @param <T> is the device type
* @param <C> is the device configuration class
* @param <D> is the device data class
*/
public abstract class AbstractDevice<T,D> extends DBBean {
public abstract class AbstractDevice<T extends AbstractDevice, C,D> extends DBBean {
private static final Logger logger = LogUtil.getLogger();
// Sensor specific data
@ -25,7 +32,7 @@ public abstract class AbstractDevice<T,D> extends DBBean {
private String config; // only used to store the deviceConfig configuration in DB
/** Sensor specific configuration **/
private transient T deviceConfig;
private transient C deviceConfig;
/** latest device data received **/
private transient D deviceData;
@ -39,24 +46,26 @@ public abstract class AbstractDevice<T,D> extends DBBean {
@DBColumn("map_y")
private double y;
protected transient List<HalDeviceReportListener<T>> listeners = new LinkedList<>();
/**************** DEVICE CONFIG ******************/
public Configurator<T> getDeviceConfigurator() {
T obj = getDeviceConfig();
public Configurator<C> getDeviceConfigurator() {
C obj = getDeviceConfig();
if (obj != null) {
Configurator<T> configurator = new Configurator<>(obj);
Configurator<C> configurator = new Configurator<>(obj);
configurator.setPreConfigurationListener(ControllerManager.getInstance());
configurator.setPostConfigurationListener(ControllerManager.getInstance());
return configurator;
}
return null;
}
public T getDeviceConfig() {
public C getDeviceConfig() {
if (deviceConfig == null || !deviceConfig.getClass().getName().equals(type)) {
try {
Class c = Class.forName(type);
deviceConfig = (T) c.newInstance();
deviceConfig = (C) c.newInstance();
applyConfig();
deviceData = getLatestDeviceData(HalContext.getDB());
@ -72,7 +81,7 @@ public abstract class AbstractDevice<T,D> extends DBBean {
* And the current config will be applied on the new DeviceData.
* DeviceData will be reset if the input is set as null.
*/
public void setDeviceConfig(T data) {
public void setDeviceConfig(C data) {
if(data != null) {
type = data.getClass().getName();
deviceConfig = data;
@ -98,7 +107,7 @@ public abstract class AbstractDevice<T,D> extends DBBean {
* Will update the config String that will be stored in DB.
*/
private void updateConfigString() {
Configurator<T> configurator = getDeviceConfigurator();
Configurator<C> configurator = getDeviceConfigurator();
this.config = JSONWriter.toString(configurator.getValuesAsNode());
}
/**
@ -107,12 +116,13 @@ public abstract class AbstractDevice<T,D> extends DBBean {
*/
private void applyConfig(){
if (config != null && !config.isEmpty()) {
Configurator<T> configurator = getDeviceConfigurator();
Configurator<C> configurator = getDeviceConfigurator();
configurator.setValues(JSONParser.read(config));
configurator.applyConfiguration();
}
}
public abstract Class<?> getController();
/**************** DEVICE DATA ******************/
@ -180,4 +190,13 @@ public abstract class AbstractDevice<T,D> extends DBBean {
this.y = y;
}
public void addReportListener(HalDeviceReportListener<T> listener){
listeners.add(listener);
}
public void removeReportListener(HalDeviceReportListener<T> listener){
listeners.remove(listener);
}
public List<HalDeviceReportListener<T>> getReportListeners(){
return listeners;
}
}

View file

@ -24,7 +24,7 @@ import java.util.logging.Logger;
* Created by Ziver on 2015-12-15.
*/
@DBBean.DBTable(value="event", superBean=true)
public class Event extends AbstractDevice<HalEventConfig,HalEventData>{
public class Event extends AbstractDevice<Event, HalEventConfig,HalEventData>{
private static final Logger logger = LogUtil.getLogger();
@ -40,7 +40,7 @@ public class Event extends AbstractDevice<HalEventConfig,HalEventData>{
@Override
public Class<? extends HalEventController> getController(){
return getDeviceConfig().getEventControllerClass();
}

View file

@ -1,6 +1,7 @@
package se.hal.struct;
import se.hal.HalContext;
import se.hal.intf.HalDeviceReportListener;
import se.hal.intf.HalSensorController;
import se.hal.intf.HalSensorConfig;
import se.hal.intf.HalSensorData;
@ -19,7 +20,7 @@ import java.util.logging.Logger;
@DBBean.DBTable(value="sensor", superBean=true)
public class Sensor extends AbstractDevice<HalSensorConfig,HalSensorData>{
public class Sensor extends AbstractDevice<Sensor, HalSensorConfig,HalSensorData>{
private static final Logger logger = LogUtil.getLogger();
private long external_id = -1;
@ -109,7 +110,7 @@ public class Sensor extends AbstractDevice<HalSensorConfig,HalSensorData>{
}
@Override
public Class<? extends HalSensorController> getController(){
return getDeviceConfig().getSensorControllerClass();
}

View file

@ -0,0 +1,84 @@
package se.hal.trigger;
import se.hal.HalContext;
import se.hal.TriggerManager;
import se.hal.intf.HalDeviceReportListener;
import se.hal.intf.HalEventData;
import se.hal.intf.HalTrigger;
import se.hal.struct.Event;
import zutil.db.DBConnection;
import zutil.log.LogUtil;
import zutil.ui.Configurator;
import zutil.ui.Configurator.PostConfigurationActionListener;
import zutil.ui.Configurator.PreConfigurationActionListener;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*/
public class EventTrigger implements HalTrigger,
PreConfigurationActionListener,
PostConfigurationActionListener, HalDeviceReportListener<Event> {
private static final Logger logger = LogUtil.getLogger();
@Configurator.Configurable("Event Device ID")
private int eventId = -1;
@Configurator.Configurable("Data to compare to")
private double expectedData;
private transient HalEventData receivedData;
private Event getEvent(long id){
try {
if (eventId >= 0)
return Event.getEvent(HalContext.getDB(), eventId);
} catch (SQLException e){ logger.log(Level.SEVERE, null, e);}
return null;
}
@Override
public void preConfigurationAction(Configurator configurator, Object obj) {
Event event = getEvent(eventId);
if (event != null)
event.removeReportListener(this);
reset();
}
@Override
public void postConfigurationAction(Configurator configurator, Object obj) {
Event event = getEvent(eventId);
if (event != null)
event.addReportListener(this);
}
@Override
public void receivedReport(Event device) {
receivedData = device.getDeviceData();
// Instant trigger evaluation
TriggerManager.getInstance().evaluateAndExecute();
}
@Override
public boolean evaluate() {
if (receivedData != null)
return expectedData == receivedData.getData();
return false;
}
@Override
public void reset() {
receivedData = null;
}
@Override
public String toString(){
Event event = getEvent(eventId);
return (event != null ? event.getName() : null) + " == "+ expectedData;
}
}