Skip to content

Commit

Permalink
A Backend sketch for #661
Browse files Browse the repository at this point in the history
  • Loading branch information
Puckfist committed Sep 12, 2018
1 parent eb3a815 commit f722ef8
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 32 deletions.
Expand Up @@ -4,7 +4,18 @@
*/
package com.serotonin.m2m2.rt.event.detectors;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.serotonin.m2m2.Common;
import com.serotonin.m2m2.i18n.TranslatableMessage;
import com.serotonin.m2m2.rt.event.type.EventType;
import com.serotonin.m2m2.util.timeout.TimeoutClient;
import com.serotonin.m2m2.util.timeout.TimeoutTask;
import com.serotonin.m2m2.vo.event.detector.AbstractEventDetectorVO;
import com.serotonin.timer.OneTimeTrigger;
import com.serotonin.timer.Task;

/**
*
Expand All @@ -15,12 +26,88 @@
public abstract class AbstractEventDetectorRT<T extends AbstractEventDetectorVO<?>> {

protected T vo;
private TimeoutClient quiescentClient;
private Task quiescentTask;
private final long quiescentMillis;
private boolean quiescentState;
private Map<String, Object> quiescentContext;

public AbstractEventDetectorRT(T vo){
this.vo = vo;
quiescentMillis = Common.getMillis(vo.getQuiescentPeriodType(), vo.getQuiescentPeriods());
quiescentClient = new TimeoutClient() {

@Override
public void scheduleTimeout(long fireTime) {
wakeup();
}

@Override
public String getTaskId() {
//XIDs unique as of 3.3
return "EDQ-" + vo.getXid();
}

@Override
public String getThreadName() {
return vo.getXid() + " Quiescence";
}
};
}

public T getVO(){
return vo;
}

protected void raiseEvent(long time, Map<String, Object> context) {
if(quiescentMillis != 0 && quiescentTask != null) {
synchronized(this) { //get the lock and check
if(quiescentTask != null) {
quiescentState = true;
quiescentContext = context;
return;
}
}
}

TranslatableMessage msg;
if (!StringUtils.isBlank(vo.getName()))
msg = new TranslatableMessage("common.default", vo.getName());
else
msg = getMessage();

Common.eventManager.raiseEvent(getEventType(), time, vo.isRtnApplicable(), vo.getAlarmLevel(), msg, context);
}

protected void returnToNormal(long time) {
quiescentState = false;
Common.eventManager.returnToNormal(getEventType(), time, vo.getAlarmLevel());
if(quiescentMillis != 0) {
synchronized(this) {
if(quiescentTask != null)
quiescentTask.cancel();
quiescentTask = new TimeoutTask(new OneTimeTrigger(quiescentMillis), quiescentClient);
}
}
}

private void wakeup() {
boolean state;
Map<String, Object> context;
synchronized(this) {
state = quiescentState;
context = quiescentContext;
quiescentState = false;
quiescentContext = null;
quiescentTask = null;
}

if(state) {
raiseEvent(Common.timer.currentTimeMillis(), context);
}
}

protected abstract EventType getEventType();

abstract protected TranslatableMessage getMessage();
}
Expand Up @@ -7,11 +7,7 @@
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.serotonin.m2m2.Common;
import com.serotonin.m2m2.db.dao.DataPointTagsDao;
import com.serotonin.m2m2.i18n.TranslatableMessage;
import com.serotonin.m2m2.rt.dataImage.DataPointListener;
import com.serotonin.m2m2.rt.dataImage.PointValueTime;
import com.serotonin.m2m2.rt.event.type.DataPointEventType;
Expand All @@ -28,28 +24,13 @@ public PointEventDetectorRT(T vo) {
super(vo);
}


protected EventType getEventType() {
DataPointEventType et = new DataPointEventType(vo.njbGetDataPoint().getId(), vo.getId());
if (!vo.isRtnApplicable())
et.setDuplicateHandling(EventType.DuplicateHandling.ALLOW);
return et;
}

protected void raiseEvent(long time, Map<String, Object> context) {
TranslatableMessage msg;
if (!StringUtils.isBlank(vo.getName()))
msg = new TranslatableMessage("common.default", vo.getName());
else
msg = getMessage();

Common.eventManager.raiseEvent(getEventType(), time, vo.isRtnApplicable(), vo.getAlarmLevel(), msg, context);
}

protected void returnToNormal(long time) {
Common.eventManager.returnToNormal(getEventType(), time, vo.getAlarmLevel());
}

protected Map<String, Object> createEventContext() {
Map<String, Object> context = new HashMap<String, Object>();
context.put("pointEventDetector", vo);
Expand All @@ -61,9 +42,6 @@ protected Map<String, Object> createEventContext() {
return context;
}


abstract protected TranslatableMessage getMessage();

public abstract boolean isEventActive();

@Override
Expand Down
Expand Up @@ -14,6 +14,7 @@
import com.serotonin.json.JsonReader;
import com.serotonin.json.ObjectWriter;
import com.serotonin.json.type.JsonObject;
import com.serotonin.m2m2.Common;
import com.serotonin.m2m2.db.dao.AbstractDao;
import com.serotonin.m2m2.db.dao.EventDetectorDao;
import com.serotonin.m2m2.db.dao.EventHandlerDao;
Expand All @@ -39,6 +40,10 @@ public abstract class AbstractEventDetectorVO<T extends AbstractEventDetectorVO<

/* Source of the detector */
protected int sourceId;
protected int quiescentPeriods;
protected int quiescentPeriodType = Common.TimePeriods.SECONDS;

protected int alarmLevel;

/**
* Handlers that will be added to this detector upon save.
Expand Down Expand Up @@ -134,6 +139,24 @@ public int getSourceId(){
public void setSourceId(int id){
sourceId = id;
}
public int getAlarmLevel() {
return alarmLevel;
}
public void setAlarmLevel(int alarmLevel) {
this.alarmLevel = alarmLevel;
}
public int getQuiescentPeriods() {
return quiescentPeriods;
}
public void setQuiescentPeriods(int quiescentPeriods) {
this.quiescentPeriods = quiescentPeriods;
}
public int getQuiescentPeriodType() {
return quiescentPeriodType;
}
public void setQuiescentPeriodType(int quiescentPeriodType) {
this.quiescentPeriodType = quiescentPeriodType;
}
public void addAddedEventHandler(AbstractEventHandlerVO<?> eventHandler) {
if(addedEventHandlers == null)
addedEventHandlers = new ArrayList<>();
Expand Down Expand Up @@ -182,6 +205,12 @@ else if (!isXidUnique(xid, id))
if(EventHandlerDao.getInstance().getXidById(eh.getId()) == null)
response.addMessage("handlers", new TranslatableMessage("emport.eventHandler.missing", eh.getXid()));
}

if(quiescentPeriods < 0)
response.addMessage("quiescentPeriods", new TranslatableMessage("validate.cannotBeNegative"));

if(!Common.TIME_PERIOD_CODES.isValidId(quiescentPeriodType))
response.addMessage("quiescentPeriodType", new TranslatableMessage("validate.invalidValueWithAcceptable", Common.TIME_PERIOD_CODES.getCodeList()));
}

@Override
Expand All @@ -190,6 +219,8 @@ public void jsonWrite(ObjectWriter writer) throws IOException, JsonException {
writer.writeEntry("sourceType", this.definition.getSourceTypeName());
writer.writeEntry("xid", xid);
writer.writeEntry("name", name);
writer.writeEntry("quiescentPeriods", quiescentPeriods);
writer.writeEntry("quiescentPeriodType", quiescentPeriodType);

/* Event handler references are not exported here because there would be a circular dependency
* with the eventTypes array in the handler, and since there are other event types that was deemed
Expand All @@ -209,5 +240,13 @@ public void jsonRead(JsonReader reader, JsonObject jsonObject) throws JsonExcept
if(text != null)
name = text;
}

if(jsonObject.containsKey("quiescentPeriods"))
quiescentPeriods = jsonObject.getInt("quiescentPeriods");

text = jsonObject.getString("quiescentPeriodType");
if(text != null) {
quiescentPeriodType = Common.TIME_PERIOD_CODES.getId(text);
}
}
}
Expand Up @@ -12,7 +12,6 @@
import com.serotonin.json.JsonReader;
import com.serotonin.json.ObjectWriter;
import com.serotonin.json.type.JsonObject;
import com.serotonin.json.type.JsonValue;
import com.serotonin.m2m2.db.dao.DataPointDao;
import com.serotonin.m2m2.i18n.ProcessResult;
import com.serotonin.m2m2.i18n.TranslatableJsonException;
Expand All @@ -32,22 +31,13 @@ public abstract class AbstractPointEventDetectorVO<T extends AbstractPointEventD
public static final String XID_PREFIX = "PED_";
protected static final String MISSING_PROP_TRANSLATION_KEY = "emport.error.ped.missingAttr";

private int alarmLevel;

//Extra Fields
protected DataPointVO dataPoint;
private final int[] supportedDataTypes;

public AbstractPointEventDetectorVO(int[] supportedDataTypes){
this.supportedDataTypes = supportedDataTypes;
}

public int getAlarmLevel() {
return alarmLevel;
}
public void setAlarmLevel(int alarmLevel) {
this.alarmLevel = alarmLevel;
}

public DataPointVO njbGetDataPoint() {
return dataPoint;
Expand Down

0 comments on commit f722ef8

Please sign in to comment.