Implementation of Event based triggering. issue 51
This commit is contained in:
parent
a020ec6668
commit
9af96a7cb2
10 changed files with 144 additions and 20 deletions
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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()}}">
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
14
src/se/hal/intf/HalDeviceReportListener.java
Executable file
14
src/se/hal/intf/HalDeviceReportListener.java
Executable 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);
|
||||
}
|
||||
|
|
@ -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"}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
84
src/se/hal/trigger/EventTrigger.java
Executable file
84
src/se/hal/trigger/EventTrigger.java
Executable 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;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue